Merge "Update CarMenuItem.Builder to require a Context." into androidx-master-dev
diff --git a/activity/activity-ktx/api/1.1.0-alpha03.txt b/activity/activity-ktx/api/1.1.0-alpha03.txt
new file mode 100644
index 0000000..c6e9a9a
--- /dev/null
+++ b/activity/activity-ktx/api/1.1.0-alpha03.txt
@@ -0,0 +1,15 @@
+// Signature format: 3.0
+package androidx.activity {
+
+  public final class ActivityViewModelLazyKt {
+    ctor public ActivityViewModelLazyKt();
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> viewModels(androidx.activity.ComponentActivity, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+  }
+
+  public final class OnBackPressedDispatcherKt {
+    ctor public OnBackPressedDispatcherKt();
+    method public static androidx.activity.OnBackPressedCallback addCallback(androidx.activity.OnBackPressedDispatcher, androidx.lifecycle.LifecycleOwner? owner = null, boolean enabled = true, kotlin.jvm.functions.Function1<? super androidx.activity.OnBackPressedCallback,kotlin.Unit> onBackPressed);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha03.txt b/activity/activity-ktx/api/res-1.1.0-alpha03.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha03.txt
copy to activity/activity-ktx/api/res-1.1.0-alpha03.txt
diff --git a/activity/activity-ktx/api/restricted_1.1.0-alpha03.txt b/activity/activity-ktx/api/restricted_1.1.0-alpha03.txt
new file mode 100644
index 0000000..c6e9a9a
--- /dev/null
+++ b/activity/activity-ktx/api/restricted_1.1.0-alpha03.txt
@@ -0,0 +1,15 @@
+// Signature format: 3.0
+package androidx.activity {
+
+  public final class ActivityViewModelLazyKt {
+    ctor public ActivityViewModelLazyKt();
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> viewModels(androidx.activity.ComponentActivity, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+  }
+
+  public final class OnBackPressedDispatcherKt {
+    ctor public OnBackPressedDispatcherKt();
+    method public static androidx.activity.OnBackPressedCallback addCallback(androidx.activity.OnBackPressedDispatcher, androidx.lifecycle.LifecycleOwner? owner = null, boolean enabled = true, kotlin.jvm.functions.Function1<? super androidx.activity.OnBackPressedCallback,kotlin.Unit> onBackPressed);
+  }
+
+}
+
diff --git a/activity/activity/api/1.1.0-alpha03.txt b/activity/activity/api/1.1.0-alpha03.txt
new file mode 100644
index 0000000..f087fd3
--- /dev/null
+++ b/activity/activity/api/1.1.0-alpha03.txt
@@ -0,0 +1,39 @@
+// Signature format: 3.0
+package androidx.activity {
+
+  public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+    ctor public ComponentActivity();
+    ctor @ContentView public ComponentActivity(@LayoutRes int);
+    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+    method @Deprecated public Object? getLastCustomNonConfigurationInstance();
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method public final androidx.activity.OnBackPressedDispatcher getOnBackPressedDispatcher();
+    method public final androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+    method @Deprecated public Object? onRetainCustomNonConfigurationInstance();
+    method public final Object? onRetainNonConfigurationInstance();
+  }
+
+  public abstract class OnBackPressedCallback {
+    ctor public OnBackPressedCallback(boolean);
+    method @MainThread public abstract void handleOnBackPressed();
+    method @MainThread public final boolean isEnabled();
+    method @MainThread public final void remove();
+    method @MainThread public final void setEnabled(boolean);
+  }
+
+  public final class OnBackPressedDispatcher {
+    ctor public OnBackPressedDispatcher();
+    ctor public OnBackPressedDispatcher(Runnable?);
+    method @MainThread public void addCallback(androidx.activity.OnBackPressedCallback);
+    method @MainThread public void addCallback(androidx.lifecycle.LifecycleOwner, androidx.activity.OnBackPressedCallback);
+    method @MainThread public boolean hasEnabledCallbacks();
+    method @MainThread public void onBackPressed();
+  }
+
+  public interface OnBackPressedDispatcherOwner extends androidx.lifecycle.LifecycleOwner {
+    method public androidx.activity.OnBackPressedDispatcher getOnBackPressedDispatcher();
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha03.txt b/activity/activity/api/res-1.1.0-alpha03.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha03.txt
copy to activity/activity/api/res-1.1.0-alpha03.txt
diff --git a/activity/activity/api/restricted_1.1.0-alpha03.txt b/activity/activity/api/restricted_1.1.0-alpha03.txt
new file mode 100644
index 0000000..f087fd3
--- /dev/null
+++ b/activity/activity/api/restricted_1.1.0-alpha03.txt
@@ -0,0 +1,39 @@
+// Signature format: 3.0
+package androidx.activity {
+
+  public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+    ctor public ComponentActivity();
+    ctor @ContentView public ComponentActivity(@LayoutRes int);
+    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+    method @Deprecated public Object? getLastCustomNonConfigurationInstance();
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method public final androidx.activity.OnBackPressedDispatcher getOnBackPressedDispatcher();
+    method public final androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+    method @Deprecated public Object? onRetainCustomNonConfigurationInstance();
+    method public final Object? onRetainNonConfigurationInstance();
+  }
+
+  public abstract class OnBackPressedCallback {
+    ctor public OnBackPressedCallback(boolean);
+    method @MainThread public abstract void handleOnBackPressed();
+    method @MainThread public final boolean isEnabled();
+    method @MainThread public final void remove();
+    method @MainThread public final void setEnabled(boolean);
+  }
+
+  public final class OnBackPressedDispatcher {
+    ctor public OnBackPressedDispatcher();
+    ctor public OnBackPressedDispatcher(Runnable?);
+    method @MainThread public void addCallback(androidx.activity.OnBackPressedCallback);
+    method @MainThread public void addCallback(androidx.lifecycle.LifecycleOwner, androidx.activity.OnBackPressedCallback);
+    method @MainThread public boolean hasEnabledCallbacks();
+    method @MainThread public void onBackPressed();
+  }
+
+  public interface OnBackPressedDispatcherOwner extends androidx.lifecycle.LifecycleOwner {
+    method public androidx.activity.OnBackPressedDispatcher getOnBackPressedDispatcher();
+  }
+
+}
+
diff --git a/preference/ktx/api/restricted_1.1.0-beta02.txt b/ads/ads-identifier-common/api/1.0.0-alpha02.txt
similarity index 100%
copy from preference/ktx/api/restricted_1.1.0-beta02.txt
copy to ads/ads-identifier-common/api/1.0.0-alpha02.txt
diff --git a/preference/ktx/api/res-1.1.0-alpha02.txt b/ads/ads-identifier-common/api/res-1.0.0-alpha02.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha02.txt
copy to ads/ads-identifier-common/api/res-1.0.0-alpha02.txt
diff --git a/ads/ads-identifier-common/api/restricted_1.0.0-alpha02.txt b/ads/ads-identifier-common/api/restricted_1.0.0-alpha02.txt
new file mode 100644
index 0000000..ae9f628
--- /dev/null
+++ b/ads/ads-identifier-common/api/restricted_1.0.0-alpha02.txt
@@ -0,0 +1,11 @@
+// Signature format: 3.0
+package androidx.ads.identifier {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public class AdvertisingIdUtils {
+    method public static java.util.List<android.content.pm.ResolveInfo!> getAdvertisingIdProviderServices(android.content.pm.PackageManager);
+    method public static android.content.pm.ServiceInfo? selectServiceByPriority(java.util.List<android.content.pm.ResolveInfo!>?, android.content.pm.PackageManager);
+    field public static final String GET_AD_ID_ACTION = "androidx.ads.identifier.provider.GET_AD_ID";
+  }
+
+}
+
diff --git a/ads/ads-identifier-provider/api/1.0.0-alpha02.txt b/ads/ads-identifier-provider/api/1.0.0-alpha02.txt
new file mode 100644
index 0000000..463129f
--- /dev/null
+++ b/ads/ads-identifier-provider/api/1.0.0-alpha02.txt
@@ -0,0 +1,21 @@
+// Signature format: 3.0
+package androidx.ads.identifier.provider {
+
+  public interface AdvertisingIdProvider {
+    method public String getId();
+    method public boolean isLimitAdTrackingEnabled();
+  }
+
+  public abstract class AdvertisingIdProviderInfo {
+    method public abstract String getPackageName();
+    method public abstract android.content.Intent? getSettingsIntent();
+    method public abstract boolean isHighestPriority();
+  }
+
+  public class AdvertisingIdProviderManager {
+    method public static java.util.List<androidx.ads.identifier.provider.AdvertisingIdProviderInfo!> getAdvertisingIdProviders(android.content.Context);
+    method public static void registerProviderCallable(java.util.concurrent.Callable<androidx.ads.identifier.provider.AdvertisingIdProvider!>);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha02.txt b/ads/ads-identifier-provider/api/res-1.0.0-alpha02.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha02.txt
copy to ads/ads-identifier-provider/api/res-1.0.0-alpha02.txt
diff --git a/ads/ads-identifier-provider/api/restricted_1.0.0-alpha02.txt b/ads/ads-identifier-provider/api/restricted_1.0.0-alpha02.txt
new file mode 100644
index 0000000..463129f
--- /dev/null
+++ b/ads/ads-identifier-provider/api/restricted_1.0.0-alpha02.txt
@@ -0,0 +1,21 @@
+// Signature format: 3.0
+package androidx.ads.identifier.provider {
+
+  public interface AdvertisingIdProvider {
+    method public String getId();
+    method public boolean isLimitAdTrackingEnabled();
+  }
+
+  public abstract class AdvertisingIdProviderInfo {
+    method public abstract String getPackageName();
+    method public abstract android.content.Intent? getSettingsIntent();
+    method public abstract boolean isHighestPriority();
+  }
+
+  public class AdvertisingIdProviderManager {
+    method public static java.util.List<androidx.ads.identifier.provider.AdvertisingIdProviderInfo!> getAdvertisingIdProviders(android.content.Context);
+    method public static void registerProviderCallable(java.util.concurrent.Callable<androidx.ads.identifier.provider.AdvertisingIdProvider!>);
+  }
+
+}
+
diff --git a/ads/ads-identifier/api/1.0.0-alpha02.txt b/ads/ads-identifier/api/1.0.0-alpha02.txt
new file mode 100644
index 0000000..20ed609
--- /dev/null
+++ b/ads/ads-identifier/api/1.0.0-alpha02.txt
@@ -0,0 +1,21 @@
+// Signature format: 3.0
+package androidx.ads.identifier {
+
+  public class AdvertisingIdClient {
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.ads.identifier.AdvertisingIdInfo!> getAdvertisingIdInfo(android.content.Context);
+    method public static boolean isAdvertisingIdProviderAvailable(android.content.Context);
+  }
+
+  public abstract class AdvertisingIdInfo {
+    method public abstract String getId();
+    method public abstract String getProviderPackageName();
+    method public abstract boolean isLimitAdTrackingEnabled();
+  }
+
+  public class AdvertisingIdNotAvailableException extends java.lang.Exception {
+    ctor public AdvertisingIdNotAvailableException(String);
+    ctor public AdvertisingIdNotAvailableException(String, Throwable);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha02.txt b/ads/ads-identifier/api/res-1.0.0-alpha02.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha02.txt
copy to ads/ads-identifier/api/res-1.0.0-alpha02.txt
diff --git a/ads/ads-identifier/api/restricted_1.0.0-alpha02.txt b/ads/ads-identifier/api/restricted_1.0.0-alpha02.txt
new file mode 100644
index 0000000..20ed609
--- /dev/null
+++ b/ads/ads-identifier/api/restricted_1.0.0-alpha02.txt
@@ -0,0 +1,21 @@
+// Signature format: 3.0
+package androidx.ads.identifier {
+
+  public class AdvertisingIdClient {
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.ads.identifier.AdvertisingIdInfo!> getAdvertisingIdInfo(android.content.Context);
+    method public static boolean isAdvertisingIdProviderAvailable(android.content.Context);
+  }
+
+  public abstract class AdvertisingIdInfo {
+    method public abstract String getId();
+    method public abstract String getProviderPackageName();
+    method public abstract boolean isLimitAdTrackingEnabled();
+  }
+
+  public class AdvertisingIdNotAvailableException extends java.lang.Exception {
+    ctor public AdvertisingIdNotAvailableException(String);
+    ctor public AdvertisingIdNotAvailableException(String, Throwable);
+  }
+
+}
+
diff --git a/annotation/annotation-experimental/api/api_lint.ignore b/annotation/annotation-experimental/api/api_lint.ignore
new file mode 100644
index 0000000..0f4a077
--- /dev/null
+++ b/annotation/annotation-experimental/api/api_lint.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+MissingNullability: androidx.annotation.experimental.Experimental#level():
+    Missing nullability on method `level` return
+MissingNullability: androidx.annotation.experimental.UseExperimental#markerClass():
+    Missing nullability on method `markerClass` return
diff --git a/annotation/annotation/api/api_lint.ignore b/annotation/annotation/api/api_lint.ignore
new file mode 100644
index 0000000..0620d0e
--- /dev/null
+++ b/annotation/annotation/api/api_lint.ignore
@@ -0,0 +1,39 @@
+// Baseline format: 1.0
+MissingNullability: androidx.annotation.CheckResult#suggest():
+    Missing nullability on method `suggest` return
+MissingNullability: androidx.annotation.GuardedBy#value():
+    Missing nullability on method `value` return
+MissingNullability: androidx.annotation.InspectableProperty#enumMapping():
+    Missing nullability on method `enumMapping` return
+MissingNullability: androidx.annotation.InspectableProperty#flagMapping():
+    Missing nullability on method `flagMapping` return
+MissingNullability: androidx.annotation.InspectableProperty#name():
+    Missing nullability on method `name` return
+MissingNullability: androidx.annotation.InspectableProperty#valueType():
+    Missing nullability on method `valueType` return
+MissingNullability: androidx.annotation.InspectableProperty.EnumEntry#name():
+    Missing nullability on method `name` return
+MissingNullability: androidx.annotation.InspectableProperty.FlagEntry#name():
+    Missing nullability on method `name` return
+MissingNullability: androidx.annotation.IntDef#value():
+    Missing nullability on method `value` return
+MissingNullability: androidx.annotation.LongDef#value():
+    Missing nullability on method `value` return
+MissingNullability: androidx.annotation.RequiresFeature#enforcement():
+    Missing nullability on method `enforcement` return
+MissingNullability: androidx.annotation.RequiresFeature#name():
+    Missing nullability on method `name` return
+MissingNullability: androidx.annotation.RequiresPermission#allOf():
+    Missing nullability on method `allOf` return
+MissingNullability: androidx.annotation.RequiresPermission#anyOf():
+    Missing nullability on method `anyOf` return
+MissingNullability: androidx.annotation.RequiresPermission#value():
+    Missing nullability on method `value` return
+MissingNullability: androidx.annotation.RequiresPermission.Read#value():
+    Missing nullability on method `value` return
+MissingNullability: androidx.annotation.RequiresPermission.Write#value():
+    Missing nullability on method `value` return
+MissingNullability: androidx.annotation.RestrictTo#value():
+    Missing nullability on method `value` return
+MissingNullability: androidx.annotation.StringDef#value():
+    Missing nullability on method `value` return
diff --git a/appcompat/api/api_lint.ignore b/appcompat/api/api_lint.ignore
index 7c227b9..a41872a 100644
--- a/appcompat/api/api_lint.ignore
+++ b/appcompat/api/api_lint.ignore
@@ -13,6 +13,884 @@
     AppCompatActivity should not extend `Activity`. Activity subclasses are impossible to compose. Expose a composable API instead.
 
 
+MissingNullability: androidx.appcompat.app.ActionBar#addOnMenuVisibilityListener(androidx.appcompat.app.ActionBar.OnMenuVisibilityListener) parameter #0:
+    Missing nullability on parameter `listener` in method `addOnMenuVisibilityListener`
+MissingNullability: androidx.appcompat.app.ActionBar#addTab(androidx.appcompat.app.ActionBar.Tab) parameter #0:
+    Missing nullability on parameter `tab` in method `addTab`
+MissingNullability: androidx.appcompat.app.ActionBar#addTab(androidx.appcompat.app.ActionBar.Tab, boolean) parameter #0:
+    Missing nullability on parameter `tab` in method `addTab`
+MissingNullability: androidx.appcompat.app.ActionBar#addTab(androidx.appcompat.app.ActionBar.Tab, int) parameter #0:
+    Missing nullability on parameter `tab` in method `addTab`
+MissingNullability: androidx.appcompat.app.ActionBar#addTab(androidx.appcompat.app.ActionBar.Tab, int, boolean) parameter #0:
+    Missing nullability on parameter `tab` in method `addTab`
+MissingNullability: androidx.appcompat.app.ActionBar#getCustomView():
+    Missing nullability on method `getCustomView` return
+MissingNullability: androidx.appcompat.app.ActionBar#getThemedContext():
+    Missing nullability on method `getThemedContext` return
+MissingNullability: androidx.appcompat.app.ActionBar#removeOnMenuVisibilityListener(androidx.appcompat.app.ActionBar.OnMenuVisibilityListener) parameter #0:
+    Missing nullability on parameter `listener` in method `removeOnMenuVisibilityListener`
+MissingNullability: androidx.appcompat.app.ActionBar#removeTab(androidx.appcompat.app.ActionBar.Tab) parameter #0:
+    Missing nullability on parameter `tab` in method `removeTab`
+MissingNullability: androidx.appcompat.app.ActionBar#selectTab(androidx.appcompat.app.ActionBar.Tab) parameter #0:
+    Missing nullability on parameter `tab` in method `selectTab`
+MissingNullability: androidx.appcompat.app.ActionBar#setCustomView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `setCustomView`
+MissingNullability: androidx.appcompat.app.ActionBar#setCustomView(android.view.View, androidx.appcompat.app.ActionBar.LayoutParams) parameter #0:
+    Missing nullability on parameter `view` in method `setCustomView`
+MissingNullability: androidx.appcompat.app.ActionBar#setCustomView(android.view.View, androidx.appcompat.app.ActionBar.LayoutParams) parameter #1:
+    Missing nullability on parameter `layoutParams` in method `setCustomView`
+MissingNullability: androidx.appcompat.app.ActionBar#setIcon(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `icon` in method `setIcon`
+MissingNullability: androidx.appcompat.app.ActionBar#setListNavigationCallbacks(android.widget.SpinnerAdapter, androidx.appcompat.app.ActionBar.OnNavigationListener) parameter #0:
+    Missing nullability on parameter `adapter` in method `setListNavigationCallbacks`
+MissingNullability: androidx.appcompat.app.ActionBar#setListNavigationCallbacks(android.widget.SpinnerAdapter, androidx.appcompat.app.ActionBar.OnNavigationListener) parameter #1:
+    Missing nullability on parameter `callback` in method `setListNavigationCallbacks`
+MissingNullability: androidx.appcompat.app.ActionBar#setLogo(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `logo` in method `setLogo`
+MissingNullability: androidx.appcompat.app.ActionBar#setSplitBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `d` in method `setSplitBackgroundDrawable`
+MissingNullability: androidx.appcompat.app.ActionBar#setStackedBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `d` in method `setStackedBackgroundDrawable`
+MissingNullability: androidx.appcompat.app.ActionBar#setSubtitle(CharSequence) parameter #0:
+    Missing nullability on parameter `subtitle` in method `setSubtitle`
+MissingNullability: androidx.appcompat.app.ActionBar#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.appcompat.app.ActionBar.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `LayoutParams`
+MissingNullability: androidx.appcompat.app.ActionBar.LayoutParams#LayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.appcompat.app.ActionBar.LayoutParams#LayoutParams(androidx.appcompat.app.ActionBar.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#getContentDescription():
+    Missing nullability on method `getContentDescription` return
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#getCustomView():
+    Missing nullability on method `getCustomView` return
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#getIcon():
+    Missing nullability on method `getIcon` return
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#getTag():
+    Missing nullability on method `getTag` return
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#getText():
+    Missing nullability on method `getText` return
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#setContentDescription(CharSequence):
+    Missing nullability on method `setContentDescription` return
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#setContentDescription(CharSequence) parameter #0:
+    Missing nullability on parameter `contentDesc` in method `setContentDescription`
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#setContentDescription(int):
+    Missing nullability on method `setContentDescription` return
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#setCustomView(android.view.View):
+    Missing nullability on method `setCustomView` return
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#setCustomView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `setCustomView`
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#setCustomView(int):
+    Missing nullability on method `setCustomView` return
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#setIcon(android.graphics.drawable.Drawable):
+    Missing nullability on method `setIcon` return
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#setIcon(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `icon` in method `setIcon`
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#setIcon(int):
+    Missing nullability on method `setIcon` return
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#setTabListener(androidx.appcompat.app.ActionBar.TabListener):
+    Missing nullability on method `setTabListener` return
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#setTabListener(androidx.appcompat.app.ActionBar.TabListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setTabListener`
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#setTag(Object):
+    Missing nullability on method `setTag` return
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#setTag(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `setTag`
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#setText(CharSequence):
+    Missing nullability on method `setText` return
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#setText(CharSequence) parameter #0:
+    Missing nullability on parameter `text` in method `setText`
+MissingNullability: androidx.appcompat.app.ActionBar.Tab#setText(int):
+    Missing nullability on method `setText` return
+MissingNullability: androidx.appcompat.app.ActionBar.TabListener#onTabReselected(androidx.appcompat.app.ActionBar.Tab, androidx.fragment.app.FragmentTransaction) parameter #0:
+    Missing nullability on parameter `tab` in method `onTabReselected`
+MissingNullability: androidx.appcompat.app.ActionBar.TabListener#onTabReselected(androidx.appcompat.app.ActionBar.Tab, androidx.fragment.app.FragmentTransaction) parameter #1:
+    Missing nullability on parameter `ft` in method `onTabReselected`
+MissingNullability: androidx.appcompat.app.ActionBar.TabListener#onTabSelected(androidx.appcompat.app.ActionBar.Tab, androidx.fragment.app.FragmentTransaction) parameter #0:
+    Missing nullability on parameter `tab` in method `onTabSelected`
+MissingNullability: androidx.appcompat.app.ActionBar.TabListener#onTabSelected(androidx.appcompat.app.ActionBar.Tab, androidx.fragment.app.FragmentTransaction) parameter #1:
+    Missing nullability on parameter `ft` in method `onTabSelected`
+MissingNullability: androidx.appcompat.app.ActionBar.TabListener#onTabUnselected(androidx.appcompat.app.ActionBar.Tab, androidx.fragment.app.FragmentTransaction) parameter #0:
+    Missing nullability on parameter `tab` in method `onTabUnselected`
+MissingNullability: androidx.appcompat.app.ActionBar.TabListener#onTabUnselected(androidx.appcompat.app.ActionBar.Tab, androidx.fragment.app.FragmentTransaction) parameter #1:
+    Missing nullability on parameter `ft` in method `onTabUnselected`
+MissingNullability: androidx.appcompat.app.ActionBarDrawerToggle#ActionBarDrawerToggle(android.app.Activity, androidx.drawerlayout.widget.DrawerLayout, androidx.appcompat.widget.Toolbar, int, int) parameter #0:
+    Missing nullability on parameter `activity` in method `ActionBarDrawerToggle`
+MissingNullability: androidx.appcompat.app.ActionBarDrawerToggle#ActionBarDrawerToggle(android.app.Activity, androidx.drawerlayout.widget.DrawerLayout, androidx.appcompat.widget.Toolbar, int, int) parameter #1:
+    Missing nullability on parameter `drawerLayout` in method `ActionBarDrawerToggle`
+MissingNullability: androidx.appcompat.app.ActionBarDrawerToggle#ActionBarDrawerToggle(android.app.Activity, androidx.drawerlayout.widget.DrawerLayout, androidx.appcompat.widget.Toolbar, int, int) parameter #2:
+    Missing nullability on parameter `toolbar` in method `ActionBarDrawerToggle`
+MissingNullability: androidx.appcompat.app.ActionBarDrawerToggle#ActionBarDrawerToggle(android.app.Activity, androidx.drawerlayout.widget.DrawerLayout, int, int) parameter #0:
+    Missing nullability on parameter `activity` in method `ActionBarDrawerToggle`
+MissingNullability: androidx.appcompat.app.ActionBarDrawerToggle#ActionBarDrawerToggle(android.app.Activity, androidx.drawerlayout.widget.DrawerLayout, int, int) parameter #1:
+    Missing nullability on parameter `drawerLayout` in method `ActionBarDrawerToggle`
+MissingNullability: androidx.appcompat.app.ActionBarDrawerToggle#getToolbarNavigationClickListener():
+    Missing nullability on method `getToolbarNavigationClickListener` return
+MissingNullability: androidx.appcompat.app.ActionBarDrawerToggle#onConfigurationChanged(android.content.res.Configuration) parameter #0:
+    Missing nullability on parameter `newConfig` in method `onConfigurationChanged`
+MissingNullability: androidx.appcompat.app.ActionBarDrawerToggle#onDrawerClosed(android.view.View) parameter #0:
+    Missing nullability on parameter `drawerView` in method `onDrawerClosed`
+MissingNullability: androidx.appcompat.app.ActionBarDrawerToggle#onDrawerOpened(android.view.View) parameter #0:
+    Missing nullability on parameter `drawerView` in method `onDrawerOpened`
+MissingNullability: androidx.appcompat.app.ActionBarDrawerToggle#onDrawerSlide(android.view.View, float) parameter #0:
+    Missing nullability on parameter `drawerView` in method `onDrawerSlide`
+MissingNullability: androidx.appcompat.app.ActionBarDrawerToggle#onOptionsItemSelected(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `onOptionsItemSelected`
+MissingNullability: androidx.appcompat.app.ActionBarDrawerToggle#setHomeAsUpIndicator(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `indicator` in method `setHomeAsUpIndicator`
+MissingNullability: androidx.appcompat.app.ActionBarDrawerToggle#setToolbarNavigationClickListener(android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `onToolbarNavigationClickListener` in method `setToolbarNavigationClickListener`
+MissingNullability: androidx.appcompat.app.ActionBarDrawerToggle.Delegate#getActionBarThemedContext():
+    Missing nullability on method `getActionBarThemedContext` return
+MissingNullability: androidx.appcompat.app.ActionBarDrawerToggle.Delegate#getThemeUpIndicator():
+    Missing nullability on method `getThemeUpIndicator` return
+MissingNullability: androidx.appcompat.app.ActionBarDrawerToggle.Delegate#setActionBarUpIndicator(android.graphics.drawable.Drawable, int) parameter #0:
+    Missing nullability on parameter `upDrawable` in method `setActionBarUpIndicator`
+MissingNullability: androidx.appcompat.app.AlertDialog#getButton(int):
+    Missing nullability on method `getButton` return
+MissingNullability: androidx.appcompat.app.AlertDialog#getListView():
+    Missing nullability on method `getListView` return
+MissingNullability: androidx.appcompat.app.AlertDialog#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.appcompat.app.AlertDialog#onKeyDown(int, android.view.KeyEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onKeyDown`
+MissingNullability: androidx.appcompat.app.AlertDialog#onKeyUp(int, android.view.KeyEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onKeyUp`
+MissingNullability: androidx.appcompat.app.AlertDialog#setButton(int, CharSequence, android.content.DialogInterface.OnClickListener) parameter #1:
+    Missing nullability on parameter `text` in method `setButton`
+MissingNullability: androidx.appcompat.app.AlertDialog#setButton(int, CharSequence, android.content.DialogInterface.OnClickListener) parameter #2:
+    Missing nullability on parameter `listener` in method `setButton`
+MissingNullability: androidx.appcompat.app.AlertDialog#setButton(int, CharSequence, android.graphics.drawable.Drawable, android.content.DialogInterface.OnClickListener) parameter #1:
+    Missing nullability on parameter `text` in method `setButton`
+MissingNullability: androidx.appcompat.app.AlertDialog#setButton(int, CharSequence, android.graphics.drawable.Drawable, android.content.DialogInterface.OnClickListener) parameter #2:
+    Missing nullability on parameter `icon` in method `setButton`
+MissingNullability: androidx.appcompat.app.AlertDialog#setButton(int, CharSequence, android.graphics.drawable.Drawable, android.content.DialogInterface.OnClickListener) parameter #3:
+    Missing nullability on parameter `listener` in method `setButton`
+MissingNullability: androidx.appcompat.app.AlertDialog#setButton(int, CharSequence, android.os.Message) parameter #1:
+    Missing nullability on parameter `text` in method `setButton`
+MissingNullability: androidx.appcompat.app.AlertDialog#setButton(int, CharSequence, android.os.Message) parameter #2:
+    Missing nullability on parameter `msg` in method `setButton`
+MissingNullability: androidx.appcompat.app.AlertDialog#setCustomTitle(android.view.View) parameter #0:
+    Missing nullability on parameter `customTitleView` in method `setCustomTitle`
+MissingNullability: androidx.appcompat.app.AlertDialog#setIcon(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `icon` in method `setIcon`
+MissingNullability: androidx.appcompat.app.AlertDialog#setMessage(CharSequence) parameter #0:
+    Missing nullability on parameter `message` in method `setMessage`
+MissingNullability: androidx.appcompat.app.AlertDialog#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.appcompat.app.AlertDialog#setView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `setView`
+MissingNullability: androidx.appcompat.app.AlertDialog#setView(android.view.View, int, int, int, int) parameter #0:
+    Missing nullability on parameter `view` in method `setView`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setAdapter(android.widget.ListAdapter, android.content.DialogInterface.OnClickListener):
+    Missing nullability on method `setAdapter` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setAdapter(android.widget.ListAdapter, android.content.DialogInterface.OnClickListener) parameter #0:
+    Missing nullability on parameter `adapter` in method `setAdapter`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setAdapter(android.widget.ListAdapter, android.content.DialogInterface.OnClickListener) parameter #1:
+    Missing nullability on parameter `listener` in method `setAdapter`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setCancelable(boolean):
+    Missing nullability on method `setCancelable` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setCursor(android.database.Cursor, android.content.DialogInterface.OnClickListener, String):
+    Missing nullability on method `setCursor` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setCursor(android.database.Cursor, android.content.DialogInterface.OnClickListener, String) parameter #0:
+    Missing nullability on parameter `cursor` in method `setCursor`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setCursor(android.database.Cursor, android.content.DialogInterface.OnClickListener, String) parameter #1:
+    Missing nullability on parameter `listener` in method `setCursor`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setCursor(android.database.Cursor, android.content.DialogInterface.OnClickListener, String) parameter #2:
+    Missing nullability on parameter `labelColumn` in method `setCursor`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setCustomTitle(android.view.View):
+    Missing nullability on method `setCustomTitle` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setIcon(android.graphics.drawable.Drawable):
+    Missing nullability on method `setIcon` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setIcon(int):
+    Missing nullability on method `setIcon` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setIconAttribute(int):
+    Missing nullability on method `setIconAttribute` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setItems(CharSequence[], android.content.DialogInterface.OnClickListener):
+    Missing nullability on method `setItems` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setItems(CharSequence[], android.content.DialogInterface.OnClickListener) parameter #0:
+    Missing nullability on parameter `items` in method `setItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setItems(CharSequence[], android.content.DialogInterface.OnClickListener) parameter #1:
+    Missing nullability on parameter `listener` in method `setItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setItems(int, android.content.DialogInterface.OnClickListener):
+    Missing nullability on method `setItems` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setItems(int, android.content.DialogInterface.OnClickListener) parameter #1:
+    Missing nullability on parameter `listener` in method `setItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setMessage(CharSequence):
+    Missing nullability on method `setMessage` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setMessage(int):
+    Missing nullability on method `setMessage` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setMultiChoiceItems(CharSequence[], boolean[], android.content.DialogInterface.OnMultiChoiceClickListener):
+    Missing nullability on method `setMultiChoiceItems` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setMultiChoiceItems(CharSequence[], boolean[], android.content.DialogInterface.OnMultiChoiceClickListener) parameter #0:
+    Missing nullability on parameter `items` in method `setMultiChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setMultiChoiceItems(CharSequence[], boolean[], android.content.DialogInterface.OnMultiChoiceClickListener) parameter #1:
+    Missing nullability on parameter `checkedItems` in method `setMultiChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setMultiChoiceItems(CharSequence[], boolean[], android.content.DialogInterface.OnMultiChoiceClickListener) parameter #2:
+    Missing nullability on parameter `listener` in method `setMultiChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setMultiChoiceItems(android.database.Cursor, String, String, android.content.DialogInterface.OnMultiChoiceClickListener):
+    Missing nullability on method `setMultiChoiceItems` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setMultiChoiceItems(android.database.Cursor, String, String, android.content.DialogInterface.OnMultiChoiceClickListener) parameter #0:
+    Missing nullability on parameter `cursor` in method `setMultiChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setMultiChoiceItems(android.database.Cursor, String, String, android.content.DialogInterface.OnMultiChoiceClickListener) parameter #1:
+    Missing nullability on parameter `isCheckedColumn` in method `setMultiChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setMultiChoiceItems(android.database.Cursor, String, String, android.content.DialogInterface.OnMultiChoiceClickListener) parameter #2:
+    Missing nullability on parameter `labelColumn` in method `setMultiChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setMultiChoiceItems(android.database.Cursor, String, String, android.content.DialogInterface.OnMultiChoiceClickListener) parameter #3:
+    Missing nullability on parameter `listener` in method `setMultiChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setMultiChoiceItems(int, boolean[], android.content.DialogInterface.OnMultiChoiceClickListener):
+    Missing nullability on method `setMultiChoiceItems` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setMultiChoiceItems(int, boolean[], android.content.DialogInterface.OnMultiChoiceClickListener) parameter #1:
+    Missing nullability on parameter `checkedItems` in method `setMultiChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setMultiChoiceItems(int, boolean[], android.content.DialogInterface.OnMultiChoiceClickListener) parameter #2:
+    Missing nullability on parameter `listener` in method `setMultiChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setNegativeButton(CharSequence, android.content.DialogInterface.OnClickListener):
+    Missing nullability on method `setNegativeButton` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setNegativeButton(CharSequence, android.content.DialogInterface.OnClickListener) parameter #0:
+    Missing nullability on parameter `text` in method `setNegativeButton`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setNegativeButton(CharSequence, android.content.DialogInterface.OnClickListener) parameter #1:
+    Missing nullability on parameter `listener` in method `setNegativeButton`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setNegativeButton(int, android.content.DialogInterface.OnClickListener):
+    Missing nullability on method `setNegativeButton` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setNegativeButton(int, android.content.DialogInterface.OnClickListener) parameter #1:
+    Missing nullability on parameter `listener` in method `setNegativeButton`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setNegativeButtonIcon(android.graphics.drawable.Drawable):
+    Missing nullability on method `setNegativeButtonIcon` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setNegativeButtonIcon(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `icon` in method `setNegativeButtonIcon`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setNeutralButton(CharSequence, android.content.DialogInterface.OnClickListener):
+    Missing nullability on method `setNeutralButton` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setNeutralButton(CharSequence, android.content.DialogInterface.OnClickListener) parameter #0:
+    Missing nullability on parameter `text` in method `setNeutralButton`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setNeutralButton(CharSequence, android.content.DialogInterface.OnClickListener) parameter #1:
+    Missing nullability on parameter `listener` in method `setNeutralButton`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setNeutralButton(int, android.content.DialogInterface.OnClickListener):
+    Missing nullability on method `setNeutralButton` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setNeutralButton(int, android.content.DialogInterface.OnClickListener) parameter #1:
+    Missing nullability on parameter `listener` in method `setNeutralButton`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setNeutralButtonIcon(android.graphics.drawable.Drawable):
+    Missing nullability on method `setNeutralButtonIcon` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setNeutralButtonIcon(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `icon` in method `setNeutralButtonIcon`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setOnCancelListener(android.content.DialogInterface.OnCancelListener):
+    Missing nullability on method `setOnCancelListener` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setOnCancelListener(android.content.DialogInterface.OnCancelListener) parameter #0:
+    Missing nullability on parameter `onCancelListener` in method `setOnCancelListener`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setOnDismissListener(android.content.DialogInterface.OnDismissListener):
+    Missing nullability on method `setOnDismissListener` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setOnDismissListener(android.content.DialogInterface.OnDismissListener) parameter #0:
+    Missing nullability on parameter `onDismissListener` in method `setOnDismissListener`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener):
+    Missing nullability on method `setOnItemSelectedListener` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemSelectedListener`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setOnKeyListener(android.content.DialogInterface.OnKeyListener):
+    Missing nullability on method `setOnKeyListener` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setOnKeyListener(android.content.DialogInterface.OnKeyListener) parameter #0:
+    Missing nullability on parameter `onKeyListener` in method `setOnKeyListener`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setPositiveButton(CharSequence, android.content.DialogInterface.OnClickListener):
+    Missing nullability on method `setPositiveButton` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setPositiveButton(CharSequence, android.content.DialogInterface.OnClickListener) parameter #0:
+    Missing nullability on parameter `text` in method `setPositiveButton`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setPositiveButton(CharSequence, android.content.DialogInterface.OnClickListener) parameter #1:
+    Missing nullability on parameter `listener` in method `setPositiveButton`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setPositiveButton(int, android.content.DialogInterface.OnClickListener):
+    Missing nullability on method `setPositiveButton` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setPositiveButton(int, android.content.DialogInterface.OnClickListener) parameter #1:
+    Missing nullability on parameter `listener` in method `setPositiveButton`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setPositiveButtonIcon(android.graphics.drawable.Drawable):
+    Missing nullability on method `setPositiveButtonIcon` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setPositiveButtonIcon(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `icon` in method `setPositiveButtonIcon`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setSingleChoiceItems(CharSequence[], int, android.content.DialogInterface.OnClickListener):
+    Missing nullability on method `setSingleChoiceItems` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setSingleChoiceItems(CharSequence[], int, android.content.DialogInterface.OnClickListener) parameter #0:
+    Missing nullability on parameter `items` in method `setSingleChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setSingleChoiceItems(CharSequence[], int, android.content.DialogInterface.OnClickListener) parameter #2:
+    Missing nullability on parameter `listener` in method `setSingleChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setSingleChoiceItems(android.database.Cursor, int, String, android.content.DialogInterface.OnClickListener):
+    Missing nullability on method `setSingleChoiceItems` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setSingleChoiceItems(android.database.Cursor, int, String, android.content.DialogInterface.OnClickListener) parameter #0:
+    Missing nullability on parameter `cursor` in method `setSingleChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setSingleChoiceItems(android.database.Cursor, int, String, android.content.DialogInterface.OnClickListener) parameter #2:
+    Missing nullability on parameter `labelColumn` in method `setSingleChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setSingleChoiceItems(android.database.Cursor, int, String, android.content.DialogInterface.OnClickListener) parameter #3:
+    Missing nullability on parameter `listener` in method `setSingleChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setSingleChoiceItems(android.widget.ListAdapter, int, android.content.DialogInterface.OnClickListener):
+    Missing nullability on method `setSingleChoiceItems` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setSingleChoiceItems(android.widget.ListAdapter, int, android.content.DialogInterface.OnClickListener) parameter #0:
+    Missing nullability on parameter `adapter` in method `setSingleChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setSingleChoiceItems(android.widget.ListAdapter, int, android.content.DialogInterface.OnClickListener) parameter #2:
+    Missing nullability on parameter `listener` in method `setSingleChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setSingleChoiceItems(int, int, android.content.DialogInterface.OnClickListener):
+    Missing nullability on method `setSingleChoiceItems` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setSingleChoiceItems(int, int, android.content.DialogInterface.OnClickListener) parameter #2:
+    Missing nullability on parameter `listener` in method `setSingleChoiceItems`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setTitle(CharSequence):
+    Missing nullability on method `setTitle` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setTitle(int):
+    Missing nullability on method `setTitle` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setView(android.view.View):
+    Missing nullability on method `setView` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `setView`
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#setView(int):
+    Missing nullability on method `setView` return
+MissingNullability: androidx.appcompat.app.AlertDialog.Builder#show():
+    Missing nullability on method `show` return
+MissingNullability: androidx.appcompat.app.AppCompatActivity#addContentView(android.view.View, android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `view` in method `addContentView`
+MissingNullability: androidx.appcompat.app.AppCompatActivity#addContentView(android.view.View, android.view.ViewGroup.LayoutParams) parameter #1:
+    Missing nullability on parameter `params` in method `addContentView`
+MissingNullability: androidx.appcompat.app.AppCompatActivity#attachBaseContext(android.content.Context) parameter #0:
+    Missing nullability on parameter `newBase` in method `attachBaseContext`
+MissingNullability: androidx.appcompat.app.AppCompatActivity#dispatchKeyEvent(android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `event` in method `dispatchKeyEvent`
+MissingNullability: androidx.appcompat.app.AppCompatActivity#getResources():
+    Missing nullability on method `getResources` return
+MissingNullability: androidx.appcompat.app.AppCompatActivity#onKeyDown(int, android.view.KeyEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onKeyDown`
+MissingNullability: androidx.appcompat.app.AppCompatActivity#onMenuOpened(int, android.view.Menu) parameter #1:
+    Missing nullability on parameter `menu` in method `onMenuOpened`
+MissingNullability: androidx.appcompat.app.AppCompatActivity#onTitleChanged(CharSequence, int) parameter #0:
+    Missing nullability on parameter `title` in method `onTitleChanged`
+MissingNullability: androidx.appcompat.app.AppCompatActivity#setContentView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `setContentView`
+MissingNullability: androidx.appcompat.app.AppCompatActivity#setContentView(android.view.View, android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `view` in method `setContentView`
+MissingNullability: androidx.appcompat.app.AppCompatActivity#setContentView(android.view.View, android.view.ViewGroup.LayoutParams) parameter #1:
+    Missing nullability on parameter `params` in method `setContentView`
+MissingNullability: androidx.appcompat.app.AppCompatCallback#onSupportActionModeFinished(androidx.appcompat.view.ActionMode) parameter #0:
+    Missing nullability on parameter `mode` in method `onSupportActionModeFinished`
+MissingNullability: androidx.appcompat.app.AppCompatCallback#onSupportActionModeStarted(androidx.appcompat.view.ActionMode) parameter #0:
+    Missing nullability on parameter `mode` in method `onSupportActionModeStarted`
+MissingNullability: androidx.appcompat.app.AppCompatCallback#onWindowStartingSupportActionMode(androidx.appcompat.view.ActionMode.Callback) parameter #0:
+    Missing nullability on parameter `callback` in method `onWindowStartingSupportActionMode`
+MissingNullability: androidx.appcompat.app.AppCompatDelegate#addContentView(android.view.View, android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `v` in method `addContentView`
+MissingNullability: androidx.appcompat.app.AppCompatDelegate#addContentView(android.view.View, android.view.ViewGroup.LayoutParams) parameter #1:
+    Missing nullability on parameter `lp` in method `addContentView`
+MissingNullability: androidx.appcompat.app.AppCompatDelegate#attachBaseContext(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `attachBaseContext`
+MissingNullability: androidx.appcompat.app.AppCompatDelegate#createView(android.view.View, String, android.content.Context, android.util.AttributeSet):
+    Missing nullability on method `createView` return
+MissingNullability: androidx.appcompat.app.AppCompatDelegate#createView(android.view.View, String, android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `name` in method `createView`
+MissingNullability: androidx.appcompat.app.AppCompatDelegate#getMenuInflater():
+    Missing nullability on method `getMenuInflater` return
+MissingNullability: androidx.appcompat.app.AppCompatDelegate#onConfigurationChanged(android.content.res.Configuration) parameter #0:
+    Missing nullability on parameter `newConfig` in method `onConfigurationChanged`
+MissingNullability: androidx.appcompat.app.AppCompatDelegate#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.appcompat.app.AppCompatDelegate#onPostCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onPostCreate`
+MissingNullability: androidx.appcompat.app.AppCompatDelegate#onSaveInstanceState(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `outState` in method `onSaveInstanceState`
+MissingNullability: androidx.appcompat.app.AppCompatDelegate#setContentView(android.view.View) parameter #0:
+    Missing nullability on parameter `v` in method `setContentView`
+MissingNullability: androidx.appcompat.app.AppCompatDelegate#setContentView(android.view.View, android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `v` in method `setContentView`
+MissingNullability: androidx.appcompat.app.AppCompatDelegate#setContentView(android.view.View, android.view.ViewGroup.LayoutParams) parameter #1:
+    Missing nullability on parameter `lp` in method `setContentView`
+MissingNullability: androidx.appcompat.app.AppCompatDialog#AppCompatDialog(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `AppCompatDialog`
+MissingNullability: androidx.appcompat.app.AppCompatDialog#AppCompatDialog(android.content.Context, boolean, android.content.DialogInterface.OnCancelListener) parameter #0:
+    Missing nullability on parameter `context` in method `AppCompatDialog`
+MissingNullability: androidx.appcompat.app.AppCompatDialog#AppCompatDialog(android.content.Context, boolean, android.content.DialogInterface.OnCancelListener) parameter #2:
+    Missing nullability on parameter `cancelListener` in method `AppCompatDialog`
+MissingNullability: androidx.appcompat.app.AppCompatDialog#AppCompatDialog(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `AppCompatDialog`
+MissingNullability: androidx.appcompat.app.AppCompatDialog#addContentView(android.view.View, android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `view` in method `addContentView`
+MissingNullability: androidx.appcompat.app.AppCompatDialog#addContentView(android.view.View, android.view.ViewGroup.LayoutParams) parameter #1:
+    Missing nullability on parameter `params` in method `addContentView`
+MissingNullability: androidx.appcompat.app.AppCompatDialog#dispatchKeyEvent(android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `event` in method `dispatchKeyEvent`
+MissingNullability: androidx.appcompat.app.AppCompatDialog#getDelegate():
+    Missing nullability on method `getDelegate` return
+MissingNullability: androidx.appcompat.app.AppCompatDialog#getSupportActionBar():
+    Missing nullability on method `getSupportActionBar` return
+MissingNullability: androidx.appcompat.app.AppCompatDialog#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.appcompat.app.AppCompatDialog#onSupportActionModeFinished(androidx.appcompat.view.ActionMode) parameter #0:
+    Missing nullability on parameter `mode` in method `onSupportActionModeFinished`
+MissingNullability: androidx.appcompat.app.AppCompatDialog#onSupportActionModeStarted(androidx.appcompat.view.ActionMode) parameter #0:
+    Missing nullability on parameter `mode` in method `onSupportActionModeStarted`
+MissingNullability: androidx.appcompat.app.AppCompatDialog#onWindowStartingSupportActionMode(androidx.appcompat.view.ActionMode.Callback) parameter #0:
+    Missing nullability on parameter `callback` in method `onWindowStartingSupportActionMode`
+MissingNullability: androidx.appcompat.app.AppCompatDialog#setContentView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `setContentView`
+MissingNullability: androidx.appcompat.app.AppCompatDialog#setContentView(android.view.View, android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `view` in method `setContentView`
+MissingNullability: androidx.appcompat.app.AppCompatDialog#setContentView(android.view.View, android.view.ViewGroup.LayoutParams) parameter #1:
+    Missing nullability on parameter `params` in method `setContentView`
+MissingNullability: androidx.appcompat.app.AppCompatDialog#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createAutoCompleteTextView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `createAutoCompleteTextView`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createAutoCompleteTextView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `createAutoCompleteTextView`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createButton(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `createButton`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createButton(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `createButton`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createCheckBox(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `createCheckBox`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createCheckBox(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `createCheckBox`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createCheckedTextView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `createCheckedTextView`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createCheckedTextView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `createCheckedTextView`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createEditText(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `createEditText`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createEditText(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `createEditText`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createImageButton(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `createImageButton`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createImageButton(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `createImageButton`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createImageView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `createImageView`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createImageView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `createImageView`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createMultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `createMultiAutoCompleteTextView`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createMultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `createMultiAutoCompleteTextView`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createRadioButton(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `createRadioButton`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createRadioButton(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `createRadioButton`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createRatingBar(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `createRatingBar`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createRatingBar(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `createRatingBar`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createSeekBar(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `createSeekBar`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createSeekBar(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `createSeekBar`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createSpinner(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `createSpinner`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createSpinner(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `createSpinner`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createTextView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `createTextView`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createTextView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `createTextView`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createToggleButton(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `createToggleButton`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createToggleButton(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `createToggleButton`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createView(android.content.Context, String, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `createView`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createView(android.content.Context, String, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `name` in method `createView`
+MissingNullability: androidx.appcompat.app.AppCompatViewInflater#createView(android.content.Context, String, android.util.AttributeSet) parameter #2:
+    Missing nullability on parameter `attrs` in method `createView`
+MissingNullability: androidx.appcompat.graphics.drawable.DrawerArrowDrawable#DrawerArrowDrawable(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `DrawerArrowDrawable`
+MissingNullability: androidx.appcompat.graphics.drawable.DrawerArrowDrawable#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
+MissingNullability: androidx.appcompat.graphics.drawable.DrawerArrowDrawable#getPaint():
+    Missing nullability on method `getPaint` return
+MissingNullability: androidx.appcompat.graphics.drawable.DrawerArrowDrawable#setColorFilter(android.graphics.ColorFilter) parameter #0:
+    Missing nullability on parameter `colorFilter` in method `setColorFilter`
+MissingNullability: androidx.appcompat.view.ActionMode#getCustomView():
+    Missing nullability on method `getCustomView` return
+MissingNullability: androidx.appcompat.view.ActionMode#getMenu():
+    Missing nullability on method `getMenu` return
+MissingNullability: androidx.appcompat.view.ActionMode#getMenuInflater():
+    Missing nullability on method `getMenuInflater` return
+MissingNullability: androidx.appcompat.view.ActionMode#getSubtitle():
+    Missing nullability on method `getSubtitle` return
+MissingNullability: androidx.appcompat.view.ActionMode#getTag():
+    Missing nullability on method `getTag` return
+MissingNullability: androidx.appcompat.view.ActionMode#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.appcompat.view.ActionMode#setCustomView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `setCustomView`
+MissingNullability: androidx.appcompat.view.ActionMode#setSubtitle(CharSequence) parameter #0:
+    Missing nullability on parameter `subtitle` in method `setSubtitle`
+MissingNullability: androidx.appcompat.view.ActionMode#setTag(Object) parameter #0:
+    Missing nullability on parameter `tag` in method `setTag`
+MissingNullability: androidx.appcompat.view.ActionMode#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.appcompat.view.ActionMode.Callback#onActionItemClicked(androidx.appcompat.view.ActionMode, android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `mode` in method `onActionItemClicked`
+MissingNullability: androidx.appcompat.view.ActionMode.Callback#onActionItemClicked(androidx.appcompat.view.ActionMode, android.view.MenuItem) parameter #1:
+    Missing nullability on parameter `item` in method `onActionItemClicked`
+MissingNullability: androidx.appcompat.view.ActionMode.Callback#onCreateActionMode(androidx.appcompat.view.ActionMode, android.view.Menu) parameter #0:
+    Missing nullability on parameter `mode` in method `onCreateActionMode`
+MissingNullability: androidx.appcompat.view.ActionMode.Callback#onCreateActionMode(androidx.appcompat.view.ActionMode, android.view.Menu) parameter #1:
+    Missing nullability on parameter `menu` in method `onCreateActionMode`
+MissingNullability: androidx.appcompat.view.ActionMode.Callback#onDestroyActionMode(androidx.appcompat.view.ActionMode) parameter #0:
+    Missing nullability on parameter `mode` in method `onDestroyActionMode`
+MissingNullability: androidx.appcompat.view.ActionMode.Callback#onPrepareActionMode(androidx.appcompat.view.ActionMode, android.view.Menu) parameter #0:
+    Missing nullability on parameter `mode` in method `onPrepareActionMode`
+MissingNullability: androidx.appcompat.view.ActionMode.Callback#onPrepareActionMode(androidx.appcompat.view.ActionMode, android.view.Menu) parameter #1:
+    Missing nullability on parameter `menu` in method `onPrepareActionMode`
+MissingNullability: androidx.appcompat.view.ContextThemeWrapper#ContextThemeWrapper(android.content.Context, android.content.res.Resources.Theme) parameter #0:
+    Missing nullability on parameter `base` in method `ContextThemeWrapper`
+MissingNullability: androidx.appcompat.view.ContextThemeWrapper#ContextThemeWrapper(android.content.Context, android.content.res.Resources.Theme) parameter #1:
+    Missing nullability on parameter `theme` in method `ContextThemeWrapper`
+MissingNullability: androidx.appcompat.view.ContextThemeWrapper#ContextThemeWrapper(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `base` in method `ContextThemeWrapper`
+MissingNullability: androidx.appcompat.view.ContextThemeWrapper#applyOverrideConfiguration(android.content.res.Configuration) parameter #0:
+    Missing nullability on parameter `overrideConfiguration` in method `applyOverrideConfiguration`
+MissingNullability: androidx.appcompat.view.ContextThemeWrapper#attachBaseContext(android.content.Context) parameter #0:
+    Missing nullability on parameter `newBase` in method `attachBaseContext`
+MissingNullability: androidx.appcompat.view.ContextThemeWrapper#getAssets():
+    Missing nullability on method `getAssets` return
+MissingNullability: androidx.appcompat.view.ContextThemeWrapper#getResources():
+    Missing nullability on method `getResources` return
+MissingNullability: androidx.appcompat.view.ContextThemeWrapper#getSystemService(String):
+    Missing nullability on method `getSystemService` return
+MissingNullability: androidx.appcompat.view.ContextThemeWrapper#getSystemService(String) parameter #0:
+    Missing nullability on parameter `name` in method `getSystemService`
+MissingNullability: androidx.appcompat.view.ContextThemeWrapper#getTheme():
+    Missing nullability on method `getTheme` return
+MissingNullability: androidx.appcompat.view.ContextThemeWrapper#onApplyThemeResource(android.content.res.Resources.Theme, int, boolean) parameter #0:
+    Missing nullability on parameter `theme` in method `onApplyThemeResource`
+MissingNullability: androidx.appcompat.widget.ActionMenuView#checkLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `checkLayoutParams`
+MissingNullability: androidx.appcompat.widget.ActionMenuView#dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `event` in method `dispatchPopulateAccessibilityEvent`
+MissingNullability: androidx.appcompat.widget.ActionMenuView#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.appcompat.widget.ActionMenuView#generateLayoutParams(android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.appcompat.widget.ActionMenuView#generateLayoutParams(android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.appcompat.widget.ActionMenuView#generateLayoutParams(android.view.ViewGroup.LayoutParams):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.appcompat.widget.ActionMenuView#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `generateLayoutParams`
+MissingNullability: androidx.appcompat.widget.ActionMenuView#getMenu():
+    Missing nullability on method `getMenu` return
+MissingNullability: androidx.appcompat.widget.ActionMenuView#onConfigurationChanged(android.content.res.Configuration) parameter #0:
+    Missing nullability on parameter `newConfig` in method `onConfigurationChanged`
+MissingNullability: androidx.appcompat.widget.ActionMenuView#setOnMenuItemClickListener(androidx.appcompat.widget.ActionMenuView.OnMenuItemClickListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnMenuItemClickListener`
+MissingNullability: androidx.appcompat.widget.ActionMenuView.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `c` in method `LayoutParams`
+MissingNullability: androidx.appcompat.widget.ActionMenuView.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `LayoutParams`
+MissingNullability: androidx.appcompat.widget.ActionMenuView.LayoutParams#LayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `other` in method `LayoutParams`
+MissingNullability: androidx.appcompat.widget.ActionMenuView.LayoutParams#LayoutParams(androidx.appcompat.widget.ActionMenuView.LayoutParams) parameter #0:
+    Missing nullability on parameter `other` in method `LayoutParams`
+MissingNullability: androidx.appcompat.widget.ActionMenuView.OnMenuItemClickListener#onMenuItemClick(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `onMenuItemClick`
+MissingNullability: androidx.appcompat.widget.AppCompatAutoCompleteTextView#onCreateInputConnection(android.view.inputmethod.EditorInfo):
+    Missing nullability on method `onCreateInputConnection` return
+MissingNullability: androidx.appcompat.widget.AppCompatAutoCompleteTextView#onCreateInputConnection(android.view.inputmethod.EditorInfo) parameter #0:
+    Missing nullability on parameter `outAttrs` in method `onCreateInputConnection`
+MissingNullability: androidx.appcompat.widget.AppCompatAutoCompleteTextView#setBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `background` in method `setBackgroundDrawable`
+MissingNullability: androidx.appcompat.widget.AppCompatAutoCompleteTextView#setCustomSelectionActionModeCallback(android.view.ActionMode.Callback) parameter #0:
+    Missing nullability on parameter `actionModeCallback` in method `setCustomSelectionActionModeCallback`
+MissingNullability: androidx.appcompat.widget.AppCompatAutoCompleteTextView#setTextAppearance(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `setTextAppearance`
+MissingNullability: androidx.appcompat.widget.AppCompatButton#onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `event` in method `onInitializeAccessibilityEvent`
+MissingNullability: androidx.appcompat.widget.AppCompatButton#onInitializeAccessibilityNodeInfo(android.view.accessibility.AccessibilityNodeInfo) parameter #0:
+    Missing nullability on parameter `info` in method `onInitializeAccessibilityNodeInfo`
+MissingNullability: androidx.appcompat.widget.AppCompatButton#onTextChanged(CharSequence, int, int, int) parameter #0:
+    Missing nullability on parameter `text` in method `onTextChanged`
+MissingNullability: androidx.appcompat.widget.AppCompatButton#setBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `background` in method `setBackgroundDrawable`
+MissingNullability: androidx.appcompat.widget.AppCompatButton#setCustomSelectionActionModeCallback(android.view.ActionMode.Callback) parameter #0:
+    Missing nullability on parameter `actionModeCallback` in method `setCustomSelectionActionModeCallback`
+MissingNullability: androidx.appcompat.widget.AppCompatButton#setTextAppearance(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `setTextAppearance`
+MissingNullability: androidx.appcompat.widget.AppCompatCheckBox#setBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `background` in method `setBackgroundDrawable`
+MissingNullability: androidx.appcompat.widget.AppCompatCheckBox#setButtonDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `buttonDrawable` in method `setButtonDrawable`
+MissingNullability: androidx.appcompat.widget.AppCompatCheckedTextView#onCreateInputConnection(android.view.inputmethod.EditorInfo):
+    Missing nullability on method `onCreateInputConnection` return
+MissingNullability: androidx.appcompat.widget.AppCompatCheckedTextView#onCreateInputConnection(android.view.inputmethod.EditorInfo) parameter #0:
+    Missing nullability on parameter `outAttrs` in method `onCreateInputConnection`
+MissingNullability: androidx.appcompat.widget.AppCompatCheckedTextView#setCustomSelectionActionModeCallback(android.view.ActionMode.Callback) parameter #0:
+    Missing nullability on parameter `actionModeCallback` in method `setCustomSelectionActionModeCallback`
+MissingNullability: androidx.appcompat.widget.AppCompatCheckedTextView#setTextAppearance(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `setTextAppearance`
+MissingNullability: androidx.appcompat.widget.AppCompatEditText#onCreateInputConnection(android.view.inputmethod.EditorInfo):
+    Missing nullability on method `onCreateInputConnection` return
+MissingNullability: androidx.appcompat.widget.AppCompatEditText#onCreateInputConnection(android.view.inputmethod.EditorInfo) parameter #0:
+    Missing nullability on parameter `outAttrs` in method `onCreateInputConnection`
+MissingNullability: androidx.appcompat.widget.AppCompatEditText#setBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `background` in method `setBackgroundDrawable`
+MissingNullability: androidx.appcompat.widget.AppCompatEditText#setCustomSelectionActionModeCallback(android.view.ActionMode.Callback) parameter #0:
+    Missing nullability on parameter `actionModeCallback` in method `setCustomSelectionActionModeCallback`
+MissingNullability: androidx.appcompat.widget.AppCompatEditText#setTextAppearance(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `setTextAppearance`
+MissingNullability: androidx.appcompat.widget.AppCompatImageButton#setBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `background` in method `setBackgroundDrawable`
+MissingNullability: androidx.appcompat.widget.AppCompatImageButton#setImageBitmap(android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `bm` in method `setImageBitmap`
+MissingNullability: androidx.appcompat.widget.AppCompatImageView#setBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `background` in method `setBackgroundDrawable`
+MissingNullability: androidx.appcompat.widget.AppCompatImageView#setImageBitmap(android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `bm` in method `setImageBitmap`
+MissingNullability: androidx.appcompat.widget.AppCompatMultiAutoCompleteTextView#onCreateInputConnection(android.view.inputmethod.EditorInfo):
+    Missing nullability on method `onCreateInputConnection` return
+MissingNullability: androidx.appcompat.widget.AppCompatMultiAutoCompleteTextView#onCreateInputConnection(android.view.inputmethod.EditorInfo) parameter #0:
+    Missing nullability on parameter `outAttrs` in method `onCreateInputConnection`
+MissingNullability: androidx.appcompat.widget.AppCompatMultiAutoCompleteTextView#setBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `background` in method `setBackgroundDrawable`
+MissingNullability: androidx.appcompat.widget.AppCompatMultiAutoCompleteTextView#setTextAppearance(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `setTextAppearance`
+MissingNullability: androidx.appcompat.widget.AppCompatRadioButton#AppCompatRadioButton(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `AppCompatRadioButton`
+MissingNullability: androidx.appcompat.widget.AppCompatRadioButton#AppCompatRadioButton(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `AppCompatRadioButton`
+MissingNullability: androidx.appcompat.widget.AppCompatRadioButton#AppCompatRadioButton(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `AppCompatRadioButton`
+MissingNullability: androidx.appcompat.widget.AppCompatRadioButton#setBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `background` in method `setBackgroundDrawable`
+MissingNullability: androidx.appcompat.widget.AppCompatRadioButton#setButtonDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `buttonDrawable` in method `setButtonDrawable`
+MissingNullability: androidx.appcompat.widget.AppCompatSeekBar#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `onDraw`
+MissingNullability: androidx.appcompat.widget.AppCompatSpinner#AppCompatSpinner(android.content.Context, android.util.AttributeSet, int, int, android.content.res.Resources.Theme) parameter #4:
+    Missing nullability on parameter `popupTheme` in method `AppCompatSpinner`
+MissingNullability: androidx.appcompat.widget.AppCompatSpinner#getPopupBackground():
+    Missing nullability on method `getPopupBackground` return
+MissingNullability: androidx.appcompat.widget.AppCompatSpinner#getPopupContext():
+    Missing nullability on method `getPopupContext` return
+MissingNullability: androidx.appcompat.widget.AppCompatSpinner#getPrompt():
+    Missing nullability on method `getPrompt` return
+MissingNullability: androidx.appcompat.widget.AppCompatSpinner#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.appcompat.widget.AppCompatSpinner#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.appcompat.widget.AppCompatSpinner#onTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `event` in method `onTouchEvent`
+MissingNullability: androidx.appcompat.widget.AppCompatSpinner#setAdapter(android.widget.SpinnerAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setAdapter`
+MissingNullability: androidx.appcompat.widget.AppCompatSpinner#setBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `background` in method `setBackgroundDrawable`
+MissingNullability: androidx.appcompat.widget.AppCompatSpinner#setPopupBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `background` in method `setPopupBackgroundDrawable`
+MissingNullability: androidx.appcompat.widget.AppCompatSpinner#setPrompt(CharSequence) parameter #0:
+    Missing nullability on parameter `prompt` in method `setPrompt`
+MissingNullability: androidx.appcompat.widget.AppCompatTextView#getText():
+    Missing nullability on method `getText` return
+MissingNullability: androidx.appcompat.widget.AppCompatTextView#onCreateInputConnection(android.view.inputmethod.EditorInfo):
+    Missing nullability on method `onCreateInputConnection` return
+MissingNullability: androidx.appcompat.widget.AppCompatTextView#onCreateInputConnection(android.view.inputmethod.EditorInfo) parameter #0:
+    Missing nullability on parameter `outAttrs` in method `onCreateInputConnection`
+MissingNullability: androidx.appcompat.widget.AppCompatTextView#onTextChanged(CharSequence, int, int, int) parameter #0:
+    Missing nullability on parameter `text` in method `onTextChanged`
+MissingNullability: androidx.appcompat.widget.AppCompatTextView#setBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `background` in method `setBackgroundDrawable`
+MissingNullability: androidx.appcompat.widget.AppCompatTextView#setCustomSelectionActionModeCallback(android.view.ActionMode.Callback) parameter #0:
+    Missing nullability on parameter `actionModeCallback` in method `setCustomSelectionActionModeCallback`
+MissingNullability: androidx.appcompat.widget.AppCompatTextView#setTextAppearance(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `setTextAppearance`
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat#checkLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `checkLayoutParams`
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat#generateLayoutParams(android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat#generateLayoutParams(android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat#generateLayoutParams(android.view.ViewGroup.LayoutParams):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `generateLayoutParams`
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat#getDividerDrawable():
+    Missing nullability on method `getDividerDrawable` return
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `onDraw`
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat#onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `event` in method `onInitializeAccessibilityEvent`
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat#onInitializeAccessibilityNodeInfo(android.view.accessibility.AccessibilityNodeInfo) parameter #0:
+    Missing nullability on parameter `info` in method `onInitializeAccessibilityNodeInfo`
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat#setDividerDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `divider` in method `setDividerDrawable`
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `c` in method `LayoutParams`
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `LayoutParams`
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat.LayoutParams#LayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `LayoutParams`
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat.LayoutParams#LayoutParams(android.view.ViewGroup.MarginLayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat.LayoutParams#LayoutParams(androidx.appcompat.widget.LinearLayoutCompat.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.appcompat.widget.ListPopupWindow#createDragToOpenListener(android.view.View):
+    Missing nullability on method `createDragToOpenListener` return
+MissingNullability: androidx.appcompat.widget.ListPopupWindow#createDragToOpenListener(android.view.View) parameter #0:
+    Missing nullability on parameter `src` in method `createDragToOpenListener`
+MissingNullability: androidx.appcompat.widget.ListPopupWindow#setListSelector(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `selector` in method `setListSelector`
+MissingNullability: androidx.appcompat.widget.PopupMenu.OnDismissListener#onDismiss(androidx.appcompat.widget.PopupMenu) parameter #0:
+    Missing nullability on parameter `menu` in method `onDismiss`
+MissingNullability: androidx.appcompat.widget.PopupMenu.OnMenuItemClickListener#onMenuItemClick(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `onMenuItemClick`
+MissingNullability: androidx.appcompat.widget.SearchView#getQuery():
+    Missing nullability on method `getQuery` return
+MissingNullability: androidx.appcompat.widget.SearchView#getSuggestionsAdapter():
+    Missing nullability on method `getSuggestionsAdapter` return
+MissingNullability: androidx.appcompat.widget.SearchView#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.appcompat.widget.SearchView#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.appcompat.widget.SearchView#requestFocus(int, android.graphics.Rect) parameter #1:
+    Missing nullability on parameter `previouslyFocusedRect` in method `requestFocus`
+MissingNullability: androidx.appcompat.widget.SearchView#setOnCloseListener(androidx.appcompat.widget.SearchView.OnCloseListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnCloseListener`
+MissingNullability: androidx.appcompat.widget.SearchView#setOnQueryTextFocusChangeListener(android.view.View.OnFocusChangeListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnQueryTextFocusChangeListener`
+MissingNullability: androidx.appcompat.widget.SearchView#setOnQueryTextListener(androidx.appcompat.widget.SearchView.OnQueryTextListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnQueryTextListener`
+MissingNullability: androidx.appcompat.widget.SearchView#setOnSearchClickListener(android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnSearchClickListener`
+MissingNullability: androidx.appcompat.widget.SearchView#setOnSuggestionListener(androidx.appcompat.widget.SearchView.OnSuggestionListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnSuggestionListener`
+MissingNullability: androidx.appcompat.widget.SearchView#setQuery(CharSequence, boolean) parameter #0:
+    Missing nullability on parameter `query` in method `setQuery`
+MissingNullability: androidx.appcompat.widget.SearchView#setSearchableInfo(android.app.SearchableInfo) parameter #0:
+    Missing nullability on parameter `searchable` in method `setSearchableInfo`
+MissingNullability: androidx.appcompat.widget.SearchView#setSuggestionsAdapter(androidx.cursoradapter.widget.CursorAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setSuggestionsAdapter`
+MissingNullability: androidx.appcompat.widget.SearchView.OnQueryTextListener#onQueryTextChange(String) parameter #0:
+    Missing nullability on parameter `newText` in method `onQueryTextChange`
+MissingNullability: androidx.appcompat.widget.SearchView.OnQueryTextListener#onQueryTextSubmit(String) parameter #0:
+    Missing nullability on parameter `query` in method `onQueryTextSubmit`
+MissingNullability: androidx.appcompat.widget.ShareActionProvider#ShareActionProvider(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `ShareActionProvider`
+MissingNullability: androidx.appcompat.widget.ShareActionProvider#onCreateActionView():
+    Missing nullability on method `onCreateActionView` return
+MissingNullability: androidx.appcompat.widget.ShareActionProvider#onPrepareSubMenu(android.view.SubMenu) parameter #0:
+    Missing nullability on parameter `subMenu` in method `onPrepareSubMenu`
+MissingNullability: androidx.appcompat.widget.ShareActionProvider#setOnShareTargetSelectedListener(androidx.appcompat.widget.ShareActionProvider.OnShareTargetSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnShareTargetSelectedListener`
+MissingNullability: androidx.appcompat.widget.ShareActionProvider#setShareHistoryFileName(String) parameter #0:
+    Missing nullability on parameter `shareHistoryFile` in method `setShareHistoryFileName`
+MissingNullability: androidx.appcompat.widget.ShareActionProvider#setShareIntent(android.content.Intent) parameter #0:
+    Missing nullability on parameter `shareIntent` in method `setShareIntent`
+MissingNullability: androidx.appcompat.widget.ShareActionProvider.OnShareTargetSelectedListener#onShareTargetSelected(androidx.appcompat.widget.ShareActionProvider, android.content.Intent) parameter #0:
+    Missing nullability on parameter `source` in method `onShareTargetSelected`
+MissingNullability: androidx.appcompat.widget.ShareActionProvider.OnShareTargetSelectedListener#onShareTargetSelected(androidx.appcompat.widget.ShareActionProvider, android.content.Intent) parameter #1:
+    Missing nullability on parameter `intent` in method `onShareTargetSelected`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `c` in method `draw`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#getTextOff():
+    Missing nullability on method `getTextOff` return
+MissingNullability: androidx.appcompat.widget.SwitchCompat#getTextOn():
+    Missing nullability on method `getTextOn` return
+MissingNullability: androidx.appcompat.widget.SwitchCompat#getThumbDrawable():
+    Missing nullability on method `getThumbDrawable` return
+MissingNullability: androidx.appcompat.widget.SwitchCompat#getTrackDrawable():
+    Missing nullability on method `getTrackDrawable` return
+MissingNullability: androidx.appcompat.widget.SwitchCompat#onCreateDrawableState(int):
+    Missing nullability on method `onCreateDrawableState` return
+MissingNullability: androidx.appcompat.widget.SwitchCompat#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `onDraw`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `event` in method `onInitializeAccessibilityEvent`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#onInitializeAccessibilityNodeInfo(android.view.accessibility.AccessibilityNodeInfo) parameter #0:
+    Missing nullability on parameter `info` in method `onInitializeAccessibilityNodeInfo`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `event` in method `onPopulateAccessibilityEvent`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#onTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onTouchEvent`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#setCustomSelectionActionModeCallback(android.view.ActionMode.Callback) parameter #0:
+    Missing nullability on parameter `actionModeCallback` in method `setCustomSelectionActionModeCallback`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#setSwitchTextAppearance(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `setSwitchTextAppearance`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#setSwitchTypeface(android.graphics.Typeface) parameter #0:
+    Missing nullability on parameter `typeface` in method `setSwitchTypeface`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#setSwitchTypeface(android.graphics.Typeface, int) parameter #0:
+    Missing nullability on parameter `tf` in method `setSwitchTypeface`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#setTextOff(CharSequence) parameter #0:
+    Missing nullability on parameter `textOff` in method `setTextOff`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#setTextOn(CharSequence) parameter #0:
+    Missing nullability on parameter `textOn` in method `setTextOn`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#setThumbDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `thumb` in method `setThumbDrawable`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#setTrackDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `track` in method `setTrackDrawable`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#verifyDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `who` in method `verifyDrawable`
+MissingNullability: androidx.appcompat.widget.Toolbar#checkLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `checkLayoutParams`
+MissingNullability: androidx.appcompat.widget.Toolbar#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.appcompat.widget.Toolbar#generateLayoutParams(android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.appcompat.widget.Toolbar#generateLayoutParams(android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.appcompat.widget.Toolbar#generateLayoutParams(android.view.ViewGroup.LayoutParams):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.appcompat.widget.Toolbar#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `generateLayoutParams`
+MissingNullability: androidx.appcompat.widget.Toolbar#getLogo():
+    Missing nullability on method `getLogo` return
+MissingNullability: androidx.appcompat.widget.Toolbar#getLogoDescription():
+    Missing nullability on method `getLogoDescription` return
+MissingNullability: androidx.appcompat.widget.Toolbar#getMenu():
+    Missing nullability on method `getMenu` return
+MissingNullability: androidx.appcompat.widget.Toolbar#getSubtitle():
+    Missing nullability on method `getSubtitle` return
+MissingNullability: androidx.appcompat.widget.Toolbar#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.appcompat.widget.Toolbar#onHoverEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onHoverEvent`
+MissingNullability: androidx.appcompat.widget.Toolbar#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.appcompat.widget.Toolbar#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.appcompat.widget.Toolbar#onTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onTouchEvent`
+MissingNullability: androidx.appcompat.widget.Toolbar#setLogo(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setLogo`
+MissingNullability: androidx.appcompat.widget.Toolbar#setLogoDescription(CharSequence) parameter #0:
+    Missing nullability on parameter `description` in method `setLogoDescription`
+MissingNullability: androidx.appcompat.widget.Toolbar#setNavigationOnClickListener(android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setNavigationOnClickListener`
+MissingNullability: androidx.appcompat.widget.Toolbar#setOnMenuItemClickListener(androidx.appcompat.widget.Toolbar.OnMenuItemClickListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnMenuItemClickListener`
+MissingNullability: androidx.appcompat.widget.Toolbar#setSubtitle(CharSequence) parameter #0:
+    Missing nullability on parameter `subtitle` in method `setSubtitle`
+MissingNullability: androidx.appcompat.widget.Toolbar#setSubtitleTextAppearance(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `setSubtitleTextAppearance`
+MissingNullability: androidx.appcompat.widget.Toolbar#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.appcompat.widget.Toolbar#setTitleTextAppearance(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `setTitleTextAppearance`
+MissingNullability: androidx.appcompat.widget.Toolbar.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `LayoutParams`
+MissingNullability: androidx.appcompat.widget.Toolbar.LayoutParams#LayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.appcompat.widget.Toolbar.LayoutParams#LayoutParams(android.view.ViewGroup.MarginLayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.appcompat.widget.Toolbar.LayoutParams#LayoutParams(androidx.appcompat.app.ActionBar.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.appcompat.widget.Toolbar.LayoutParams#LayoutParams(androidx.appcompat.widget.Toolbar.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.appcompat.widget.Toolbar.OnMenuItemClickListener#onMenuItemClick(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `onMenuItemClick`
+MissingNullability: androidx.appcompat.widget.Toolbar.SavedState#CREATOR:
+    Missing nullability on field `CREATOR` in class `class androidx.appcompat.widget.Toolbar.SavedState`
+MissingNullability: androidx.appcompat.widget.Toolbar.SavedState#SavedState(android.os.Parcel) parameter #0:
+    Missing nullability on parameter `source` in method `SavedState`
+MissingNullability: androidx.appcompat.widget.Toolbar.SavedState#SavedState(android.os.Parcel, ClassLoader) parameter #0:
+    Missing nullability on parameter `source` in method `SavedState`
+MissingNullability: androidx.appcompat.widget.Toolbar.SavedState#SavedState(android.os.Parcel, ClassLoader) parameter #1:
+    Missing nullability on parameter `loader` in method `SavedState`
+MissingNullability: androidx.appcompat.widget.Toolbar.SavedState#SavedState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `superState` in method `SavedState`
+MissingNullability: androidx.appcompat.widget.Toolbar.SavedState#writeToParcel(android.os.Parcel, int) parameter #0:
+    Missing nullability on parameter `out` in method `writeToParcel`
+
+
 ParcelConstructor: androidx.appcompat.widget.Toolbar.SavedState#SavedState(android.os.Parcel):
     Parcelable inflation is exposed through CREATOR, not raw constructors, in androidx.appcompat.widget.Toolbar.SavedState
 
diff --git a/appcompat/build.gradle b/appcompat/build.gradle
index 5ce2ab6..0f1a603 100644
--- a/appcompat/build.gradle
+++ b/appcompat/build.gradle
@@ -53,6 +53,10 @@
         noCompress 'ttf'
     }
 
+    testOptions {
+        animationsDisabled = true
+    }
+
     buildTypes.all {
         consumerProguardFiles("proguard-rules.pro")
     }
diff --git a/appcompat/res/values/themes_base.xml b/appcompat/res/values/themes_base.xml
index 6ca69aa..db97f83 100644
--- a/appcompat/res/values/themes_base.xml
+++ b/appcompat/res/values/themes_base.xml
@@ -173,7 +173,6 @@
 
     <!-- Base platform-dependent theme providing an action bar in a dark-themed activity. -->
     <style name="Base.V7.Theme.AppCompat" parent="Platform.AppCompat">
-        <item name="viewInflaterClass">androidx.appcompat.app.AppCompatViewInflater</item>
         <item name="windowNoTitle">false</item>
         <item name="windowActionBar">true</item>
         <item name="windowActionBarOverlay">false</item>
@@ -346,8 +345,6 @@
 
     <!-- Base platform-dependent theme providing an action bar in a light-themed activity. -->
     <style name="Base.V7.Theme.AppCompat.Light" parent="Platform.AppCompat.Light">
-        <item name="viewInflaterClass">androidx.appcompat.app.AppCompatViewInflater</item>
-
         <item name="windowNoTitle">false</item>
         <item name="windowActionBar">true</item>
         <item name="windowActionBarOverlay">false</item>
diff --git a/appcompat/resources/api/api_lint.ignore b/appcompat/resources/api/api_lint.ignore
new file mode 100644
index 0000000..744e4a2
--- /dev/null
+++ b/appcompat/resources/api/api_lint.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+MissingNullability: androidx.appcompat.content.res.AppCompatResources#getColorStateList(android.content.Context, int):
+    Missing nullability on method `getColorStateList` return
+MissingNullability: androidx.appcompat.graphics.drawable.AnimatedStateListDrawableCompat#createFromXmlInner(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme):
+    Missing nullability on method `createFromXmlInner` return
+MissingNullability: androidx.appcompat.graphics.drawable.AnimatedStateListDrawableCompat#mutate():
+    Missing nullability on method `mutate` return
+MissingNullability: androidx.appcompat.graphics.drawable.AnimatedStateListDrawableCompat#onStateChange(int[]) parameter #0:
+    Missing nullability on parameter `stateSet` in method `onStateChange`
diff --git a/appcompat/src/androidTest/java/androidx/appcompat/app/EmptyOptionsPanelTest.java b/appcompat/src/androidTest/java/androidx/appcompat/app/EmptyOptionsPanelTest.java
index c9ebc29..3c61a48 100644
--- a/appcompat/src/androidTest/java/androidx/appcompat/app/EmptyOptionsPanelTest.java
+++ b/appcompat/src/androidTest/java/androidx/appcompat/app/EmptyOptionsPanelTest.java
@@ -53,8 +53,9 @@
         mActivity = mActivityTestRule.getActivity();
     }
 
-    // executeShellCommandAndFind() is only available on API 18+
-    @SdkSuppress(minSdkVersion = 18)
+    // executeShellCommandAndFind() is only available on API 21+ and for some reason the shell
+    // command doesn't execute correctly below API 26, so suppress everything below that.
+    @SdkSuppress(minSdkVersion = 26)
     @Test
     @MediumTest
     public void testEmptyOptionsPanelNotShown() throws Exception {
diff --git a/appcompat/src/androidTest/java/androidx/appcompat/testutils/TestUtils.java b/appcompat/src/androidTest/java/androidx/appcompat/testutils/TestUtils.java
index 2d6f748..c0b1fa1c 100644
--- a/appcompat/src/androidTest/java/androidx/appcompat/testutils/TestUtils.java
+++ b/appcompat/src/androidTest/java/androidx/appcompat/testutils/TestUtils.java
@@ -307,6 +307,7 @@
      * @param offsetX extra X offset for the tap
      * @param offsetY extra Y offset for the tap
      */
+    @RequiresApi(16)
     public static void emulateTapOnView(Instrumentation instrumentation,
             ActivityTestRule<?> activityTestRule, View anchorView,
             int offsetX, int offsetY) {
@@ -370,6 +371,7 @@
      * @param runner the runnable to run on the main thread, or {@code null} to
      *               simply force invalidation and a draw pass
      */
+    @RequiresApi(16)
     public static void runOnMainAndDrawSync(@NonNull final ActivityTestRule activityTestRule,
             @NonNull final View view, @Nullable final Runnable runner) {
         final CountDownLatch latch = new CountDownLatch(1);
@@ -419,9 +421,9 @@
      * Executes the given shell command and returns true if any line matches the find predicate, or
      * false otherwise.
      * <p>
-     * Requires API 18+ due to UiAutomation dependency.
+     * Requires API 21+ due to UiAutomation.executeShellCommand() dependency.
      */
-    @RequiresApi(18)
+    @RequiresApi(21)
     public static boolean executeShellCommandAndFind(@NonNull String cmd,
             @NonNull Predicate<String> find) throws IOException {
         InputStream stdout = new ParcelFileDescriptor.AutoCloseInputStream(
diff --git a/appcompat/src/androidTest/java/androidx/appcompat/testutils/TestUtilsActions.java b/appcompat/src/androidTest/java/androidx/appcompat/testutils/TestUtilsActions.java
index 67224bd..71cd925 100644
--- a/appcompat/src/androidTest/java/androidx/appcompat/testutils/TestUtilsActions.java
+++ b/appcompat/src/androidTest/java/androidx/appcompat/testutils/TestUtilsActions.java
@@ -205,17 +205,36 @@
             public void perform(UiController uiController, View view) {
                 uiController.loopMainThreadUntilIdle();
 
-                switch (activity.getRequestedOrientation()) {
-                    case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
-                        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-                        break;
-                    default:
-                        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
-                        break;
+                if (activity.getRequestedOrientation()
+                        == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
+                    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+                } else {
+                    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                 }
 
                 uiController.loopMainThreadUntilIdle();
             }
         };
     }
+
+    public static ViewAction setScreenOrientation(final Activity activity, final int orientation) {
+        return new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isDisplayed();
+            }
+
+            @Override
+            public String getDescription() {
+                return "Rotating screen orientation";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+                activity.setRequestedOrientation(orientation);
+                uiController.loopMainThreadUntilIdle();
+            }
+        };
+    }
 }
diff --git a/appcompat/src/androidTest/java/androidx/appcompat/testutils/TestUtilsMatchers.java b/appcompat/src/androidTest/java/androidx/appcompat/testutils/TestUtilsMatchers.java
index 1a202a4..30d6367 100644
--- a/appcompat/src/androidTest/java/androidx/appcompat/testutils/TestUtilsMatchers.java
+++ b/appcompat/src/androidTest/java/androidx/appcompat/testutils/TestUtilsMatchers.java
@@ -30,6 +30,7 @@
 import androidx.core.view.TintableBackgroundView;
 import androidx.test.espresso.matcher.BoundedMatcher;
 
+import org.hamcrest.BaseMatcher;
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
 import org.hamcrest.TypeSafeMatcher;
@@ -41,7 +42,7 @@
      * Returns a matcher that matches <code>ImageView</code>s which have drawable flat-filled
      * with the specific color.
      */
-    public static Matcher drawable(@ColorInt final int color) {
+    public static Matcher<View> drawable(@ColorInt final int color) {
         return new BoundedMatcher<View, ImageView>(ImageView.class) {
             private String failedComparisonDescription;
 
@@ -81,7 +82,7 @@
      * Returns a matcher that matches <code>View</code>s which have background flat-filled
      * with the specific color.
      */
-    public static Matcher isBackground(@ColorInt final int color) {
+    public static Matcher<View> isBackground(@ColorInt final int color) {
         return isBackground(color, false);
     }
 
@@ -89,7 +90,8 @@
      * Returns a matcher that matches <code>View</code>s which have background flat-filled
      * with the specific color.
      */
-    public static Matcher isBackground(@ColorInt final int color, final boolean onlyTestCenter) {
+    public static Matcher<View> isBackground(
+            @ColorInt final int color, final boolean onlyTestCenter) {
         return new BoundedMatcher<View, View>(View.class) {
             private String failedComparisonDescription;
 
@@ -132,7 +134,7 @@
      * Returns a matcher that matches <code>View</code>s whose combined background starting
      * from the view and up its ancestor chain matches the specified color.
      */
-    public static Matcher isCombinedBackground(@ColorInt final int color,
+    public static Matcher<View> isCombinedBackground(@ColorInt final int color,
             final boolean onlyTestCenterPixel) {
         return new BoundedMatcher<View, View>(View.class) {
             private String failedComparisonDescription;
@@ -173,7 +175,7 @@
     /**
      * Returns a matcher that matches <code>CheckedTextView</code>s which are in checked state.
      */
-    public static Matcher isCheckedTextView() {
+    public static Matcher<View> isCheckedTextView() {
         return new BoundedMatcher<View, CheckedTextView>(CheckedTextView.class) {
             private String failedDescription;
 
@@ -199,7 +201,7 @@
     /**
      * Returns a matcher that matches <code>CheckedTextView</code>s which are in checked state.
      */
-    public static Matcher isNonCheckedTextView() {
+    public static Matcher<View> isNonCheckedTextView() {
         return new BoundedMatcher<View, CheckedTextView>(CheckedTextView.class) {
             private String failedDescription;
 
@@ -245,7 +247,7 @@
     /**
      * Returns a matcher that matches Views which implement TintableBackgroundView.
      */
-    public static Matcher<View> isTintableBackgroundView() {
+    static Matcher<View> isTintableBackgroundView() {
         return new TypeSafeMatcher<View>() {
             @Override
             public void describeTo(Description description) {
@@ -388,7 +390,7 @@
      * Returns a matcher that matches <code>SwitchCompat</code>s whose thumb drawable is flat-filled
      * with the specific color.
      */
-    public static Matcher thumbColor(@ColorInt final int color) {
+    public static Matcher<SwitchCompat> thumbColor(@ColorInt final int color) {
         return new TypeSafeMatcher<SwitchCompat>() {
             private String mFailedComparisonDescription;
 
@@ -431,7 +433,7 @@
      * Returns a matcher that matches <code>SwitchCompat</code>s whose track drawable is flat-filled
      * with the specific color.
      */
-    public static Matcher trackColor(@ColorInt final int color) {
+    public static Matcher<SwitchCompat> trackColor(@ColorInt final int color) {
         return new TypeSafeMatcher<SwitchCompat>() {
             private String mFailedComparisonDescription;
 
@@ -469,4 +471,21 @@
             }
         };
     }
+
+    /**
+     * Wraps an extends-View matcher with a View matcher for compatibility with Espresso APIs.
+     */
+    public static Matcher<View> asViewMatcher(final Matcher<? extends View> matcher) {
+        return new BaseMatcher<View>() {
+            @Override
+            public void describeTo(Description description) {
+                matcher.describeTo(description);
+            }
+
+            @Override
+            public boolean matches(Object item) {
+                return matcher.matches(item);
+            }
+        };
+    }
 }
diff --git a/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatBaseAutoSizeTest.java b/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatBaseAutoSizeTest.java
index 5028d1c..46b2a1b 100644
--- a/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatBaseAutoSizeTest.java
+++ b/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatBaseAutoSizeTest.java
@@ -42,6 +42,7 @@
 import androidx.core.content.res.ResourcesCompat;
 import androidx.core.widget.AutoSizeableTextView;
 import androidx.core.widget.TextViewCompat;
+import androidx.test.filters.LargeTest;
 import androidx.test.filters.MediumTest;
 import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
@@ -189,7 +190,7 @@
     }
 
     @Test
-    @MediumTest
+    @LargeTest
     public void testAutoSizeCallers_setText() throws Throwable {
         final T autoSizeView = prepareAndRetrieveAutoSizeTestData(R.id.view_autosize_uniform,
                 false);
@@ -884,7 +885,7 @@
     }
 
     @Test(expected = NullPointerException.class)
-    @SmallTest
+    @MediumTest
     public void testAutoSizeUniform_predefinedSizesNullArray() throws Throwable {
         final T view = mActivity.findViewById(R.id.view_text);
         assertEquals(TextViewCompat.AUTO_SIZE_TEXT_TYPE_NONE,
diff --git a/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatBaseViewTest.java b/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatBaseViewTest.java
index aa8b0e6..2137144 100644
--- a/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatBaseViewTest.java
+++ b/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatBaseViewTest.java
@@ -44,6 +44,7 @@
 import androidx.appcompat.testutils.TestUtils;
 import androidx.core.content.res.ResourcesCompat;
 import androidx.core.graphics.ColorUtils;
+import androidx.test.espresso.UiController;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
 import androidx.test.rule.ActivityTestRule;
@@ -68,10 +69,11 @@
     protected ViewGroup mContainer;
 
     protected A mActivity;
+    protected UiController mUiController;
     protected Resources mResources;
 
     public AppCompatBaseViewTest(Class<A> clazz) {
-        mActivityTestRule = new ActivityTestRule<A>(clazz);
+        mActivityTestRule = new ActivityTestRule<>(clazz);
     }
 
     @Before
diff --git a/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatSpinnerTest.java b/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatSpinnerTest.java
index 6f76b24b..c5fc808 100644
--- a/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatSpinnerTest.java
+++ b/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatSpinnerTest.java
@@ -15,6 +15,8 @@
  */
 package androidx.appcompat.widget;
 
+import static androidx.appcompat.testutils.TestUtilsActions.setScreenOrientation;
+import static androidx.appcompat.testutils.TestUtilsMatchers.asViewMatcher;
 import static androidx.appcompat.testutils.TestUtilsMatchers.hasChild;
 import static androidx.appcompat.testutils.TestUtilsMatchers.isCombinedBackground;
 import static androidx.test.espresso.Espresso.onView;
@@ -23,6 +25,7 @@
 import static androidx.test.espresso.assertion.ViewAssertions.matches;
 import static androidx.test.espresso.matcher.RootMatchers.isPlatformPopup;
 import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
 import static androidx.test.espresso.matcher.ViewMatchers.withId;
 import static androidx.test.espresso.matcher.ViewMatchers.withText;
 
@@ -37,8 +40,8 @@
 import android.content.pm.ActivityInfo;
 import android.content.res.Resources;
 import android.os.Build;
-import android.os.SystemClock;
 import android.view.View;
+import android.view.ViewGroup;
 
 import androidx.annotation.ColorInt;
 import androidx.annotation.ColorRes;
@@ -63,7 +66,6 @@
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
 import org.hamcrest.TypeSafeMatcher;
-import org.junit.After;
 import org.junit.Test;
 
 /**
@@ -90,12 +92,6 @@
     public void setUp() {
         super.setUp();
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
-        setOrientation(true);
-    }
-
-    @After
-    public void cleanUp() {
-        setOrientation(true);
     }
 
     /**
@@ -103,11 +99,11 @@
      * is themed with the specified color.
      */
     private void verifySpinnerPopupTheming(@IdRes int spinnerId,
-            @ColorRes int expectedPopupColorResId, boolean matchDropDownListView) {
+            @ColorRes int expectedPopupColorResId) {
         final Resources res = mActivityTestRule.getActivity().getResources();
         final @ColorInt int expectedPopupColor =
                 ResourcesCompat.getColor(res, expectedPopupColorResId, null);
-        final AppCompatSpinner spinner = (AppCompatSpinner) mContainer.findViewById(spinnerId);
+        final AppCompatSpinner spinner = mContainer.findViewById(spinnerId);
 
         // Click the spinner to show its popup content
         onView(withId(spinnerId)).perform(click());
@@ -125,11 +121,11 @@
         // internal implementation details on which exact "chrome" part of the popup has the
         // matching background.
         String itemText = (String) spinner.getAdapter().getItem(2);
-        Matcher popupContentMatcher = hasChild(withText(itemText));
+        Matcher<ViewGroup> popupContentMatcher = hasChild(withText(itemText));
         // Note that we are only testing the center pixel of the combined popup background. This
         // is to "eliminate" otherwise hacky code that would need to skip over rounded corners and
         // drop shadow of the combined visual appearance of a popup.
-        onView(popupContentMatcher).inRoot(isPlatformPopup()).check(
+        onView(asViewMatcher(popupContentMatcher)).inRoot(isPlatformPopup()).check(
                 matches(isCombinedBackground(expectedPopupColor, true)));
 
         // Click an entry in the popup to dismiss it
@@ -141,36 +137,37 @@
 
     @Test
     public void testPopupThemingFromXmlAttribute() {
-        verifySpinnerPopupTheming(R.id.view_magenta_themed_popup, R.color.test_magenta, true);
+        verifySpinnerPopupTheming(R.id.view_magenta_themed_popup, R.color.test_magenta);
     }
 
     @Test
     public void testUnthemedPopupRuntimeTheming() {
         final AppCompatSpinner spinner =
-                (AppCompatSpinner) mContainer.findViewById(R.id.view_unthemed_popup);
+                mContainer.findViewById(R.id.view_unthemed_popup);
         spinner.setPopupBackgroundResource(R.drawable.test_background_blue);
-        verifySpinnerPopupTheming(R.id.view_unthemed_popup, R.color.test_blue, false);
+        verifySpinnerPopupTheming(R.id.view_unthemed_popup, R.color.test_blue);
 
         // Set a different popup background
         spinner.setPopupBackgroundDrawable(ContextCompat.getDrawable(
                 mActivityTestRule.getActivity(), R.drawable.test_background_green));
-        verifySpinnerPopupTheming(R.id.view_unthemed_popup, R.color.test_green, false);
+        verifySpinnerPopupTheming(R.id.view_unthemed_popup, R.color.test_green);
     }
 
     @Test
+    @FlakyTest
     public void testThemedPopupRuntimeTheming() {
         final AppCompatSpinner spinner =
-                (AppCompatSpinner) mContainer.findViewById(R.id.view_ocean_themed_popup);
-        verifySpinnerPopupTheming(R.id.view_ocean_themed_popup, R.color.ocean_default, true);
+                mContainer.findViewById(R.id.view_ocean_themed_popup);
+        verifySpinnerPopupTheming(R.id.view_ocean_themed_popup, R.color.ocean_default);
 
         // Now set a different popup background
         spinner.setPopupBackgroundResource(R.drawable.test_background_red);
-        verifySpinnerPopupTheming(R.id.view_ocean_themed_popup, R.color.test_red, false);
+        verifySpinnerPopupTheming(R.id.view_ocean_themed_popup, R.color.test_red);
 
         // Set a different popup background
         spinner.setPopupBackgroundDrawable(ContextCompat.getDrawable(
                 mActivityTestRule.getActivity(), R.drawable.test_background_blue));
-        verifySpinnerPopupTheming(R.id.view_ocean_themed_popup, R.color.test_blue, false);
+        verifySpinnerPopupTheming(R.id.view_ocean_themed_popup, R.color.test_blue);
     }
 
     @MediumTest
@@ -191,15 +188,15 @@
 
     @Test
     public void testChangeOrientationDialogPopupPersists() {
-        verifyChangeOrientationPopupPersists(R.id.spinner_dialog_popup, true);
+        verifyChangeOrientationPopupPersists(R.id.spinner_dialog_popup);
     }
 
     @Test
     public void testChangeOrientationDropdownPopupPersists() {
-        verifyChangeOrientationPopupPersists(R.id.spinner_dropdown_popup, false);
+        verifyChangeOrientationPopupPersists(R.id.spinner_dropdown_popup);
     }
 
-    private void verifyChangeOrientationPopupPersists(@IdRes int spinnerId, boolean isDialog) {
+    private void verifyChangeOrientationPopupPersists(@IdRes int spinnerId) {
         onView(withId(spinnerId)).perform(click());
         // Wait until the popup is showing
         waitUntilPopupIsShown((AppCompatSpinner) mActivity.findViewById(spinnerId));
@@ -210,11 +207,11 @@
                 new Instrumentation.ActivityMonitor(mActivity.getClass().getName(), null, false);
         mInstrumentation.addMonitor(monitor);
 
-        mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
-        SystemClock.sleep(250);
+        onView(isRoot()).perform(
+                setScreenOrientation(mActivity, ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE));
 
-        mInstrumentation.waitForIdleSync();
         mActivity = (AppCompatSpinnerActivity) mInstrumentation.waitForMonitor(monitor);
+        mInstrumentation.waitForIdleSync();
 
         // Now we can get the new (post-rotation) instance of our spinner
         AppCompatSpinner newSpinner = mActivity.findViewById(spinnerId);
@@ -245,6 +242,7 @@
     }
 
     @Test
+    @FlakyTest
     public void testHorizontalOffset() {
         checkOffsetIsCorrect(500, false, false);
     }
@@ -425,18 +423,4 @@
         mContainer = mActivity.findViewById(R.id.container);
         mResources = mActivity.getResources();
     }
-
-    private void setOrientation(final boolean toPortrait) {
-        final int desiredOrientation = toPortrait
-                ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
-                : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
-
-        if (mActivity.getRequestedOrientation() != desiredOrientation) {
-            mActivity.setRequestedOrientation(desiredOrientation);
-            SystemClock.sleep(250);
-            mActivity = mActivityTestRule.getActivity();
-            mContainer = mActivity.findViewById(R.id.container);
-            mResources = mActivity.getResources();
-        }
-    }
 }
diff --git a/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatTextViewAutoSizeTest.java b/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatTextViewAutoSizeTest.java
index 75c2b92..caf0354 100644
--- a/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatTextViewAutoSizeTest.java
+++ b/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatTextViewAutoSizeTest.java
@@ -32,6 +32,7 @@
 import androidx.appcompat.test.R;
 import androidx.core.widget.TextViewCompat;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.MediumTest;
 import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
@@ -54,6 +55,7 @@
         return new AppCompatTextView(mActivity);
     }
 
+    @MediumTest
     @Test
     public void testAutoSize_notSupportedByEditText() throws Throwable {
         final AppCompatEditText autoSizeEditText = mActivity.findViewById(
diff --git a/appcompat/src/androidTest/java/androidx/appcompat/widget/SearchView_CursorTest.java b/appcompat/src/androidTest/java/androidx/appcompat/widget/SearchView_CursorTest.java
index b043a07..69365b0 100644
--- a/appcompat/src/androidTest/java/androidx/appcompat/widget/SearchView_CursorTest.java
+++ b/appcompat/src/androidTest/java/androidx/appcompat/widget/SearchView_CursorTest.java
@@ -42,6 +42,7 @@
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
+import androidx.test.filters.SdkSuppress;
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.rule.ActivityTestRule;
 import androidx.testutils.PollingCheck;
@@ -168,6 +169,9 @@
         verify(mockQueryTextListener, times(1)).onQueryTextChange("Di");
     }
 
+    // ViewTreeObserver.OnDrawListener (used for waiting for the redraw pass on
+    // emulating a tap) is only available on 16+
+    @SdkSuppress(minSdkVersion = 16)
     @Test
     public void testSuggestionSelection() throws Throwable {
         final SearchView.OnSuggestionListener mockSuggestionListener =
diff --git a/appcompat/src/androidTest/java/androidx/appcompat/widget/SwitchCompatTest.java b/appcompat/src/androidTest/java/androidx/appcompat/widget/SwitchCompatTest.java
index 2119a2a..35a1bb5 100644
--- a/appcompat/src/androidTest/java/androidx/appcompat/widget/SwitchCompatTest.java
+++ b/appcompat/src/androidTest/java/androidx/appcompat/widget/SwitchCompatTest.java
@@ -16,6 +16,7 @@
 
 package androidx.appcompat.widget;
 
+import static androidx.appcompat.testutils.TestUtilsMatchers.asViewMatcher;
 import static androidx.appcompat.testutils.TestUtilsMatchers.thumbColor;
 import static androidx.appcompat.testutils.TestUtilsMatchers.trackColor;
 import static androidx.test.espresso.Espresso.onView;
@@ -47,7 +48,7 @@
 
     @Rule
     public final ActivityTestRule<SwitchCompatActivity> mActivityTestRule =
-            new ActivityTestRule(SwitchCompatActivity.class);
+            new ActivityTestRule<>(SwitchCompatActivity.class);
     private SwitchCompatActivity mActivity;
     private ViewGroup mContainer;
 
@@ -72,7 +73,9 @@
         final int expectedTrackTint = 0xff00ffff;
 
         // Then the tints should be applied
-        onView(withId(R.id.switch_tint)).check(matches(thumbColor(expectedThumbTint)));
-        onView(withId(R.id.switch_tint)).check(matches(trackColor(expectedTrackTint)));
+        onView(withId(R.id.switch_tint))
+                .check(matches(asViewMatcher(thumbColor(expectedThumbTint))));
+        onView(withId(R.id.switch_tint))
+                .check(matches(asViewMatcher(trackColor(expectedTrackTint))));
     }
 }
diff --git a/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java b/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
index fd10f53..c33e630 100644
--- a/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
+++ b/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
@@ -1376,10 +1376,9 @@
             TypedArray a = mContext.obtainStyledAttributes(R.styleable.AppCompatTheme);
             String viewInflaterClassName =
                     a.getString(R.styleable.AppCompatTheme_viewInflaterClass);
-            if ((viewInflaterClassName == null)
-                    || AppCompatViewInflater.class.getName().equals(viewInflaterClassName)) {
-                // Either default class name or set explicitly to null. In both cases
-                // create the base inflater (no reflection)
+            if (viewInflaterClassName == null) {
+                // Set to null (the default in all AppCompat themes). Create the base inflater
+                // (no reflection)
                 mAppCompatViewInflater = new AppCompatViewInflater();
             } else {
                 try {
@@ -2289,7 +2288,7 @@
                 // just have to try it and catch the exception. We only log if we're actually
                 // trying to apply a uiMode configuration though.
                 if (newNightMode != applicationNightMode) {
-                    Log.e(TAG, "updateForNightMode. Calling applyOverrideConfiguration() failed"
+                    Log.w(TAG, "updateForNightMode. Calling applyOverrideConfiguration() failed"
                             + " with an exception. Will fall back to using"
                             + " Resources.updateConfiguration()", e);
                 }
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatAutoCompleteTextView.java b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatAutoCompleteTextView.java
index b45dd08..1bc06a4 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatAutoCompleteTextView.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatAutoCompleteTextView.java
@@ -75,6 +75,8 @@
             @NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
 
+        ThemeUtils.checkAppCompatTheme(this, getContext());
+
         TintTypedArray a = TintTypedArray.obtainStyledAttributes(getContext(), attrs,
                 TINT_ATTRS, defStyleAttr, 0);
         if (a.hasValue(0)) {
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatButton.java b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatButton.java
index 202f867..0eda604 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatButton.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatButton.java
@@ -72,6 +72,8 @@
             @NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
 
+        ThemeUtils.checkAppCompatTheme(this, getContext());
+
         mBackgroundTintHelper = new AppCompatBackgroundHelper(this);
         mBackgroundTintHelper.loadFromAttributes(attrs, defStyleAttr);
 
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatCheckBox.java b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatCheckBox.java
index a544365..1a72501 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatCheckBox.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatCheckBox.java
@@ -69,6 +69,9 @@
     public AppCompatCheckBox(
             @NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
+
+        ThemeUtils.checkAppCompatTheme(this, getContext());
+
         mCompoundButtonHelper = new AppCompatCompoundButtonHelper(this);
         mCompoundButtonHelper.loadFromAttributes(attrs, defStyleAttr);
 
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatCheckedTextView.java b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatCheckedTextView.java
index 155d413a..60d71e1 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatCheckedTextView.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatCheckedTextView.java
@@ -57,6 +57,8 @@
             @NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
 
+        ThemeUtils.checkAppCompatTheme(this, getContext());
+
         mTextHelper = new AppCompatTextHelper(this);
         mTextHelper.loadFromAttributes(attrs, defStyleAttr);
         mTextHelper.applyCompoundDrawablesTints();
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatEditText.java b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatEditText.java
index 686ba3d..a6a64b3 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatEditText.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatEditText.java
@@ -73,6 +73,8 @@
             @NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
 
+        ThemeUtils.checkAppCompatTheme(this, getContext());
+
         mBackgroundTintHelper = new AppCompatBackgroundHelper(this);
         mBackgroundTintHelper.loadFromAttributes(attrs, defStyleAttr);
 
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageButton.java b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageButton.java
index bf825bd..de944c6 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageButton.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageButton.java
@@ -74,6 +74,8 @@
             @NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
 
+        ThemeUtils.checkAppCompatTheme(this, getContext());
+
         mBackgroundTintHelper = new AppCompatBackgroundHelper(this);
         mBackgroundTintHelper.loadFromAttributes(attrs, defStyleAttr);
 
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageView.java b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageView.java
index 82f0f7e..53ec8e4 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageView.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageView.java
@@ -73,6 +73,8 @@
             @NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
 
+        ThemeUtils.checkAppCompatTheme(this, getContext());
+
         mBackgroundTintHelper = new AppCompatBackgroundHelper(this);
         mBackgroundTintHelper.loadFromAttributes(attrs, defStyleAttr);
 
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatMultiAutoCompleteTextView.java b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatMultiAutoCompleteTextView.java
index 0a08c1b..123df21 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatMultiAutoCompleteTextView.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatMultiAutoCompleteTextView.java
@@ -73,6 +73,8 @@
             @NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
 
+        ThemeUtils.checkAppCompatTheme(this, getContext());
+
         TintTypedArray a = TintTypedArray.obtainStyledAttributes(getContext(), attrs,
                 TINT_ATTRS, defStyleAttr, 0);
         if (a.hasValue(0)) {
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatRadioButton.java b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatRadioButton.java
index e57bab5..056d8bd 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatRadioButton.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatRadioButton.java
@@ -67,6 +67,9 @@
 
     public AppCompatRadioButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
+
+        ThemeUtils.checkAppCompatTheme(this, getContext());
+
         mCompoundButtonHelper = new AppCompatCompoundButtonHelper(this);
         mCompoundButtonHelper.loadFromAttributes(attrs, defStyleAttr);
 
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatRatingBar.java b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatRatingBar.java
index 0a5afa5..242f61e 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatRatingBar.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatRatingBar.java
@@ -50,6 +50,8 @@
             @NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
 
+        ThemeUtils.checkAppCompatTheme(this, getContext());
+
         mAppCompatProgressBarHelper = new AppCompatProgressBarHelper(this);
         mAppCompatProgressBarHelper.loadFromAttributes(attrs, defStyleAttr);
     }
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatSeekBar.java b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatSeekBar.java
index bd362f6..70a8b0f 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatSeekBar.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatSeekBar.java
@@ -49,6 +49,8 @@
             @NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
 
+        ThemeUtils.checkAppCompatTheme(this, getContext());
+
         mAppCompatSeekBarHelper = new AppCompatSeekBarHelper(this);
         mAppCompatSeekBarHelper.loadFromAttributes(attrs, defStyleAttr);
     }
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatSpinner.java b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatSpinner.java
index 92e8aea..3ec7c21 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatSpinner.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatSpinner.java
@@ -208,6 +208,8 @@
             int defStyleAttr, int mode, Resources.Theme popupTheme) {
         super(context, attrs, defStyleAttr);
 
+        ThemeUtils.checkAppCompatTheme(this, getContext());
+
         TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, attrs,
                 R.styleable.Spinner, defStyleAttr, 0);
 
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextView.java b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextView.java
index 194d121..c1728b2 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextView.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextView.java
@@ -99,6 +99,8 @@
             @NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
 
+        ThemeUtils.checkAppCompatTheme(this, getContext());
+
         mBackgroundTintHelper = new AppCompatBackgroundHelper(this);
         mBackgroundTintHelper.loadFromAttributes(attrs, defStyleAttr);
 
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatToggleButton.java b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatToggleButton.java
index da2e649..a98012b2 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/AppCompatToggleButton.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/AppCompatToggleButton.java
@@ -49,6 +49,8 @@
             @NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
 
+        ThemeUtils.checkAppCompatTheme(this, getContext());
+
         mTextHelper = new AppCompatTextHelper(this);
         mTextHelper.loadFromAttributes(attrs, defStyleAttr);
     }
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/SearchView.java b/appcompat/src/main/java/androidx/appcompat/widget/SearchView.java
index e1fc231..c89fc17 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/SearchView.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/SearchView.java
@@ -16,9 +16,12 @@
 
 package androidx.appcompat.widget;
 
+import static android.widget.ListPopupWindow.INPUT_METHOD_NEEDED;
+
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
 import static androidx.appcompat.widget.SuggestionsAdapter.getColumnString;
 
+import android.annotation.SuppressLint;
 import android.app.PendingIntent;
 import android.app.SearchManager;
 import android.app.SearchableInfo;
@@ -174,7 +177,8 @@
     SearchableInfo mSearchable;
     private Bundle mAppSearchData;
 
-    static final AutoCompleteTextViewReflector HIDDEN_METHOD_INVOKER = new AutoCompleteTextViewReflector();
+    static final PreQAutoCompleteTextViewReflector PRE_API_29_HIDDEN_METHOD_INVOKER =
+            (Build.VERSION.SDK_INT < 29) ? new PreQAutoCompleteTextViewReflector() : null;
 
     private final Runnable mUpdateDrawableStateRunnable = new Runnable() {
         @Override
@@ -1068,7 +1072,7 @@
                 mSearchSrcTextView.setSelection(selPoint);
                 mSearchSrcTextView.setListSelection(0);
                 mSearchSrcTextView.clearListSelection();
-                HIDDEN_METHOD_INVOKER.ensureImeVisible(mSearchSrcTextView, true);
+                mSearchSrcTextView.ensureImeVisible();
 
                 return true;
             }
@@ -1698,8 +1702,8 @@
         if (Build.VERSION.SDK_INT >= 29) {
             mSearchSrcTextView.refreshAutoCompleteResults();
         } else {
-            HIDDEN_METHOD_INVOKER.doBeforeTextChanged(mSearchSrcTextView);
-            HIDDEN_METHOD_INVOKER.doAfterTextChanged(mSearchSrcTextView);
+            PRE_API_29_HIDDEN_METHOD_INVOKER.doBeforeTextChanged(mSearchSrcTextView);
+            PRE_API_29_HIDDEN_METHOD_INVOKER.doAfterTextChanged(mSearchSrcTextView);
         }
     }
 
@@ -1912,7 +1916,7 @@
 
                 // If in landscape mode, then make sure that the ime is in front of the dropdown.
                 if (isLandscapeMode(getContext())) {
-                    HIDDEN_METHOD_INVOKER.ensureImeVisible(this, true);
+                    ensureImeVisible();
                 }
             }
         }
@@ -2021,61 +2025,87 @@
             // onCreateInputConnection().
             mHasPendingShowSoftInputRequest = true;
         }
+
+        void ensureImeVisible() {
+            if (Build.VERSION.SDK_INT >= 29) {
+                setInputMethodMode(INPUT_METHOD_NEEDED);
+                if (enoughToFilter()) {
+                    showDropDown();
+                }
+            } else {
+                PRE_API_29_HIDDEN_METHOD_INVOKER.ensureImeVisible(this);
+            }
+        }
     }
 
-    private static class AutoCompleteTextViewReflector {
-        private Method doBeforeTextChanged, doAfterTextChanged;
-        private Method ensureImeVisible;
+    private static class PreQAutoCompleteTextViewReflector {
+        private Method mDoBeforeTextChanged = null;
+        private Method mDoAfterTextChanged = null;
+        private Method mEnsureImeVisible = null;
 
-        AutoCompleteTextViewReflector() {
+
+        @SuppressWarnings("JavaReflectionMemberAccess")
+        @SuppressLint("DiscouragedPrivateApi")
+        PreQAutoCompleteTextViewReflector() {
+            preApi29Check();
             try {
-                doBeforeTextChanged = AutoCompleteTextView.class
+                mDoBeforeTextChanged = AutoCompleteTextView.class
                         .getDeclaredMethod("doBeforeTextChanged");
-                doBeforeTextChanged.setAccessible(true);
+                mDoBeforeTextChanged.setAccessible(true);
             } catch (NoSuchMethodException e) {
                 // Ah well.
             }
             try {
-                doAfterTextChanged = AutoCompleteTextView.class
+                mDoAfterTextChanged = AutoCompleteTextView.class
                         .getDeclaredMethod("doAfterTextChanged");
-                doAfterTextChanged.setAccessible(true);
+                mDoAfterTextChanged.setAccessible(true);
             } catch (NoSuchMethodException e) {
                 // Ah well.
             }
             try {
-                ensureImeVisible = AutoCompleteTextView.class
+                mEnsureImeVisible = AutoCompleteTextView.class
                         .getMethod("ensureImeVisible", boolean.class);
-                ensureImeVisible.setAccessible(true);
+                mEnsureImeVisible.setAccessible(true);
             } catch (NoSuchMethodException e) {
                 // Ah well.
             }
         }
 
         void doBeforeTextChanged(AutoCompleteTextView view) {
-            if (doBeforeTextChanged != null) {
+            preApi29Check();
+            if (mDoBeforeTextChanged != null) {
                 try {
-                    doBeforeTextChanged.invoke(view);
+                    mDoBeforeTextChanged.invoke(view);
                 } catch (Exception e) {
                 }
             }
         }
 
         void doAfterTextChanged(AutoCompleteTextView view) {
-            if (doAfterTextChanged != null) {
+            preApi29Check();
+            if (mDoAfterTextChanged != null) {
                 try {
-                    doAfterTextChanged.invoke(view);
+                    mDoAfterTextChanged.invoke(view);
                 } catch (Exception e) {
                 }
             }
         }
 
-        void ensureImeVisible(AutoCompleteTextView view, boolean visible) {
-            if (ensureImeVisible != null) {
+        void ensureImeVisible(AutoCompleteTextView view) {
+            preApi29Check();
+            if (mEnsureImeVisible != null) {
                 try {
-                    ensureImeVisible.invoke(view, visible);
+                    mEnsureImeVisible.invoke(view, /* visible = */ true);
                 } catch (Exception e) {
                 }
             }
         }
+
+        private static void preApi29Check() {
+            if (Build.VERSION.SDK_INT >= 29) {
+                throw new UnsupportedClassVersionError(
+                        "This function can only be used for API Level < 29.");
+            }
+        }
     }
 }
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/SwitchCompat.java b/appcompat/src/main/java/androidx/appcompat/widget/SwitchCompat.java
index fd237f0..ec30a58 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/SwitchCompat.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/SwitchCompat.java
@@ -219,6 +219,8 @@
     public SwitchCompat(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
 
+        ThemeUtils.checkAppCompatTheme(this, getContext());
+
         mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
 
         final Resources res = getResources();
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/ThemeUtils.java b/appcompat/src/main/java/androidx/appcompat/widget/ThemeUtils.java
index ee00ded..d114519 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/ThemeUtils.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/ThemeUtils.java
@@ -16,14 +16,26 @@
 
 package androidx.appcompat.widget;
 
+import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+
 import android.content.Context;
 import android.content.res.ColorStateList;
+import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.util.TypedValue;
+import android.view.View;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.appcompat.R;
 import androidx.core.graphics.ColorUtils;
 
-class ThemeUtils {
+/**
+ * @hide
+ */
+@RestrictTo(LIBRARY)
+public class ThemeUtils {
 
     private static final ThreadLocal<TypedValue> TL_TYPED_VALUE = new ThreadLocal<>();
 
@@ -39,6 +51,14 @@
 
     private static final int[] TEMP_ARRAY = new int[1];
 
+    /**
+     * Creates a color state list from the provided colors.
+     *
+     * @param textColor Regular text color.
+     * @param disabledTextColor Disabled text color.
+     * @return Color state list.
+     */
+    @NonNull
     public static ColorStateList createDisabledStateList(int textColor, int disabledTextColor) {
         // Now create a new ColorStateList with the default color, and the new disabled
         // color
@@ -59,7 +79,14 @@
         return new ColorStateList(states, colors);
     }
 
-    public static int getThemeAttrColor(Context context, int attr) {
+    /**
+     * Resolves the color from the provided theme attribute.
+     *
+     * @param context Context. Must be non-null.
+     * @param attr Theme attribute for resolving color.
+     * @return Resolved color.
+     */
+    public static int getThemeAttrColor(@NonNull Context context, int attr) {
         TEMP_ARRAY[0] = attr;
         TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, null, TEMP_ARRAY);
         try {
@@ -69,7 +96,15 @@
         }
     }
 
-    public static ColorStateList getThemeAttrColorStateList(Context context, int attr) {
+    /**
+     * Resolves the color state list from the provided theme attribute.
+     *
+     * @param context Context. Must be non-null.
+     * @param attr Theme attribute for resolving color state list.
+     * @return Resolved color state list.
+     */
+    @Nullable
+    public static ColorStateList getThemeAttrColorStateList(@NonNull Context context, int attr) {
         TEMP_ARRAY[0] = attr;
         TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, null, TEMP_ARRAY);
         try {
@@ -79,7 +114,14 @@
         }
     }
 
-    public static int getDisabledThemeAttrColor(Context context, int attr) {
+    /**
+     * Resolves the disabled color from the provided theme attribute.
+     *
+     * @param context Context. Must be non-null.
+     * @param attr Theme attribute for resolving disabled color.
+     * @return Resolved disabled color.
+     */
+    public static int getDisabledThemeAttrColor(@NonNull Context context, int attr) {
         final ColorStateList csl = getThemeAttrColorStateList(context, attr);
         if (csl != null && csl.isStateful()) {
             // If the CSL is stateful, we'll assume it has a disabled state and use it
@@ -105,12 +147,32 @@
         return typedValue;
     }
 
-    static int getThemeAttrColor(Context context, int attr, float alpha) {
+    static int getThemeAttrColor(@NonNull Context context, int attr, float alpha) {
         final int color = getThemeAttrColor(context, attr);
         final int originalAlpha = Color.alpha(color);
         return ColorUtils.setAlphaComponent(color, Math.round(originalAlpha * alpha));
     }
 
+    /**
+     * Checks that the specific view (which should be an AppCompat widget) is
+     * using a {@link Context} that is an AppCompat theme or its descendant.
+     */
+    public static void checkAppCompatTheme(@NonNull View view, @NonNull Context context) {
+        TypedArray a = context.obtainStyledAttributes(R.styleable.AppCompatTheme);
+
+        try {
+            // Same check as in AppCompatDelegateImpl - do not allow using AppCompat widgets
+            // without a top-level AppCompat theme (or its descendant).
+            if (!a.hasValue(R.styleable.AppCompatTheme_windowActionBar)) {
+                throw new IllegalStateException("View " + view.getClass()
+                        + " is an AppCompat widget that can only be used with a "
+                        + "Theme.AppCompat theme (or descendant).");
+            }
+        } finally {
+            a.recycle();
+        }
+    }
+
     private ThemeUtils() {
     }
 }
diff --git a/arch/core-testing/api/api_lint.ignore b/arch/core-testing/api/api_lint.ignore
new file mode 100644
index 0000000..976d03d
--- /dev/null
+++ b/arch/core-testing/api/api_lint.ignore
@@ -0,0 +1,11 @@
+// Baseline format: 1.0
+MissingNullability: androidx.arch.core.executor.testing.CountingTaskExecutorRule#drainTasks(int, java.util.concurrent.TimeUnit) parameter #1:
+    Missing nullability on parameter `timeUnit` in method `drainTasks`
+MissingNullability: androidx.arch.core.executor.testing.CountingTaskExecutorRule#finished(org.junit.runner.Description) parameter #0:
+    Missing nullability on parameter `description` in method `finished`
+MissingNullability: androidx.arch.core.executor.testing.CountingTaskExecutorRule#starting(org.junit.runner.Description) parameter #0:
+    Missing nullability on parameter `description` in method `starting`
+MissingNullability: androidx.arch.core.executor.testing.InstantTaskExecutorRule#finished(org.junit.runner.Description) parameter #0:
+    Missing nullability on parameter `description` in method `finished`
+MissingNullability: androidx.arch.core.executor.testing.InstantTaskExecutorRule#starting(org.junit.runner.Description) parameter #0:
+    Missing nullability on parameter `description` in method `starting`
diff --git a/autofill/api/1.0.0-alpha03.txt b/autofill/api/1.0.0-alpha03.txt
new file mode 100644
index 0000000..a56ee53
--- /dev/null
+++ b/autofill/api/1.0.0-alpha03.txt
@@ -0,0 +1,54 @@
+// Signature format: 3.0
+package androidx.autofill {
+
+  public final class HintConstants {
+    field public static final String AUTOFILL_HINT_BIRTH_DATE_DAY = "birthDateDay";
+    field public static final String AUTOFILL_HINT_BIRTH_DATE_FULL = "birthDateFull";
+    field public static final String AUTOFILL_HINT_BIRTH_DATE_MONTH = "birthDateMonth";
+    field public static final String AUTOFILL_HINT_BIRTH_DATE_YEAR = "birthDateYear";
+    field public static final String AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE = "creditCardExpirationDate";
+    field public static final String AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY = "creditCardExpirationDay";
+    field public static final String AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH = "creditCardExpirationMonth";
+    field public static final String AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR = "creditCardExpirationYear";
+    field public static final String AUTOFILL_HINT_CREDIT_CARD_NUMBER = "creditCardNumber";
+    field public static final String AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE = "creditCardSecurityCode";
+    field public static final String AUTOFILL_HINT_EMAIL_ADDRESS = "emailAddress";
+    field public static final String AUTOFILL_HINT_GENDER = "gender";
+    field @Deprecated public static final String AUTOFILL_HINT_NAME = "name";
+    field public static final String AUTOFILL_HINT_NEW_PASSWORD = "newPassword";
+    field public static final String AUTOFILL_HINT_NEW_USERNAME = "newUsername";
+    field public static final String AUTOFILL_HINT_PASSWORD = "password";
+    field public static final String AUTOFILL_HINT_PERSON_NAME = "personName";
+    field public static final String AUTOFILL_HINT_PERSON_NAME_FAMILY = "personFamilyName";
+    field public static final String AUTOFILL_HINT_PERSON_NAME_GIVEN = "personGivenName";
+    field public static final String AUTOFILL_HINT_PERSON_NAME_MIDDLE = "personMiddleName";
+    field public static final String AUTOFILL_HINT_PERSON_NAME_MIDDLE_INITIAL = "personMiddleInitial";
+    field public static final String AUTOFILL_HINT_PERSON_NAME_PREFIX = "personNamePrefix";
+    field public static final String AUTOFILL_HINT_PERSON_NAME_SUFFIX = "personNameSuffix";
+    field @Deprecated public static final String AUTOFILL_HINT_PHONE = "phone";
+    field public static final String AUTOFILL_HINT_PHONE_COUNTRY_CODE = "phoneCountryCode";
+    field public static final String AUTOFILL_HINT_PHONE_NATIONAL = "phoneNational";
+    field public static final String AUTOFILL_HINT_PHONE_NUMBER = "phoneNumber";
+    field public static final String AUTOFILL_HINT_PHONE_NUMBER_DEVICE = "phoneNumberDevice";
+    field public static final String AUTOFILL_HINT_POSTAL_ADDRESS = "postalAddress";
+    field public static final String AUTOFILL_HINT_POSTAL_ADDRESS_COUNTRY = "addressCountry";
+    field public static final String AUTOFILL_HINT_POSTAL_ADDRESS_EXTENDED_ADDRESS = "extendedAddress";
+    field public static final String AUTOFILL_HINT_POSTAL_ADDRESS_EXTENDED_POSTAL_CODE = "extendedPostalCode";
+    field public static final String AUTOFILL_HINT_POSTAL_ADDRESS_LOCALITY = "addressLocality";
+    field public static final String AUTOFILL_HINT_POSTAL_ADDRESS_REGION = "addressRegion";
+    field public static final String AUTOFILL_HINT_POSTAL_ADDRESS_STREET_ADDRESS = "streetAddress";
+    field public static final String AUTOFILL_HINT_POSTAL_CODE = "postalCode";
+    field public static final String AUTOFILL_HINT_SMS_OTP = "smsOTPCode";
+    field public static final String AUTOFILL_HINT_SMS_OTP_1 = "smsOTPCode1";
+    field public static final String AUTOFILL_HINT_SMS_OTP_2 = "smsOTPCode2";
+    field public static final String AUTOFILL_HINT_SMS_OTP_3 = "smsOTPCode3";
+    field public static final String AUTOFILL_HINT_SMS_OTP_4 = "smsOTPCode4";
+    field public static final String AUTOFILL_HINT_SMS_OTP_5 = "smsOTPCode5";
+    field public static final String AUTOFILL_HINT_SMS_OTP_6 = "smsOTPCode6";
+    field public static final String AUTOFILL_HINT_SMS_OTP_7 = "smsOTPCode7";
+    field public static final String AUTOFILL_HINT_SMS_OTP_8 = "smsOTPCode8";
+    field public static final String AUTOFILL_HINT_USERNAME = "username";
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha03.txt b/autofill/api/res-1.0.0-alpha03.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha03.txt
copy to autofill/api/res-1.0.0-alpha03.txt
diff --git a/autofill/api/restricted_1.0.0-alpha03.txt b/autofill/api/restricted_1.0.0-alpha03.txt
new file mode 100644
index 0000000..a56ee53
--- /dev/null
+++ b/autofill/api/restricted_1.0.0-alpha03.txt
@@ -0,0 +1,54 @@
+// Signature format: 3.0
+package androidx.autofill {
+
+  public final class HintConstants {
+    field public static final String AUTOFILL_HINT_BIRTH_DATE_DAY = "birthDateDay";
+    field public static final String AUTOFILL_HINT_BIRTH_DATE_FULL = "birthDateFull";
+    field public static final String AUTOFILL_HINT_BIRTH_DATE_MONTH = "birthDateMonth";
+    field public static final String AUTOFILL_HINT_BIRTH_DATE_YEAR = "birthDateYear";
+    field public static final String AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE = "creditCardExpirationDate";
+    field public static final String AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY = "creditCardExpirationDay";
+    field public static final String AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH = "creditCardExpirationMonth";
+    field public static final String AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR = "creditCardExpirationYear";
+    field public static final String AUTOFILL_HINT_CREDIT_CARD_NUMBER = "creditCardNumber";
+    field public static final String AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE = "creditCardSecurityCode";
+    field public static final String AUTOFILL_HINT_EMAIL_ADDRESS = "emailAddress";
+    field public static final String AUTOFILL_HINT_GENDER = "gender";
+    field @Deprecated public static final String AUTOFILL_HINT_NAME = "name";
+    field public static final String AUTOFILL_HINT_NEW_PASSWORD = "newPassword";
+    field public static final String AUTOFILL_HINT_NEW_USERNAME = "newUsername";
+    field public static final String AUTOFILL_HINT_PASSWORD = "password";
+    field public static final String AUTOFILL_HINT_PERSON_NAME = "personName";
+    field public static final String AUTOFILL_HINT_PERSON_NAME_FAMILY = "personFamilyName";
+    field public static final String AUTOFILL_HINT_PERSON_NAME_GIVEN = "personGivenName";
+    field public static final String AUTOFILL_HINT_PERSON_NAME_MIDDLE = "personMiddleName";
+    field public static final String AUTOFILL_HINT_PERSON_NAME_MIDDLE_INITIAL = "personMiddleInitial";
+    field public static final String AUTOFILL_HINT_PERSON_NAME_PREFIX = "personNamePrefix";
+    field public static final String AUTOFILL_HINT_PERSON_NAME_SUFFIX = "personNameSuffix";
+    field @Deprecated public static final String AUTOFILL_HINT_PHONE = "phone";
+    field public static final String AUTOFILL_HINT_PHONE_COUNTRY_CODE = "phoneCountryCode";
+    field public static final String AUTOFILL_HINT_PHONE_NATIONAL = "phoneNational";
+    field public static final String AUTOFILL_HINT_PHONE_NUMBER = "phoneNumber";
+    field public static final String AUTOFILL_HINT_PHONE_NUMBER_DEVICE = "phoneNumberDevice";
+    field public static final String AUTOFILL_HINT_POSTAL_ADDRESS = "postalAddress";
+    field public static final String AUTOFILL_HINT_POSTAL_ADDRESS_COUNTRY = "addressCountry";
+    field public static final String AUTOFILL_HINT_POSTAL_ADDRESS_EXTENDED_ADDRESS = "extendedAddress";
+    field public static final String AUTOFILL_HINT_POSTAL_ADDRESS_EXTENDED_POSTAL_CODE = "extendedPostalCode";
+    field public static final String AUTOFILL_HINT_POSTAL_ADDRESS_LOCALITY = "addressLocality";
+    field public static final String AUTOFILL_HINT_POSTAL_ADDRESS_REGION = "addressRegion";
+    field public static final String AUTOFILL_HINT_POSTAL_ADDRESS_STREET_ADDRESS = "streetAddress";
+    field public static final String AUTOFILL_HINT_POSTAL_CODE = "postalCode";
+    field public static final String AUTOFILL_HINT_SMS_OTP = "smsOTPCode";
+    field public static final String AUTOFILL_HINT_SMS_OTP_1 = "smsOTPCode1";
+    field public static final String AUTOFILL_HINT_SMS_OTP_2 = "smsOTPCode2";
+    field public static final String AUTOFILL_HINT_SMS_OTP_3 = "smsOTPCode3";
+    field public static final String AUTOFILL_HINT_SMS_OTP_4 = "smsOTPCode4";
+    field public static final String AUTOFILL_HINT_SMS_OTP_5 = "smsOTPCode5";
+    field public static final String AUTOFILL_HINT_SMS_OTP_6 = "smsOTPCode6";
+    field public static final String AUTOFILL_HINT_SMS_OTP_7 = "smsOTPCode7";
+    field public static final String AUTOFILL_HINT_SMS_OTP_8 = "smsOTPCode8";
+    field public static final String AUTOFILL_HINT_USERNAME = "username";
+  }
+
+}
+
diff --git a/benchmark/common/src/main/java/androidx/benchmark/Arguments.kt b/benchmark/common/src/main/java/androidx/benchmark/Arguments.kt
index e6163bf..fb89659 100644
--- a/benchmark/common/src/main/java/androidx/benchmark/Arguments.kt
+++ b/benchmark/common/src/main/java/androidx/benchmark/Arguments.kt
@@ -32,15 +32,20 @@
     val additionalTestOutputDir: String?
     val outputEnable: Boolean
     val startupMode: Boolean
+    val dryRunMode: Boolean
     val suppressedErrors: Set<String>
 
     init {
         val prefix = "androidx.benchmark"
         val arguments = argumentSource ?: InstrumentationRegistry.getArguments()
 
-        startupMode = arguments.getString("$prefix.startupMode.enable")?.toBoolean() ?: false
+        dryRunMode = arguments.getString("$prefix.dryRunMode.enable")?.toBoolean() ?: false
 
-        outputEnable = arguments.getString("$prefix.output.enable")?.toBoolean() ?: false
+        startupMode = !dryRunMode &&
+                (arguments.getString("$prefix.startupMode.enable")?.toBoolean() ?: false)
+
+        outputEnable = !dryRunMode &&
+                (arguments.getString("$prefix.output.enable")?.toBoolean() ?: false)
 
         // Transform comma-delimited list into set of suppressed errors
         // E.g. "DEBUGGABLE, UNLOCKED" -> setOf("DEBUGGABLE", "UNLOCKED")
diff --git a/benchmark/common/src/main/java/androidx/benchmark/BenchmarkState.kt b/benchmark/common/src/main/java/androidx/benchmark/BenchmarkState.kt
index 7d55169..b59166e 100644
--- a/benchmark/common/src/main/java/androidx/benchmark/BenchmarkState.kt
+++ b/benchmark/common/src/main/java/androidx/benchmark/BenchmarkState.kt
@@ -34,8 +34,8 @@
 /**
  * Control object for benchmarking in the code in Java.
  *
- * Query a state object with [BenchmarkRule.getState], and use it to measure a block of Java with
- * [BenchmarkState.keepRunning]:
+ * Query a state object with [androidx.benchmark.junit4.BenchmarkRule.getState], and use it to
+ * measure a block of Java with [BenchmarkState.keepRunning]:
  * ```
  * @Rule
  * public BenchmarkRule benchmarkRule = new BenchmarkRule();
@@ -52,7 +52,7 @@
  * }
  * ```
  *
- * @see BenchmarkRule#getState()
+ * @see androidx.benchmark.junit4.BenchmarkRule#getState()
  */
 class BenchmarkState {
     /** @hide */
@@ -221,14 +221,7 @@
             Log.d(TAG, "Tracing to: " + f.absolutePath)
             Debug.startMethodTracingSampling(f.absolutePath, 16 * 1024 * 1024, 100)
         }
-        maxIterations = if (Arguments.startupMode) {
-            // never average multiple loops together in startupMode
-            1
-        } else {
-            val idealIterations =
-                (TARGET_TEST_DURATION_NS / warmupManager.estimatedIterationTime).toInt()
-            idealIterations.coerceIn(MIN_TEST_ITERATIONS, MAX_TEST_ITERATIONS)
-        }
+        maxIterations = OVERRIDE_ITERATIONS ?: computeIterationsFromWarmup()
         pausedDurationNs = 0
         iterationsRemaining = maxIterations
         repeatCount = 0
@@ -237,6 +230,12 @@
         startTimeNs = System.nanoTime()
     }
 
+    private fun computeIterationsFromWarmup(): Int {
+        val idealIterations =
+            (TARGET_TEST_DURATION_NS / warmupManager.estimatedIterationTime).toInt()
+        return idealIterations.coerceIn(MIN_TEST_ITERATIONS, MAX_TEST_ITERATIONS)
+    }
+
     private fun startNextTestRun(): Boolean {
         val currentTime = System.nanoTime()
 
@@ -272,7 +271,7 @@
     /**
      * Inline fast-path function for inner benchmark loop.
      *
-     * Kotlin users should use [BenchmarkRule.measureRepeated]
+     * Kotlin users should use `BenchmarkRule.measureRepeated`
      *
      * This codepath uses exclusively @JvmField/const members, so there are no method calls at all
      * in the inlined loop. On recent Android Platform versions, ART inlines these accessors anyway,
@@ -334,7 +333,7 @@
                     ThrottleDetector.computeThrottleBaseline()
                 }
 
-                if (Arguments.startupMode) {
+                if (Arguments.dryRunMode || Arguments.startupMode) {
                     beginBenchmark()
                 } else {
                     beginWarmup()
@@ -474,7 +473,15 @@
 
         // Values determined empirically.
         @VisibleForTesting
-        internal val REPEAT_COUNT = if (Arguments.startupMode) 10 else 50
+        internal val REPEAT_COUNT = when {
+            Arguments.dryRunMode -> 1
+            Arguments.startupMode -> 10
+            else -> 50
+        }
+        private val OVERRIDE_ITERATIONS = when {
+            Arguments.dryRunMode || Arguments.startupMode -> 1
+            else -> null
+        }
         private val TARGET_TEST_DURATION_NS = TimeUnit.MICROSECONDS.toNanos(500)
         private const val MAX_TEST_ITERATIONS = 1000000
         private const val MIN_TEST_ITERATIONS = 1
@@ -485,7 +492,8 @@
         private var firstBenchmark = true
 
         /**
-         * Hooks for benchmarks not using [BenchmarkRule] to register results.
+         * Hooks for benchmarks not using [androidx.benchmark.junit4.BenchmarkRule] to register
+         * results.
          *
          * Results are printed to Studio console, and added to the output JSON file.
          *
diff --git a/benchmark/gradle-plugin/build.gradle b/benchmark/gradle-plugin/build.gradle
index 949c11a..755ede5 100644
--- a/benchmark/gradle-plugin/build.gradle
+++ b/benchmark/gradle-plugin/build.gradle
@@ -41,7 +41,7 @@
 
 dependencies {
     implementation gradleApi()
-    implementation(build_libs.gradle)
+    implementation(ANDROID_GRADLE_PLUGIN)
     implementation(KOTLIN_STDLIB)
 
     testImplementation gradleTestKit()
diff --git a/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/Adb.kt b/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/Adb.kt
index c1f9009..0b39c10 100644
--- a/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/Adb.kt
+++ b/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/Adb.kt
@@ -43,6 +43,15 @@
         this.logger = logger
     }
 
+    fun isRooted(): Boolean {
+        val defaultUser = execSync("shell id").stdout
+        if (defaultUser.contains("uid=0(root)")) {
+            return true
+        }
+
+        return execSync("shell su exit", shouldThrow = false).exitValue == 0
+    }
+
     fun execSync(
         adbCmd: String,
         deviceId: String? = null,
diff --git a/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/BenchmarkPlugin.kt b/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/BenchmarkPlugin.kt
index 85617f0..608e3f1 100644
--- a/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/BenchmarkPlugin.kt
+++ b/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/BenchmarkPlugin.kt
@@ -71,10 +71,6 @@
         // disable overhead from test coverage by default, even if we use a debug variant
         extension.buildTypes.getByName("debug").isTestCoverageEnabled = false
 
-        // Benchmarks default to release build type to avoid pulling in debug libraries, which
-        // may have been compiled with coverage enabled.
-        extension.testBuildType = "release"
-
         // Registering this block as a configureEach callback is only necessary because Studio skips
         // Gradle if there are no changes, which stops this plugin from being re-applied.
         var enabledOutput = false
diff --git a/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/LockClocksTask.kt b/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/LockClocksTask.kt
index 9ded180..c03259a 100644
--- a/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/LockClocksTask.kt
+++ b/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/LockClocksTask.kt
@@ -40,7 +40,7 @@
         val adb = Adb(adbPath.get(), logger)
 
         // Skip "adb root" if already rooted as it will fail.
-        if (adb.execSync("shell su exit", shouldThrow = false).exitValue != 0) {
+        if (adb.isRooted()) {
             adb.execSync("root", silent = true)
         }
 
diff --git a/benchmark/gradle-plugin/src/main/resources/scripts/lockClocks.sh b/benchmark/gradle-plugin/src/main/resources/scripts/lockClocks.sh
index 8e525cf..5561452 100755
--- a/benchmark/gradle-plugin/src/main/resources/scripts/lockClocks.sh
+++ b/benchmark/gradle-plugin/src/main/resources/scripts/lockClocks.sh
@@ -20,11 +20,15 @@
 # performance between different device models.
 
 # Fun notes for maintaining this file:
-#      `expr` can deal with ints > INT32_MAX, but if compares cannot. This is why we use MHz.
-#      `expr` can sometimes evaluate right-to-left. This is why we use parens.
+#      $((arithmetic expressions)) can deal with ints > INT32_MAX, but if compares cannot. This is
+#      why we use MHz.
+#      $((arithmetic expressions)) can sometimes evaluate right-to-left. This is why we use parens.
 #      Everything below the initial host-check isn't bash - Android uses mksh
 #      mksh allows `\n` in an echo, bash doesn't
 #      can't use `awk`
+#      can't use `sed`
+#      can't use `cut` on < L
+#      can't use `expr` on < L
 
 CPU_TARGET_FREQ_PERCENT=50
 GPU_TARGET_FREQ_PERCENT=50
@@ -48,7 +52,7 @@
 fi
 
 # require root
-if [ "`id -u`" -ne "0" ]; then
+if [[ `id` != "uid=0"* ]]; then
     echo "Not running as root, cannot lock clocks, aborting"
     exit -1
 fi
@@ -97,15 +101,16 @@
         else
             disableIndices="$disableIndices $cpu"
         fi
+
         cpu=$(($cpu + 1))
     done
 
     # Chose a frequency to lock to that's >= $CPU_TARGET_FREQ_PERCENT% of max
     # (below, 100M = 1K for KHz->MHz * 100 for %)
-    TARGET_FREQ_MHZ=`expr \( ${cpuMaxFreq} \* ${CPU_TARGET_FREQ_PERCENT} \) \/ 100000`
+    TARGET_FREQ_MHZ=$(( (${cpuMaxFreq} * ${CPU_TARGET_FREQ_PERCENT}) / 100000 ))
     chosenFreq=0
     for freq in ${cpuAvailFreq}; do
-        freqMhz=`expr ${freq} \/ 1000`
+        freqMhz=$(( ${freq} / 1000 ))
         if [ ${freqMhz} -ge ${TARGET_FREQ_MHZ} ]; then
             chosenFreq=${freq}
             break
@@ -170,13 +175,13 @@
     done
 
     # (below, 100M = 1M for MHz * 100 for %)
-    TARGET_FREQ_MHZ=`expr \( ${gpuMaxFreq} \* ${GPU_TARGET_FREQ_PERCENT} \) \/ 100000000`
+    TARGET_FREQ_MHZ=$(( (${gpuMaxFreq} * ${GPU_TARGET_FREQ_PERCENT}) / 100000000 ))
 
     chosenFreq=${gpuMaxFreq}
     index=0
     chosenIndex=0
     for freq in ${gpuAvailFreq}; do
-        freqMhz=`expr ${freq} \/ 1000000`
+        freqMhz=$(( ${freq} / 1000000 ))
         if [ ${freqMhz} -ge ${TARGET_FREQ_MHZ} ] && [ ${chosenFreq} -ge ${freq} ]; then
             # note avail freq are generally in reverse order, so we don't break out of this loop
             chosenFreq=${freq}
@@ -186,7 +191,7 @@
     done
     lastIndex=$(($index - 1))
 
-    firstFreq=`echo $gpuAvailFreq | cut -d" " -f1`
+    firstFreq=`function_cut_first_from_space_seperated_list $gpuAvailFreq`
 
     if [ ${gpuMaxFreq} != ${firstFreq} ]; then
         # pwrlevel is index of desired freq among available frequencies, from highest to lowest.
@@ -225,6 +230,16 @@
     echo "Locked GPU to $chosenFreq / $gpuMaxFreq Hz"
 }
 
+# cut is not available on some devices (Nexus 5 running LRX22C).
+function_cut_first_from_space_seperated_list() {
+    list=$1
+
+    for freq in $list; do
+        echo $freq
+        break
+    done
+}
+
 # kill processes that manage thermals / scaling
 stop thermal-engine
 stop perfd
diff --git a/benchmark/gradle-plugin/src/test/kotlin/androidx/benchmark/gradle/BenchmarkPluginTest.kt b/benchmark/gradle-plugin/src/test/kotlin/androidx/benchmark/gradle/BenchmarkPluginTest.kt
index 61974bc..204096b 100644
--- a/benchmark/gradle-plugin/src/test/kotlin/androidx/benchmark/gradle/BenchmarkPluginTest.kt
+++ b/benchmark/gradle-plugin/src/test/kotlin/androidx/benchmark/gradle/BenchmarkPluginTest.kt
@@ -365,11 +365,6 @@
                 def extension = project.extensions.getByType(TestedExtension)
                 println extension.buildTypes.getByName("debug").testCoverageEnabled
             }
-
-            tasks.register("printTestBuildType") {
-                def extension = project.extensions.getByType(TestedExtension)
-                println extension.testBuildType = "release"
-            }
         """.trimIndent()
         )
 
@@ -380,9 +375,6 @@
 
         val codeCoverageOutput = gradleRunner.withArguments("printTestCoverageEnabled").build()
         assertTrue { codeCoverageOutput.output.contains("false") }
-
-        val testBuildTypeOutput = gradleRunner.withArguments("printTestBuildType").build()
-        assertTrue { testBuildTypeOutput.output.contains("release") }
     }
 
     @Test
@@ -404,7 +396,6 @@
             android {
                 compileSdkVersion $compileSdkVersion
                 buildToolsVersion "$buildToolsVersion"
-                testBuildType = "debug"
 
                 defaultConfig {
                     minSdkVersion $minSdkVersion
@@ -431,11 +422,6 @@
                 def extension = project.extensions.getByType(TestedExtension)
                 println extension.buildTypes.getByName("debug").testCoverageEnabled
             }
-
-            tasks.register("printTestBuildType") {
-                def extension = project.extensions.getByType(TestedExtension)
-                println extension.testBuildType
-            }
         """.trimIndent()
         )
 
@@ -446,8 +432,5 @@
 
         val codeCoverageOutput = gradleRunner.withArguments("printTestCoverageEnabled").build()
         assertTrue { codeCoverageOutput.output.contains("true") }
-
-        val testBuildTypeOutput = gradleRunner.withArguments("printTestBuildType").build()
-        assertTrue { testBuildTypeOutput.output.contains("debug") }
     }
 }
diff --git a/benchmark/integration-tests/dry-run-benchmark/.gitignore b/benchmark/integration-tests/dry-run-benchmark/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/benchmark/integration-tests/dry-run-benchmark/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/benchmark/integration-tests/dry-run-benchmark/README.md b/benchmark/integration-tests/dry-run-benchmark/README.md
new file mode 100644
index 0000000..3d21250
--- /dev/null
+++ b/benchmark/integration-tests/dry-run-benchmark/README.md
@@ -0,0 +1,3 @@
+Runs a single benchmark in startup mode (androidx.benchmark.startupMode.enable = true)
+
+Verifies warmup / looping behavior is simplified for startup measurement
\ No newline at end of file
diff --git a/benchmark/integration-tests/dry-run-benchmark/build.gradle b/benchmark/integration-tests/dry-run-benchmark/build.gradle
new file mode 100644
index 0000000..80085a3
--- /dev/null
+++ b/benchmark/integration-tests/dry-run-benchmark/build.gradle
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2019 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 static androidx.build.dependencies.DependenciesKt.*
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+    id("kotlin-android")
+    id("androidx.benchmark")
+}
+
+dependencies {
+    androidTestImplementation(project(":benchmark:benchmark-junit4"))
+    androidTestImplementation(ANDROIDX_TEST_RUNNER)
+    androidTestImplementation(JUNIT)
+    androidTestImplementation(KOTLIN_STDLIB)
+}
diff --git a/benchmark/integration-tests/dry-run-benchmark/src/androidTest/AndroidManifest.xml b/benchmark/integration-tests/dry-run-benchmark/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..dbe6a73
--- /dev/null
+++ b/benchmark/integration-tests/dry-run-benchmark/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2019 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"
+    xmlns:tools="http://schemas.android.com/tools"
+    package="androidx.benchmark.integration.dryrun.benchmark.test">
+    <application
+        android:name="androidx.benchmark.integration.dryrun.benchmark.ArgumentInjectingApplication"
+        android:debuggable="false"
+        tools:ignore="HardcodedDebugMode"
+        tools:replace="android:debuggable" />
+    />
+</manifest>
diff --git a/benchmark/integration-tests/dry-run-benchmark/src/androidTest/java/androidx/benchmark/integration/dryrun/benchmark/ArgumentInjectingApplication.kt b/benchmark/integration-tests/dry-run-benchmark/src/androidTest/java/androidx/benchmark/integration/dryrun/benchmark/ArgumentInjectingApplication.kt
new file mode 100644
index 0000000..dc94441
--- /dev/null
+++ b/benchmark/integration-tests/dry-run-benchmark/src/androidTest/java/androidx/benchmark/integration/dryrun/benchmark/ArgumentInjectingApplication.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 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.benchmark.integration.dryrun.benchmark
+
+import android.app.Application
+import android.os.Bundle
+import androidx.benchmark.argumentSource
+
+/**
+ * Hack to enable overriding benchmark arguments (since we can't easily do this in CI, per apk)
+ *
+ * The *correct* way to do this would be to put the following in benchmark/build.gradle:
+ *
+ * ```
+ * android {
+ *     defaultConfig {
+ *         // Enable startup measurement mode
+ *         testInstrumentationRunnerArgument 'androidx.benchmark.startupMode.enable', 'true'
+ *         // Enable dry run mode, which overrides startup
+ *         testInstrumentationRunnerArgument 'androidx.benchmark.dryRunMode.enable', 'true'
+ *     }
+ * }
+ * ```
+ */
+class ArgumentInjectingApplication : Application() {
+    override fun onCreate() {
+        super.onCreate()
+
+        argumentSource = Bundle().apply {
+            putString("androidx.benchmark.output.enable", "true")
+            putString("androidx.benchmark.startupMode.enable", "true") // this should be ignored
+            putString("androidx.benchmark.dryRunMode.enable", "true")
+        }
+    }
+}
\ No newline at end of file
diff --git a/benchmark/integration-tests/dry-run-benchmark/src/androidTest/java/androidx/benchmark/integration/dryrun/benchmark/DryRunBenchmark.kt b/benchmark/integration-tests/dry-run-benchmark/src/androidTest/java/androidx/benchmark/integration/dryrun/benchmark/DryRunBenchmark.kt
new file mode 100644
index 0000000..5ded92a
--- /dev/null
+++ b/benchmark/integration-tests/dry-run-benchmark/src/androidTest/java/androidx/benchmark/integration/dryrun/benchmark/DryRunBenchmark.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2019 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.benchmark.integration.dryrun.benchmark
+
+import androidx.benchmark.junit4.BenchmarkRule
+import androidx.benchmark.junit4.measureRepeated
+import androidx.test.filters.LargeTest
+import org.junit.Assert.assertEquals
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+@LargeTest
+class DryRunBenchmark {
+    @get:Rule
+    val benchmarkRule = BenchmarkRule()
+
+    @Test
+    fun benchmarkOne() {
+        var iterationCount = 0
+        benchmarkRule.measureRepeated {
+            iterationCount++
+        }
+        // dry run mode always runs 1 loops
+        assertEquals(1, iterationCount)
+    }
+
+    // We have two benchmarks here to verify startupMode is overridden
+    @Test
+    fun benchmarkTwo() {
+        var iterationCount = 0
+        benchmarkRule.measureRepeated {
+            iterationCount++
+        }
+        // dry run mode always runs 1 loops
+        assertEquals(1, iterationCount)
+    }
+}
\ No newline at end of file
diff --git a/benchmark/integration-tests/dry-run-benchmark/src/main/AndroidManifest.xml b/benchmark/integration-tests/dry-run-benchmark/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..22daa1a
--- /dev/null
+++ b/benchmark/integration-tests/dry-run-benchmark/src/main/AndroidManifest.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2019 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.benchmark.integration.dryrun.benchmark"/>
diff --git a/biometric/res/values-hy/strings.xml b/biometric/res/values-hy/strings.xml
index b10d90d9..23f5c30 100644
--- a/biometric/res/values-hy/strings.xml
+++ b/biometric/res/values-hy/strings.xml
@@ -17,7 +17,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="fingerprint_dialog_touch_sensor" msgid="5354590751262189738">"Հպեք մատնահետքերի սկաներին"</string>
+    <string name="fingerprint_dialog_touch_sensor" msgid="5354590751262189738">"Հպեք մատնահետքի սկաներին"</string>
     <string name="fingerprint_not_recognized" msgid="5491287833813257925">"Չհաջողվեց ճանաչել"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="6241458715391513061">"Օգնության հաղորդագրության դաշտ"</string>
     <string name="fingerprint_error_hw_not_available" msgid="3976825677335166260">"Մատնահետքերի սարքն անհասանելի է:"</string>
diff --git a/browser/README.md b/browser/README.md
new file mode 100644
index 0000000..f4c0498
--- /dev/null
+++ b/browser/README.md
@@ -0,0 +1,18 @@
+# Browser
+
+The `androidx.browser` library provides an interface for application developers
+to communicate and use web browsers.
+One such API is Custom Tabs which allows an Android app to open a URL using
+all the features of a fully-fledged web browser while keeping the user in the
+calling app's task.
+
+[Library Owners](OWNERS)
+
+[Source Code](https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/browser/)
+
+[Release Nodes](https://developer.android.com/jetpack/androidx/releases/browser)
+
+## Feedback
+To provide feedback or report bugs, please refer to the main AndroidX
+contribution guide and report your bugs
+[here](https://issuetracker.google.com/issues/new?component=460372).
diff --git a/browser/api/1.2.0-alpha07.txt b/browser/api/1.2.0-alpha07.txt
index 798e756..2894cc9 100644
--- a/browser/api/1.2.0-alpha07.txt
+++ b/browser/api/1.2.0-alpha07.txt
@@ -199,7 +199,7 @@
 
   public final class CustomTabsSession {
     method @VisibleForTesting public static androidx.browser.customtabs.CustomTabsSession createMockSessionForTesting(android.content.ComponentName);
-    method public boolean mayLaunchUrl(android.net.Uri!, android.os.Bundle!, java.util.List<android.os.Bundle!>!);
+    method public boolean mayLaunchUrl(android.net.Uri, android.os.Bundle?, java.util.List<android.os.Bundle!>?);
     method @androidx.browser.customtabs.CustomTabsService.Result public int postMessage(String!, android.os.Bundle!);
     method public boolean receiveFile(android.net.Uri, int, android.os.Bundle?);
     method public boolean requestPostMessageChannel(android.net.Uri!);
@@ -244,9 +244,14 @@
 
 package androidx.browser.trusted {
 
+  public final class TrustedWebActivityIntent {
+    method public android.content.Intent getIntent();
+    method public void launchTrustedWebActivity(android.content.Context);
+  }
+
   public class TrustedWebActivityIntentBuilder {
     ctor public TrustedWebActivityIntentBuilder(android.net.Uri);
-    method public android.content.Intent build(androidx.browser.customtabs.CustomTabsSession);
+    method public androidx.browser.trusted.TrustedWebActivityIntent build(androidx.browser.customtabs.CustomTabsSession);
     method public androidx.browser.customtabs.CustomTabsIntent buildCustomTabsIntent();
     method public android.net.Uri getUrl();
     method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setAdditionalTrustedOrigins(java.util.List<java.lang.String!>);
diff --git a/browser/api/1.2.0-alpha08.txt b/browser/api/1.2.0-alpha08.txt
new file mode 100644
index 0000000..efb806f
--- /dev/null
+++ b/browser/api/1.2.0-alpha08.txt
@@ -0,0 +1,376 @@
+// Signature format: 3.0
+package androidx.browser.browseractions {
+
+  @Deprecated public class BrowserActionItem {
+    ctor @Deprecated public BrowserActionItem(String, android.app.PendingIntent, @DrawableRes int);
+    ctor @Deprecated public BrowserActionItem(String, android.app.PendingIntent);
+    method @Deprecated public android.app.PendingIntent getAction();
+    method @Deprecated public int getIconId();
+    method @Deprecated public String getTitle();
+  }
+
+  @Deprecated public class BrowserActionsIntent {
+    method @Deprecated public static String? getCreatorPackageName(android.content.Intent);
+    method @Deprecated public android.content.Intent getIntent();
+    method @Deprecated public static String? getUntrustedCreatorPackageName(android.content.Intent);
+    method @Deprecated public static void launchIntent(android.content.Context!, android.content.Intent!);
+    method @Deprecated public static void openBrowserAction(android.content.Context!, android.net.Uri!);
+    method @Deprecated public static void openBrowserAction(android.content.Context!, android.net.Uri!, int, java.util.ArrayList<androidx.browser.browseractions.BrowserActionItem!>!, android.app.PendingIntent!);
+    method @Deprecated public static java.util.List<androidx.browser.browseractions.BrowserActionItem!>! parseBrowserActionItems(java.util.ArrayList<android.os.Bundle!>!);
+    field @Deprecated public static final String ACTION_BROWSER_ACTIONS_OPEN = "androidx.browser.browseractions.browser_action_open";
+    field @Deprecated public static final String EXTRA_APP_ID = "androidx.browser.browseractions.APP_ID";
+    field @Deprecated public static final String EXTRA_MENU_ITEMS = "androidx.browser.browseractions.extra.MENU_ITEMS";
+    field @Deprecated public static final String EXTRA_SELECTED_ACTION_PENDING_INTENT = "androidx.browser.browseractions.extra.SELECTED_ACTION_PENDING_INTENT";
+    field @Deprecated public static final String EXTRA_TYPE = "androidx.browser.browseractions.extra.TYPE";
+    field @Deprecated public static final int ITEM_COPY = 3; // 0x3
+    field @Deprecated public static final int ITEM_DOWNLOAD = 2; // 0x2
+    field @Deprecated public static final int ITEM_INVALID_ITEM = -1; // 0xffffffff
+    field @Deprecated public static final int ITEM_OPEN_IN_INCOGNITO = 1; // 0x1
+    field @Deprecated public static final int ITEM_OPEN_IN_NEW_TAB = 0; // 0x0
+    field @Deprecated public static final int ITEM_SHARE = 4; // 0x4
+    field @Deprecated public static final String KEY_ACTION = "androidx.browser.browseractions.ACTION";
+    field @Deprecated public static final String KEY_ICON_ID = "androidx.browser.browseractions.ICON_ID";
+    field @Deprecated public static final String KEY_TITLE = "androidx.browser.browseractions.TITLE";
+    field @Deprecated public static final int MAX_CUSTOM_ITEMS = 5; // 0x5
+    field @Deprecated public static final int URL_TYPE_AUDIO = 3; // 0x3
+    field @Deprecated public static final int URL_TYPE_FILE = 4; // 0x4
+    field @Deprecated public static final int URL_TYPE_IMAGE = 1; // 0x1
+    field @Deprecated public static final int URL_TYPE_NONE = 0; // 0x0
+    field @Deprecated public static final int URL_TYPE_PLUGIN = 5; // 0x5
+    field @Deprecated public static final int URL_TYPE_VIDEO = 2; // 0x2
+  }
+
+  @Deprecated public static final class BrowserActionsIntent.Builder {
+    ctor @Deprecated public BrowserActionsIntent.Builder(android.content.Context!, android.net.Uri!);
+    method @Deprecated public androidx.browser.browseractions.BrowserActionsIntent! build();
+    method @Deprecated public androidx.browser.browseractions.BrowserActionsIntent.Builder! setCustomItems(java.util.ArrayList<androidx.browser.browseractions.BrowserActionItem!>!);
+    method @Deprecated public androidx.browser.browseractions.BrowserActionsIntent.Builder! setCustomItems(androidx.browser.browseractions.BrowserActionItem!...);
+    method @Deprecated public androidx.browser.browseractions.BrowserActionsIntent.Builder! setOnItemSelectedAction(android.app.PendingIntent!);
+    method @Deprecated public androidx.browser.browseractions.BrowserActionsIntent.Builder! setUrlType(int);
+  }
+
+}
+
+package androidx.browser.customtabs {
+
+  public final class CustomTabColorSchemeParams {
+    field @ColorInt public final Integer? navigationBarColor;
+    field @ColorInt public final Integer? secondaryToolbarColor;
+    field @ColorInt public final Integer? toolbarColor;
+  }
+
+  public static final class CustomTabColorSchemeParams.Builder {
+    ctor public CustomTabColorSchemeParams.Builder();
+    method public androidx.browser.customtabs.CustomTabColorSchemeParams build();
+    method public androidx.browser.customtabs.CustomTabColorSchemeParams.Builder setNavigationBarColor(@ColorInt int);
+    method public androidx.browser.customtabs.CustomTabColorSchemeParams.Builder setSecondaryToolbarColor(@ColorInt int);
+    method public androidx.browser.customtabs.CustomTabColorSchemeParams.Builder setToolbarColor(@ColorInt int);
+  }
+
+  public class CustomTabsCallback {
+    ctor public CustomTabsCallback();
+    method public void extraCallback(String!, android.os.Bundle!);
+    method public void onMessageChannelReady(android.os.Bundle!);
+    method public void onNavigationEvent(int, android.os.Bundle!);
+    method public void onPostMessage(String!, android.os.Bundle!);
+    method public void onRelationshipValidationResult(@androidx.browser.customtabs.CustomTabsService.Relation int, android.net.Uri!, boolean, android.os.Bundle!);
+    field public static final int NAVIGATION_ABORTED = 4; // 0x4
+    field public static final int NAVIGATION_FAILED = 3; // 0x3
+    field public static final int NAVIGATION_FINISHED = 2; // 0x2
+    field public static final int NAVIGATION_STARTED = 1; // 0x1
+    field public static final int TAB_HIDDEN = 6; // 0x6
+    field public static final int TAB_SHOWN = 5; // 0x5
+  }
+
+  public class CustomTabsClient {
+    method public static boolean bindCustomTabsService(android.content.Context, String?, androidx.browser.customtabs.CustomTabsServiceConnection);
+    method public static boolean connectAndInitialize(android.content.Context, String);
+    method public android.os.Bundle? extraCommand(String, android.os.Bundle?);
+    method public static String? getPackageName(android.content.Context, java.util.List<java.lang.String!>?);
+    method public static String? getPackageName(android.content.Context, java.util.List<java.lang.String!>?, boolean);
+    method public androidx.browser.customtabs.CustomTabsSession? newSession(androidx.browser.customtabs.CustomTabsCallback?);
+    method public androidx.browser.customtabs.CustomTabsSession? newSession(androidx.browser.customtabs.CustomTabsCallback?, int);
+    method public boolean warmup(long);
+  }
+
+  public final class CustomTabsIntent {
+    method public static androidx.browser.customtabs.CustomTabColorSchemeParams getColorSchemeParams(android.content.Intent, int);
+    method public static int getMaxToolbarItems();
+    method public void launchUrl(android.content.Context!, android.net.Uri!);
+    method public static android.content.Intent! setAlwaysUseBrowserUI(android.content.Intent!);
+    method public static boolean shouldAlwaysUseBrowserUI(android.content.Intent!);
+    field public static final int COLOR_SCHEME_DARK = 2; // 0x2
+    field public static final int COLOR_SCHEME_LIGHT = 1; // 0x1
+    field public static final int COLOR_SCHEME_SYSTEM = 0; // 0x0
+    field public static final String EXTRA_ACTION_BUTTON_BUNDLE = "android.support.customtabs.extra.ACTION_BUTTON_BUNDLE";
+    field public static final String EXTRA_CLOSE_BUTTON_ICON = "android.support.customtabs.extra.CLOSE_BUTTON_ICON";
+    field public static final String EXTRA_COLOR_SCHEME = "androidx.browser.customtabs.extra.COLOR_SCHEME";
+    field public static final String EXTRA_COLOR_SCHEME_PARAMS = "androidx.browser.customtabs.extra.COLOR_SCHEME_PARAMS";
+    field public static final String EXTRA_DEFAULT_SHARE_MENU_ITEM = "android.support.customtabs.extra.SHARE_MENU_ITEM";
+    field public static final String EXTRA_ENABLE_INSTANT_APPS = "android.support.customtabs.extra.EXTRA_ENABLE_INSTANT_APPS";
+    field public static final String EXTRA_ENABLE_URLBAR_HIDING = "android.support.customtabs.extra.ENABLE_URLBAR_HIDING";
+    field public static final String EXTRA_EXIT_ANIMATION_BUNDLE = "android.support.customtabs.extra.EXIT_ANIMATION_BUNDLE";
+    field public static final String EXTRA_MENU_ITEMS = "android.support.customtabs.extra.MENU_ITEMS";
+    field public static final String EXTRA_NAVIGATION_BAR_COLOR = "androidx.browser.customtabs.extra.NAVIGATION_BAR_COLOR";
+    field public static final String EXTRA_REMOTEVIEWS = "android.support.customtabs.extra.EXTRA_REMOTEVIEWS";
+    field public static final String EXTRA_REMOTEVIEWS_CLICKED_ID = "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_CLICKED_ID";
+    field public static final String EXTRA_REMOTEVIEWS_PENDINGINTENT = "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_PENDINGINTENT";
+    field public static final String EXTRA_REMOTEVIEWS_VIEW_IDS = "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_VIEW_IDS";
+    field public static final String EXTRA_SECONDARY_TOOLBAR_COLOR = "android.support.customtabs.extra.SECONDARY_TOOLBAR_COLOR";
+    field public static final String EXTRA_SESSION = "android.support.customtabs.extra.SESSION";
+    field public static final String EXTRA_TINT_ACTION_BUTTON = "android.support.customtabs.extra.TINT_ACTION_BUTTON";
+    field public static final String EXTRA_TITLE_VISIBILITY_STATE = "android.support.customtabs.extra.TITLE_VISIBILITY";
+    field public static final String EXTRA_TOOLBAR_COLOR = "android.support.customtabs.extra.TOOLBAR_COLOR";
+    field public static final String EXTRA_TOOLBAR_ITEMS = "android.support.customtabs.extra.TOOLBAR_ITEMS";
+    field public static final String KEY_DESCRIPTION = "android.support.customtabs.customaction.DESCRIPTION";
+    field public static final String KEY_ICON = "android.support.customtabs.customaction.ICON";
+    field public static final String KEY_ID = "android.support.customtabs.customaction.ID";
+    field public static final String KEY_MENU_ITEM_TITLE = "android.support.customtabs.customaction.MENU_ITEM_TITLE";
+    field public static final String KEY_PENDING_INTENT = "android.support.customtabs.customaction.PENDING_INTENT";
+    field public static final int NO_TITLE = 0; // 0x0
+    field public static final int SHOW_PAGE_TITLE = 1; // 0x1
+    field public static final int TOOLBAR_ACTION_BUTTON_ID = 0; // 0x0
+    field public final android.content.Intent intent;
+    field public final android.os.Bundle? startAnimationBundle;
+  }
+
+  public static final class CustomTabsIntent.Builder {
+    ctor public CustomTabsIntent.Builder();
+    ctor public CustomTabsIntent.Builder(androidx.browser.customtabs.CustomTabsSession?);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder addDefaultShareMenuItem();
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder addMenuItem(String, android.app.PendingIntent);
+    method @Deprecated public androidx.browser.customtabs.CustomTabsIntent.Builder addToolbarItem(int, android.graphics.Bitmap, String, android.app.PendingIntent!) throws java.lang.IllegalStateException;
+    method public androidx.browser.customtabs.CustomTabsIntent build();
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder enableUrlBarHiding();
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setActionButton(android.graphics.Bitmap, String, android.app.PendingIntent, boolean);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setActionButton(android.graphics.Bitmap, String, android.app.PendingIntent);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setCloseButtonIcon(android.graphics.Bitmap);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setColorScheme(int);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setColorSchemeParams(int, androidx.browser.customtabs.CustomTabColorSchemeParams);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setExitAnimations(android.content.Context, @AnimRes int, @AnimRes int);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setInstantAppsEnabled(boolean);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setNavigationBarColor(@ColorInt int);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setSecondaryToolbarColor(@ColorInt int);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setSecondaryToolbarViews(android.widget.RemoteViews, int[]?, android.app.PendingIntent?);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setSession(androidx.browser.customtabs.CustomTabsSession);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setShowTitle(boolean);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setStartAnimations(android.content.Context, @AnimRes int, @AnimRes int);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setToolbarColor(@ColorInt int);
+  }
+
+  public abstract class CustomTabsService extends android.app.Service {
+    ctor public CustomTabsService();
+    method protected boolean cleanUpSession(androidx.browser.customtabs.CustomTabsSessionToken!);
+    method protected abstract android.os.Bundle! extraCommand(String!, android.os.Bundle!);
+    method protected abstract boolean mayLaunchUrl(androidx.browser.customtabs.CustomTabsSessionToken!, android.net.Uri!, android.os.Bundle!, java.util.List<android.os.Bundle!>!);
+    method protected abstract boolean newSession(androidx.browser.customtabs.CustomTabsSessionToken!);
+    method public android.os.IBinder! onBind(android.content.Intent!);
+    method @androidx.browser.customtabs.CustomTabsService.Result protected abstract int postMessage(androidx.browser.customtabs.CustomTabsSessionToken!, String!, android.os.Bundle!);
+    method protected abstract boolean receiveFile(androidx.browser.customtabs.CustomTabsSessionToken, android.net.Uri, int, android.os.Bundle?);
+    method protected abstract boolean requestPostMessageChannel(androidx.browser.customtabs.CustomTabsSessionToken!, android.net.Uri!);
+    method protected abstract boolean updateVisuals(androidx.browser.customtabs.CustomTabsSessionToken!, android.os.Bundle!);
+    method protected abstract boolean validateRelationship(androidx.browser.customtabs.CustomTabsSessionToken!, @androidx.browser.customtabs.CustomTabsService.Relation int, android.net.Uri!, android.os.Bundle!);
+    method protected abstract boolean warmup(long);
+    field public static final String ACTION_CUSTOM_TABS_CONNECTION = "android.support.customtabs.action.CustomTabsService";
+    field public static final String CATEGORY_COLOR_SCHEME_CUSTOMIZATION = "androidx.browser.customtabs.category.ColorSchemeCustomization";
+    field public static final String CATEGORY_NAVBAR_COLOR_CUSTOMIZATION = "androidx.browser.customtabs.category.NavBarColorCustomization";
+    field public static final int FILE_PURPOSE_TRUSTED_WEB_ACTIVITY_SPLASH_IMAGE = 1; // 0x1
+    field public static final String KEY_URL = "android.support.customtabs.otherurls.URL";
+    field public static final int RELATION_HANDLE_ALL_URLS = 2; // 0x2
+    field public static final int RELATION_USE_AS_ORIGIN = 1; // 0x1
+    field public static final int RESULT_FAILURE_DISALLOWED = -1; // 0xffffffff
+    field public static final int RESULT_FAILURE_MESSAGING_ERROR = -3; // 0xfffffffd
+    field public static final int RESULT_FAILURE_REMOTE_ERROR = -2; // 0xfffffffe
+    field public static final int RESULT_SUCCESS = 0; // 0x0
+    field public static final String TRUSTED_WEB_ACTIVITY_CATEGORY = "androidx.browser.trusted.category.TrustedWebActivities";
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({androidx.browser.customtabs.CustomTabsService.RELATION_USE_AS_ORIGIN, androidx.browser.customtabs.CustomTabsService.RELATION_HANDLE_ALL_URLS}) public static @interface CustomTabsService.Relation {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({androidx.browser.customtabs.CustomTabsService.RESULT_SUCCESS, androidx.browser.customtabs.CustomTabsService.RESULT_FAILURE_DISALLOWED, androidx.browser.customtabs.CustomTabsService.RESULT_FAILURE_REMOTE_ERROR, androidx.browser.customtabs.CustomTabsService.RESULT_FAILURE_MESSAGING_ERROR}) public static @interface CustomTabsService.Result {
+  }
+
+  public abstract class CustomTabsServiceConnection implements android.content.ServiceConnection {
+    ctor public CustomTabsServiceConnection();
+    method public abstract void onCustomTabsServiceConnected(android.content.ComponentName!, androidx.browser.customtabs.CustomTabsClient!);
+    method public final void onServiceConnected(android.content.ComponentName!, android.os.IBinder!);
+  }
+
+  public final class CustomTabsSession {
+    method @VisibleForTesting public static androidx.browser.customtabs.CustomTabsSession createMockSessionForTesting(android.content.ComponentName);
+    method public boolean mayLaunchUrl(android.net.Uri, android.os.Bundle?, java.util.List<android.os.Bundle!>?);
+    method @androidx.browser.customtabs.CustomTabsService.Result public int postMessage(String, android.os.Bundle?);
+    method public boolean receiveFile(android.net.Uri, int, android.os.Bundle?);
+    method public boolean requestPostMessageChannel(android.net.Uri);
+    method public boolean setActionButton(android.graphics.Bitmap, String);
+    method public boolean setSecondaryToolbarViews(android.widget.RemoteViews?, int[]?, android.app.PendingIntent?);
+    method @Deprecated public boolean setToolbarItem(int, android.graphics.Bitmap, String);
+    method public boolean validateRelationship(@androidx.browser.customtabs.CustomTabsService.Relation int, android.net.Uri, android.os.Bundle?);
+  }
+
+  public class CustomTabsSessionToken {
+    method public static androidx.browser.customtabs.CustomTabsSessionToken createMockSessionTokenForTesting();
+    method public androidx.browser.customtabs.CustomTabsCallback? getCallback();
+    method public static androidx.browser.customtabs.CustomTabsSessionToken? getSessionTokenFromIntent(android.content.Intent);
+    method public boolean isAssociatedWith(androidx.browser.customtabs.CustomTabsSession);
+  }
+
+  public class PostMessageService extends android.app.Service {
+    ctor public PostMessageService();
+    method public android.os.IBinder! onBind(android.content.Intent!);
+  }
+
+  public abstract class PostMessageServiceConnection implements android.content.ServiceConnection {
+    ctor public PostMessageServiceConnection(androidx.browser.customtabs.CustomTabsSessionToken!);
+    method public boolean bindSessionToPostMessageService(android.content.Context!, String!);
+    method public final boolean notifyMessageChannelReady(android.os.Bundle!);
+    method public void onPostMessageServiceConnected();
+    method public void onPostMessageServiceDisconnected();
+    method public final void onServiceConnected(android.content.ComponentName!, android.os.IBinder!);
+    method public final void onServiceDisconnected(android.content.ComponentName!);
+    method public final boolean postMessage(String!, android.os.Bundle!);
+    method public void unbindFromContext(android.content.Context!);
+  }
+
+  public class TrustedWebUtils {
+    method @Deprecated public static void launchAsTrustedWebActivity(android.content.Context, androidx.browser.customtabs.CustomTabsIntent, android.net.Uri);
+    method public static boolean splashScreensAreSupported(android.content.Context, String, String);
+    method @WorkerThread public static boolean transferSplashImage(android.content.Context, java.io.File, String, String, androidx.browser.customtabs.CustomTabsSession);
+    field public static final String EXTRA_LAUNCH_AS_TRUSTED_WEB_ACTIVITY = "android.support.customtabs.extra.LAUNCH_AS_TRUSTED_WEB_ACTIVITY";
+  }
+
+}
+
+package androidx.browser.trusted {
+
+  public final class TrustedWebActivityIntent {
+    method public android.content.Intent getIntent();
+    method public void launchTrustedWebActivity(android.content.Context);
+  }
+
+  public class TrustedWebActivityIntentBuilder {
+    ctor public TrustedWebActivityIntentBuilder(android.net.Uri);
+    method public androidx.browser.trusted.TrustedWebActivityIntent build(androidx.browser.customtabs.CustomTabsSession);
+    method public androidx.browser.customtabs.CustomTabsIntent buildCustomTabsIntent();
+    method public android.net.Uri getUrl();
+    method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setAdditionalTrustedOrigins(java.util.List<java.lang.String!>);
+    method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setColorScheme(int);
+    method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setColorSchemeParams(int, androidx.browser.customtabs.CustomTabColorSchemeParams);
+    method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setNavigationBarColor(@ColorInt int);
+    method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setShareParams(androidx.browser.trusted.sharing.ShareTarget, androidx.browser.trusted.sharing.ShareData);
+    method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setSplashScreenParams(android.os.Bundle);
+    method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setToolbarColor(@ColorInt int);
+    field public static final String EXTRA_ADDITIONAL_TRUSTED_ORIGINS = "android.support.customtabs.extra.ADDITIONAL_TRUSTED_ORIGINS";
+    field public static final String EXTRA_SHARE_DATA = "androidx.browser.trusted.extra.SHARE_DATA";
+    field public static final String EXTRA_SHARE_TARGET = "androidx.browser.trusted.extra.SHARE_TARGET";
+    field public static final String EXTRA_SPLASH_SCREEN_PARAMS = "androidx.browser.trusted.EXTRA_SPLASH_SCREEN_PARAMS";
+  }
+
+  public class TrustedWebActivityService extends android.app.Service {
+    ctor public TrustedWebActivityService();
+    method public boolean areNotificationsEnabled(String);
+    method public void cancelNotification(String, int);
+    method public android.os.Bundle getSmallIconBitmap();
+    method public int getSmallIconId();
+    method public boolean notifyNotificationWithChannel(String, int, android.app.Notification, String);
+    method public final android.os.IBinder? onBind(android.content.Intent?);
+    method public final boolean onUnbind(android.content.Intent?);
+    method public static final void setVerifiedProvider(android.content.Context, String?);
+    field public static final String ACTION_TRUSTED_WEB_ACTIVITY_SERVICE = "android.support.customtabs.trusted.TRUSTED_WEB_ACTIVITY_SERVICE";
+    field public static final String KEY_SMALL_ICON_BITMAP = "android.support.customtabs.trusted.SMALL_ICON_BITMAP";
+    field public static final String META_DATA_NAME_SMALL_ICON = "android.support.customtabs.trusted.SMALL_ICON";
+    field public static final int SMALL_ICON_NOT_SET = -1; // 0xffffffff
+  }
+
+  public class TrustedWebActivityServiceConnectionManager {
+    ctor public TrustedWebActivityServiceConnectionManager(android.content.Context);
+    method @MainThread public boolean execute(android.net.Uri, String, androidx.browser.trusted.TrustedWebActivityServiceConnectionManager.ExecutionCallback);
+    method public static java.util.Set<java.lang.String!> getVerifiedPackages(android.content.Context, String);
+    method public static void registerClient(android.content.Context, String, String);
+    method @MainThread public boolean serviceExistsForScope(android.net.Uri, String);
+  }
+
+  public static interface TrustedWebActivityServiceConnectionManager.ExecutionCallback {
+    method public void onConnected(androidx.browser.trusted.TrustedWebActivityServiceWrapper?) throws android.os.RemoteException;
+  }
+
+  public class TrustedWebActivityServiceWrapper {
+    method public boolean areNotificationsEnabled(String);
+    method public void cancel(String, int);
+    method public android.content.ComponentName getComponentName();
+    method public android.graphics.Bitmap? getSmallIconBitmap();
+    method public int getSmallIconId();
+    method public boolean notify(String, int, android.app.Notification, String);
+  }
+
+}
+
+package androidx.browser.trusted.sharing {
+
+  public final class ShareData {
+    ctor public ShareData(String?, String?, java.util.List<android.net.Uri!>?);
+    method public static androidx.browser.trusted.sharing.ShareData fromBundle(android.os.Bundle);
+    method public android.os.Bundle toBundle();
+    field public static final String KEY_TEXT = "androidx.browser.trusted.sharing.KEY_TEXT";
+    field public static final String KEY_TITLE = "androidx.browser.trusted.sharing.KEY_TITLE";
+    field public static final String KEY_URIS = "androidx.browser.trusted.sharing.KEY_URIS";
+    field public final String? text;
+    field public final String? title;
+    field public final java.util.List<android.net.Uri!>? uris;
+  }
+
+  public final class ShareTarget {
+    ctor public ShareTarget(String, String?, String?, androidx.browser.trusted.sharing.ShareTarget.Params);
+    method public static androidx.browser.trusted.sharing.ShareTarget? fromBundle(android.os.Bundle);
+    method public android.os.Bundle toBundle();
+    field public static final String ENCODING_TYPE_MULTIPART = "multipart/form-data";
+    field public static final String ENCODING_TYPE_URL_ENCODED = "application/x-www-form-urlencoded";
+    field public static final String KEY_ACTION = "androidx.browser.trusted.sharing.KEY_ACTION";
+    field public static final String KEY_ENCTYPE = "androidx.browser.trusted.sharing.KEY_ENCTYPE";
+    field public static final String KEY_METHOD = "androidx.browser.trusted.sharing.KEY_METHOD";
+    field public static final String KEY_PARAMS = "androidx.browser.trusted.sharing.KEY_PARAMS";
+    field public static final String METHOD_GET = "GET";
+    field public static final String METHOD_POST = "POST";
+    field public final String action;
+    field public final String? encodingType;
+    field public final String? method;
+    field public final androidx.browser.trusted.sharing.ShareTarget.Params params;
+  }
+
+  public static class ShareTarget.FileFormField {
+    ctor public ShareTarget.FileFormField(String, java.util.List<java.lang.String!>);
+    field public static final String KEY_ACCEPTED_TYPES = "androidx.browser.trusted.sharing.KEY_ACCEPTED_TYPES";
+    field public static final String KEY_NAME = "androidx.browser.trusted.sharing.KEY_FILE_NAME";
+    field public final java.util.List<java.lang.String!> acceptedTypes;
+    field public final String name;
+  }
+
+  public static class ShareTarget.Params {
+    ctor public ShareTarget.Params(String?, String?, java.util.List<androidx.browser.trusted.sharing.ShareTarget.FileFormField!>?);
+    field public static final String KEY_FILES = "androidx.browser.trusted.sharing.KEY_FILES";
+    field public static final String KEY_TEXT = "androidx.browser.trusted.sharing.KEY_TEXT";
+    field public static final String KEY_TITLE = "androidx.browser.trusted.sharing.KEY_TITLE";
+    field public final java.util.List<androidx.browser.trusted.sharing.ShareTarget.FileFormField!>? files;
+    field public final String? text;
+    field public final String? title;
+  }
+
+}
+
+package androidx.browser.trusted.splashscreens {
+
+  public final class SplashScreenParamKey {
+    field public static final String BACKGROUND_COLOR = "androidx.browser.trusted.trusted.KEY_SPLASH_SCREEN_BACKGROUND_COLOR";
+    field public static final String FADE_OUT_DURATION_MS = "androidx.browser.trusted.KEY_SPLASH_SCREEN_FADE_OUT_DURATION";
+    field public static final String IMAGE_TRANSFORMATION_MATRIX = "androidx.browser.trusted.KEY_SPLASH_SCREEN_TRANSFORMATION_MATRIX";
+    field public static final String SCALE_TYPE = "androidx.browser.trusted.KEY_SPLASH_SCREEN_SCALE_TYPE";
+    field public static final String VERSION = "androidx.browser.trusted.KEY_SPLASH_SCREEN_VERSION";
+  }
+
+  public final class SplashScreenVersion {
+    field public static final String V1 = "androidx.browser.trusted.category.TrustedWebActivitySplashScreensV1";
+  }
+
+}
+
diff --git a/browser/api/api_lint.ignore b/browser/api/api_lint.ignore
index 880cc30..a9dd73e 100644
--- a/browser/api/api_lint.ignore
+++ b/browser/api/api_lint.ignore
@@ -71,3 +71,149 @@
 
 IntentName: androidx.browser.browseractions.BrowserActionsIntent#KEY_ACTION:
     Intent action constant name must be ACTION_FOO: KEY_ACTION
+
+
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent#launchIntent(android.content.Context, android.content.Intent) parameter #0:
+    Missing nullability on parameter `context` in method `launchIntent`
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent#launchIntent(android.content.Context, android.content.Intent) parameter #1:
+    Missing nullability on parameter `intent` in method `launchIntent`
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent#openBrowserAction(android.content.Context, android.net.Uri) parameter #0:
+    Missing nullability on parameter `context` in method `openBrowserAction`
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent#openBrowserAction(android.content.Context, android.net.Uri) parameter #1:
+    Missing nullability on parameter `uri` in method `openBrowserAction`
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent#openBrowserAction(android.content.Context, android.net.Uri, int, java.util.ArrayList<androidx.browser.browseractions.BrowserActionItem>, android.app.PendingIntent) parameter #0:
+    Missing nullability on parameter `context` in method `openBrowserAction`
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent#openBrowserAction(android.content.Context, android.net.Uri, int, java.util.ArrayList<androidx.browser.browseractions.BrowserActionItem>, android.app.PendingIntent) parameter #1:
+    Missing nullability on parameter `uri` in method `openBrowserAction`
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent#openBrowserAction(android.content.Context, android.net.Uri, int, java.util.ArrayList<androidx.browser.browseractions.BrowserActionItem>, android.app.PendingIntent) parameter #3:
+    Missing nullability on parameter `items` in method `openBrowserAction`
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent#openBrowserAction(android.content.Context, android.net.Uri, int, java.util.ArrayList<androidx.browser.browseractions.BrowserActionItem>, android.app.PendingIntent) parameter #4:
+    Missing nullability on parameter `pendingIntent` in method `openBrowserAction`
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent#parseBrowserActionItems(java.util.ArrayList<android.os.Bundle>):
+    Missing nullability on method `parseBrowserActionItems` return
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent#parseBrowserActionItems(java.util.ArrayList<android.os.Bundle>) parameter #0:
+    Missing nullability on parameter `bundles` in method `parseBrowserActionItems`
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent.Builder#Builder(android.content.Context, android.net.Uri) parameter #0:
+    Missing nullability on parameter `context` in method `Builder`
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent.Builder#Builder(android.content.Context, android.net.Uri) parameter #1:
+    Missing nullability on parameter `uri` in method `Builder`
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent.Builder#setCustomItems(androidx.browser.browseractions.BrowserActionItem...):
+    Missing nullability on method `setCustomItems` return
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent.Builder#setCustomItems(androidx.browser.browseractions.BrowserActionItem...) parameter #0:
+    Missing nullability on parameter `items` in method `setCustomItems`
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent.Builder#setCustomItems(java.util.ArrayList<androidx.browser.browseractions.BrowserActionItem>):
+    Missing nullability on method `setCustomItems` return
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent.Builder#setCustomItems(java.util.ArrayList<androidx.browser.browseractions.BrowserActionItem>) parameter #0:
+    Missing nullability on parameter `items` in method `setCustomItems`
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent.Builder#setOnItemSelectedAction(android.app.PendingIntent):
+    Missing nullability on method `setOnItemSelectedAction` return
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent.Builder#setOnItemSelectedAction(android.app.PendingIntent) parameter #0:
+    Missing nullability on parameter `onItemSelectedPendingIntent` in method `setOnItemSelectedAction`
+MissingNullability: androidx.browser.browseractions.BrowserActionsIntent.Builder#setUrlType(int):
+    Missing nullability on method `setUrlType` return
+MissingNullability: androidx.browser.customtabs.CustomTabsCallback#extraCallback(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `callbackName` in method `extraCallback`
+MissingNullability: androidx.browser.customtabs.CustomTabsCallback#extraCallback(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `args` in method `extraCallback`
+MissingNullability: androidx.browser.customtabs.CustomTabsCallback#onMessageChannelReady(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `extras` in method `onMessageChannelReady`
+MissingNullability: androidx.browser.customtabs.CustomTabsCallback#onNavigationEvent(int, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `onNavigationEvent`
+MissingNullability: androidx.browser.customtabs.CustomTabsCallback#onPostMessage(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `message` in method `onPostMessage`
+MissingNullability: androidx.browser.customtabs.CustomTabsCallback#onPostMessage(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `onPostMessage`
+MissingNullability: androidx.browser.customtabs.CustomTabsCallback#onRelationshipValidationResult(int, android.net.Uri, boolean, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `requestedOrigin` in method `onRelationshipValidationResult`
+MissingNullability: androidx.browser.customtabs.CustomTabsCallback#onRelationshipValidationResult(int, android.net.Uri, boolean, android.os.Bundle) parameter #3:
+    Missing nullability on parameter `extras` in method `onRelationshipValidationResult`
+MissingNullability: androidx.browser.customtabs.CustomTabsIntent#launchUrl(android.content.Context, android.net.Uri) parameter #0:
+    Missing nullability on parameter `context` in method `launchUrl`
+MissingNullability: androidx.browser.customtabs.CustomTabsIntent#launchUrl(android.content.Context, android.net.Uri) parameter #1:
+    Missing nullability on parameter `url` in method `launchUrl`
+MissingNullability: androidx.browser.customtabs.CustomTabsIntent#setAlwaysUseBrowserUI(android.content.Intent):
+    Missing nullability on method `setAlwaysUseBrowserUI` return
+MissingNullability: androidx.browser.customtabs.CustomTabsIntent#setAlwaysUseBrowserUI(android.content.Intent) parameter #0:
+    Missing nullability on parameter `intent` in method `setAlwaysUseBrowserUI`
+MissingNullability: androidx.browser.customtabs.CustomTabsIntent#shouldAlwaysUseBrowserUI(android.content.Intent) parameter #0:
+    Missing nullability on parameter `intent` in method `shouldAlwaysUseBrowserUI`
+MissingNullability: androidx.browser.customtabs.CustomTabsIntent.Builder#addToolbarItem(int, android.graphics.Bitmap, String, android.app.PendingIntent) parameter #3:
+    Missing nullability on parameter `pendingIntent` in method `addToolbarItem`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#cleanUpSession(androidx.browser.customtabs.CustomTabsSessionToken) parameter #0:
+    Missing nullability on parameter `sessionToken` in method `cleanUpSession`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#extraCommand(String, android.os.Bundle):
+    Missing nullability on method `extraCommand` return
+MissingNullability: androidx.browser.customtabs.CustomTabsService#extraCommand(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `commandName` in method `extraCommand`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#extraCommand(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `args` in method `extraCommand`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#mayLaunchUrl(androidx.browser.customtabs.CustomTabsSessionToken, android.net.Uri, android.os.Bundle, java.util.List<android.os.Bundle>) parameter #0:
+    Missing nullability on parameter `sessionToken` in method `mayLaunchUrl`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#mayLaunchUrl(androidx.browser.customtabs.CustomTabsSessionToken, android.net.Uri, android.os.Bundle, java.util.List<android.os.Bundle>) parameter #1:
+    Missing nullability on parameter `url` in method `mayLaunchUrl`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#mayLaunchUrl(androidx.browser.customtabs.CustomTabsSessionToken, android.net.Uri, android.os.Bundle, java.util.List<android.os.Bundle>) parameter #2:
+    Missing nullability on parameter `extras` in method `mayLaunchUrl`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#mayLaunchUrl(androidx.browser.customtabs.CustomTabsSessionToken, android.net.Uri, android.os.Bundle, java.util.List<android.os.Bundle>) parameter #3:
+    Missing nullability on parameter `otherLikelyBundles` in method `mayLaunchUrl`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#newSession(androidx.browser.customtabs.CustomTabsSessionToken) parameter #0:
+    Missing nullability on parameter `sessionToken` in method `newSession`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#onBind(android.content.Intent):
+    Missing nullability on method `onBind` return
+MissingNullability: androidx.browser.customtabs.CustomTabsService#onBind(android.content.Intent) parameter #0:
+    Missing nullability on parameter `intent` in method `onBind`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#postMessage(androidx.browser.customtabs.CustomTabsSessionToken, String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `sessionToken` in method `postMessage`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#postMessage(androidx.browser.customtabs.CustomTabsSessionToken, String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `message` in method `postMessage`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#postMessage(androidx.browser.customtabs.CustomTabsSessionToken, String, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `extras` in method `postMessage`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#requestPostMessageChannel(androidx.browser.customtabs.CustomTabsSessionToken, android.net.Uri) parameter #0:
+    Missing nullability on parameter `sessionToken` in method `requestPostMessageChannel`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#requestPostMessageChannel(androidx.browser.customtabs.CustomTabsSessionToken, android.net.Uri) parameter #1:
+    Missing nullability on parameter `postMessageOrigin` in method `requestPostMessageChannel`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#updateVisuals(androidx.browser.customtabs.CustomTabsSessionToken, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `sessionToken` in method `updateVisuals`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#updateVisuals(androidx.browser.customtabs.CustomTabsSessionToken, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `bundle` in method `updateVisuals`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#validateRelationship(androidx.browser.customtabs.CustomTabsSessionToken, int, android.net.Uri, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `sessionToken` in method `validateRelationship`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#validateRelationship(androidx.browser.customtabs.CustomTabsSessionToken, int, android.net.Uri, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `origin` in method `validateRelationship`
+MissingNullability: androidx.browser.customtabs.CustomTabsService#validateRelationship(androidx.browser.customtabs.CustomTabsSessionToken, int, android.net.Uri, android.os.Bundle) parameter #3:
+    Missing nullability on parameter `extras` in method `validateRelationship`
+MissingNullability: androidx.browser.customtabs.CustomTabsServiceConnection#onCustomTabsServiceConnected(android.content.ComponentName, androidx.browser.customtabs.CustomTabsClient) parameter #0:
+    Missing nullability on parameter `name` in method `onCustomTabsServiceConnected`
+MissingNullability: androidx.browser.customtabs.CustomTabsServiceConnection#onCustomTabsServiceConnected(android.content.ComponentName, androidx.browser.customtabs.CustomTabsClient) parameter #1:
+    Missing nullability on parameter `client` in method `onCustomTabsServiceConnected`
+MissingNullability: androidx.browser.customtabs.CustomTabsServiceConnection#onServiceConnected(android.content.ComponentName, android.os.IBinder) parameter #0:
+    Missing nullability on parameter `name` in method `onServiceConnected`
+MissingNullability: androidx.browser.customtabs.CustomTabsServiceConnection#onServiceConnected(android.content.ComponentName, android.os.IBinder) parameter #1:
+    Missing nullability on parameter `service` in method `onServiceConnected`
+MissingNullability: androidx.browser.customtabs.CustomTabsSessionToken#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.browser.customtabs.PostMessageService#onBind(android.content.Intent):
+    Missing nullability on method `onBind` return
+MissingNullability: androidx.browser.customtabs.PostMessageService#onBind(android.content.Intent) parameter #0:
+    Missing nullability on parameter `intent` in method `onBind`
+MissingNullability: androidx.browser.customtabs.PostMessageServiceConnection#PostMessageServiceConnection(androidx.browser.customtabs.CustomTabsSessionToken) parameter #0:
+    Missing nullability on parameter `session` in method `PostMessageServiceConnection`
+MissingNullability: androidx.browser.customtabs.PostMessageServiceConnection#bindSessionToPostMessageService(android.content.Context, String) parameter #0:
+    Missing nullability on parameter `context` in method `bindSessionToPostMessageService`
+MissingNullability: androidx.browser.customtabs.PostMessageServiceConnection#bindSessionToPostMessageService(android.content.Context, String) parameter #1:
+    Missing nullability on parameter `packageName` in method `bindSessionToPostMessageService`
+MissingNullability: androidx.browser.customtabs.PostMessageServiceConnection#notifyMessageChannelReady(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `extras` in method `notifyMessageChannelReady`
+MissingNullability: androidx.browser.customtabs.PostMessageServiceConnection#onServiceConnected(android.content.ComponentName, android.os.IBinder) parameter #0:
+    Missing nullability on parameter `name` in method `onServiceConnected`
+MissingNullability: androidx.browser.customtabs.PostMessageServiceConnection#onServiceConnected(android.content.ComponentName, android.os.IBinder) parameter #1:
+    Missing nullability on parameter `service` in method `onServiceConnected`
+MissingNullability: androidx.browser.customtabs.PostMessageServiceConnection#onServiceDisconnected(android.content.ComponentName) parameter #0:
+    Missing nullability on parameter `name` in method `onServiceDisconnected`
+MissingNullability: androidx.browser.customtabs.PostMessageServiceConnection#postMessage(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `message` in method `postMessage`
+MissingNullability: androidx.browser.customtabs.PostMessageServiceConnection#postMessage(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `postMessage`
+MissingNullability: androidx.browser.customtabs.PostMessageServiceConnection#unbindFromContext(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `unbindFromContext`
diff --git a/browser/api/current.txt b/browser/api/current.txt
index 798e756..efb806f 100644
--- a/browser/api/current.txt
+++ b/browser/api/current.txt
@@ -199,10 +199,10 @@
 
   public final class CustomTabsSession {
     method @VisibleForTesting public static androidx.browser.customtabs.CustomTabsSession createMockSessionForTesting(android.content.ComponentName);
-    method public boolean mayLaunchUrl(android.net.Uri!, android.os.Bundle!, java.util.List<android.os.Bundle!>!);
-    method @androidx.browser.customtabs.CustomTabsService.Result public int postMessage(String!, android.os.Bundle!);
+    method public boolean mayLaunchUrl(android.net.Uri, android.os.Bundle?, java.util.List<android.os.Bundle!>?);
+    method @androidx.browser.customtabs.CustomTabsService.Result public int postMessage(String, android.os.Bundle?);
     method public boolean receiveFile(android.net.Uri, int, android.os.Bundle?);
-    method public boolean requestPostMessageChannel(android.net.Uri!);
+    method public boolean requestPostMessageChannel(android.net.Uri);
     method public boolean setActionButton(android.graphics.Bitmap, String);
     method public boolean setSecondaryToolbarViews(android.widget.RemoteViews?, int[]?, android.app.PendingIntent?);
     method @Deprecated public boolean setToolbarItem(int, android.graphics.Bitmap, String);
@@ -244,18 +244,26 @@
 
 package androidx.browser.trusted {
 
+  public final class TrustedWebActivityIntent {
+    method public android.content.Intent getIntent();
+    method public void launchTrustedWebActivity(android.content.Context);
+  }
+
   public class TrustedWebActivityIntentBuilder {
     ctor public TrustedWebActivityIntentBuilder(android.net.Uri);
-    method public android.content.Intent build(androidx.browser.customtabs.CustomTabsSession);
+    method public androidx.browser.trusted.TrustedWebActivityIntent build(androidx.browser.customtabs.CustomTabsSession);
     method public androidx.browser.customtabs.CustomTabsIntent buildCustomTabsIntent();
     method public android.net.Uri getUrl();
     method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setAdditionalTrustedOrigins(java.util.List<java.lang.String!>);
     method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setColorScheme(int);
     method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setColorSchemeParams(int, androidx.browser.customtabs.CustomTabColorSchemeParams);
     method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setNavigationBarColor(@ColorInt int);
+    method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setShareParams(androidx.browser.trusted.sharing.ShareTarget, androidx.browser.trusted.sharing.ShareData);
     method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setSplashScreenParams(android.os.Bundle);
     method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setToolbarColor(@ColorInt int);
     field public static final String EXTRA_ADDITIONAL_TRUSTED_ORIGINS = "android.support.customtabs.extra.ADDITIONAL_TRUSTED_ORIGINS";
+    field public static final String EXTRA_SHARE_DATA = "androidx.browser.trusted.extra.SHARE_DATA";
+    field public static final String EXTRA_SHARE_TARGET = "androidx.browser.trusted.extra.SHARE_TARGET";
     field public static final String EXTRA_SPLASH_SCREEN_PARAMS = "androidx.browser.trusted.EXTRA_SPLASH_SCREEN_PARAMS";
   }
 
@@ -298,6 +306,58 @@
 
 }
 
+package androidx.browser.trusted.sharing {
+
+  public final class ShareData {
+    ctor public ShareData(String?, String?, java.util.List<android.net.Uri!>?);
+    method public static androidx.browser.trusted.sharing.ShareData fromBundle(android.os.Bundle);
+    method public android.os.Bundle toBundle();
+    field public static final String KEY_TEXT = "androidx.browser.trusted.sharing.KEY_TEXT";
+    field public static final String KEY_TITLE = "androidx.browser.trusted.sharing.KEY_TITLE";
+    field public static final String KEY_URIS = "androidx.browser.trusted.sharing.KEY_URIS";
+    field public final String? text;
+    field public final String? title;
+    field public final java.util.List<android.net.Uri!>? uris;
+  }
+
+  public final class ShareTarget {
+    ctor public ShareTarget(String, String?, String?, androidx.browser.trusted.sharing.ShareTarget.Params);
+    method public static androidx.browser.trusted.sharing.ShareTarget? fromBundle(android.os.Bundle);
+    method public android.os.Bundle toBundle();
+    field public static final String ENCODING_TYPE_MULTIPART = "multipart/form-data";
+    field public static final String ENCODING_TYPE_URL_ENCODED = "application/x-www-form-urlencoded";
+    field public static final String KEY_ACTION = "androidx.browser.trusted.sharing.KEY_ACTION";
+    field public static final String KEY_ENCTYPE = "androidx.browser.trusted.sharing.KEY_ENCTYPE";
+    field public static final String KEY_METHOD = "androidx.browser.trusted.sharing.KEY_METHOD";
+    field public static final String KEY_PARAMS = "androidx.browser.trusted.sharing.KEY_PARAMS";
+    field public static final String METHOD_GET = "GET";
+    field public static final String METHOD_POST = "POST";
+    field public final String action;
+    field public final String? encodingType;
+    field public final String? method;
+    field public final androidx.browser.trusted.sharing.ShareTarget.Params params;
+  }
+
+  public static class ShareTarget.FileFormField {
+    ctor public ShareTarget.FileFormField(String, java.util.List<java.lang.String!>);
+    field public static final String KEY_ACCEPTED_TYPES = "androidx.browser.trusted.sharing.KEY_ACCEPTED_TYPES";
+    field public static final String KEY_NAME = "androidx.browser.trusted.sharing.KEY_FILE_NAME";
+    field public final java.util.List<java.lang.String!> acceptedTypes;
+    field public final String name;
+  }
+
+  public static class ShareTarget.Params {
+    ctor public ShareTarget.Params(String?, String?, java.util.List<androidx.browser.trusted.sharing.ShareTarget.FileFormField!>?);
+    field public static final String KEY_FILES = "androidx.browser.trusted.sharing.KEY_FILES";
+    field public static final String KEY_TEXT = "androidx.browser.trusted.sharing.KEY_TEXT";
+    field public static final String KEY_TITLE = "androidx.browser.trusted.sharing.KEY_TITLE";
+    field public final java.util.List<androidx.browser.trusted.sharing.ShareTarget.FileFormField!>? files;
+    field public final String? text;
+    field public final String? title;
+  }
+
+}
+
 package androidx.browser.trusted.splashscreens {
 
   public final class SplashScreenParamKey {
diff --git a/preference/ktx/api/res-1.0.0.txt b/browser/api/res-1.2.0-alpha08.txt
similarity index 100%
copy from preference/ktx/api/res-1.0.0.txt
copy to browser/api/res-1.2.0-alpha08.txt
diff --git a/browser/api/restricted_1.2.0-alpha07.txt b/browser/api/restricted_1.2.0-alpha07.txt
index 9cdf40e..5edad73 100644
--- a/browser/api/restricted_1.2.0-alpha07.txt
+++ b/browser/api/restricted_1.2.0-alpha07.txt
@@ -213,7 +213,7 @@
 
   public final class CustomTabsSession {
     method @VisibleForTesting public static androidx.browser.customtabs.CustomTabsSession createMockSessionForTesting(android.content.ComponentName);
-    method public boolean mayLaunchUrl(android.net.Uri!, android.os.Bundle!, java.util.List<android.os.Bundle!>!);
+    method public boolean mayLaunchUrl(android.net.Uri, android.os.Bundle?, java.util.List<android.os.Bundle!>?);
     method @androidx.browser.customtabs.CustomTabsService.Result public int postMessage(String!, android.os.Bundle!);
     method public boolean receiveFile(android.net.Uri, @androidx.browser.customtabs.CustomTabsService.FilePurpose int, android.os.Bundle?);
     method public boolean requestPostMessageChannel(android.net.Uri!);
@@ -261,9 +261,14 @@
 package androidx.browser.trusted {
 
 
+  public final class TrustedWebActivityIntent {
+    method public android.content.Intent getIntent();
+    method public void launchTrustedWebActivity(android.content.Context);
+  }
+
   public class TrustedWebActivityIntentBuilder {
     ctor public TrustedWebActivityIntentBuilder(android.net.Uri);
-    method public android.content.Intent build(androidx.browser.customtabs.CustomTabsSession);
+    method public androidx.browser.trusted.TrustedWebActivityIntent build(androidx.browser.customtabs.CustomTabsSession);
     method public androidx.browser.customtabs.CustomTabsIntent buildCustomTabsIntent();
     method public android.net.Uri getUrl();
     method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setAdditionalTrustedOrigins(java.util.List<java.lang.String!>);
diff --git a/browser/api/restricted_1.2.0-alpha08.txt b/browser/api/restricted_1.2.0-alpha08.txt
new file mode 100644
index 0000000..ae6035ea
--- /dev/null
+++ b/browser/api/restricted_1.2.0-alpha08.txt
@@ -0,0 +1,395 @@
+// Signature format: 3.0
+package androidx.browser.browseractions {
+
+  @Deprecated public class BrowserActionItem {
+    ctor @Deprecated public BrowserActionItem(String, android.app.PendingIntent, @DrawableRes int);
+    ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public BrowserActionItem(String, android.app.PendingIntent, android.net.Uri);
+    ctor @Deprecated public BrowserActionItem(String, android.app.PendingIntent);
+    method @Deprecated public android.app.PendingIntent getAction();
+    method @Deprecated public int getIconId();
+    method @Deprecated public String getTitle();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class BrowserActionsFallbackMenuView extends android.widget.LinearLayout {
+    ctor public BrowserActionsFallbackMenuView(android.content.Context!, android.util.AttributeSet!);
+  }
+
+  @Deprecated public class BrowserActionsIntent {
+    method @Deprecated public static String? getCreatorPackageName(android.content.Intent);
+    method @Deprecated public android.content.Intent getIntent();
+    method @Deprecated public static String? getUntrustedCreatorPackageName(android.content.Intent);
+    method @Deprecated public static void launchIntent(android.content.Context!, android.content.Intent!);
+    method @Deprecated public static void openBrowserAction(android.content.Context!, android.net.Uri!);
+    method @Deprecated public static void openBrowserAction(android.content.Context!, android.net.Uri!, int, java.util.ArrayList<androidx.browser.browseractions.BrowserActionItem!>!, android.app.PendingIntent!);
+    method @Deprecated public static java.util.List<androidx.browser.browseractions.BrowserActionItem!>! parseBrowserActionItems(java.util.ArrayList<android.os.Bundle!>!);
+    field @Deprecated public static final String ACTION_BROWSER_ACTIONS_OPEN = "androidx.browser.browseractions.browser_action_open";
+    field @Deprecated public static final String EXTRA_APP_ID = "androidx.browser.browseractions.APP_ID";
+    field @Deprecated public static final String EXTRA_MENU_ITEMS = "androidx.browser.browseractions.extra.MENU_ITEMS";
+    field @Deprecated public static final String EXTRA_SELECTED_ACTION_PENDING_INTENT = "androidx.browser.browseractions.extra.SELECTED_ACTION_PENDING_INTENT";
+    field @Deprecated public static final String EXTRA_TYPE = "androidx.browser.browseractions.extra.TYPE";
+    field @Deprecated public static final int ITEM_COPY = 3; // 0x3
+    field @Deprecated public static final int ITEM_DOWNLOAD = 2; // 0x2
+    field @Deprecated public static final int ITEM_INVALID_ITEM = -1; // 0xffffffff
+    field @Deprecated public static final int ITEM_OPEN_IN_INCOGNITO = 1; // 0x1
+    field @Deprecated public static final int ITEM_OPEN_IN_NEW_TAB = 0; // 0x0
+    field @Deprecated public static final int ITEM_SHARE = 4; // 0x4
+    field @Deprecated public static final String KEY_ACTION = "androidx.browser.browseractions.ACTION";
+    field @Deprecated public static final String KEY_ICON_ID = "androidx.browser.browseractions.ICON_ID";
+    field @Deprecated public static final String KEY_TITLE = "androidx.browser.browseractions.TITLE";
+    field @Deprecated public static final int MAX_CUSTOM_ITEMS = 5; // 0x5
+    field @Deprecated public static final int URL_TYPE_AUDIO = 3; // 0x3
+    field @Deprecated public static final int URL_TYPE_FILE = 4; // 0x4
+    field @Deprecated public static final int URL_TYPE_IMAGE = 1; // 0x1
+    field @Deprecated public static final int URL_TYPE_NONE = 0; // 0x0
+    field @Deprecated public static final int URL_TYPE_PLUGIN = 5; // 0x5
+    field @Deprecated public static final int URL_TYPE_VIDEO = 2; // 0x2
+  }
+
+  @Deprecated @IntDef({androidx.browser.browseractions.BrowserActionsIntent.ITEM_INVALID_ITEM, androidx.browser.browseractions.BrowserActionsIntent.ITEM_OPEN_IN_NEW_TAB, androidx.browser.browseractions.BrowserActionsIntent.ITEM_OPEN_IN_INCOGNITO, androidx.browser.browseractions.BrowserActionsIntent.ITEM_DOWNLOAD, androidx.browser.browseractions.BrowserActionsIntent.ITEM_COPY, androidx.browser.browseractions.BrowserActionsIntent.ITEM_SHARE}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface BrowserActionsIntent.BrowserActionsItemId {
+  }
+
+  @Deprecated @IntDef({androidx.browser.browseractions.BrowserActionsIntent.URL_TYPE_NONE, androidx.browser.browseractions.BrowserActionsIntent.URL_TYPE_IMAGE, androidx.browser.browseractions.BrowserActionsIntent.URL_TYPE_VIDEO, androidx.browser.browseractions.BrowserActionsIntent.URL_TYPE_AUDIO, androidx.browser.browseractions.BrowserActionsIntent.URL_TYPE_FILE, androidx.browser.browseractions.BrowserActionsIntent.URL_TYPE_PLUGIN}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface BrowserActionsIntent.BrowserActionsUrlType {
+  }
+
+  @Deprecated public static final class BrowserActionsIntent.Builder {
+    ctor @Deprecated public BrowserActionsIntent.Builder(android.content.Context!, android.net.Uri!);
+    method @Deprecated public androidx.browser.browseractions.BrowserActionsIntent! build();
+    method @Deprecated public androidx.browser.browseractions.BrowserActionsIntent.Builder! setCustomItems(java.util.ArrayList<androidx.browser.browseractions.BrowserActionItem!>!);
+    method @Deprecated public androidx.browser.browseractions.BrowserActionsIntent.Builder! setCustomItems(androidx.browser.browseractions.BrowserActionItem!...);
+    method @Deprecated public androidx.browser.browseractions.BrowserActionsIntent.Builder! setOnItemSelectedAction(android.app.PendingIntent!);
+    method @Deprecated public androidx.browser.browseractions.BrowserActionsIntent.Builder! setUrlType(@androidx.browser.browseractions.BrowserActionsIntent.BrowserActionsUrlType int);
+  }
+
+
+}
+
+package androidx.browser.customtabs {
+
+  public final class CustomTabColorSchemeParams {
+    field @ColorInt public final Integer? navigationBarColor;
+    field @ColorInt public final Integer? secondaryToolbarColor;
+    field @ColorInt public final Integer? toolbarColor;
+  }
+
+  public static final class CustomTabColorSchemeParams.Builder {
+    ctor public CustomTabColorSchemeParams.Builder();
+    method public androidx.browser.customtabs.CustomTabColorSchemeParams build();
+    method public androidx.browser.customtabs.CustomTabColorSchemeParams.Builder setNavigationBarColor(@ColorInt int);
+    method public androidx.browser.customtabs.CustomTabColorSchemeParams.Builder setSecondaryToolbarColor(@ColorInt int);
+    method public androidx.browser.customtabs.CustomTabColorSchemeParams.Builder setToolbarColor(@ColorInt int);
+  }
+
+  public class CustomTabsCallback {
+    ctor public CustomTabsCallback();
+    method public void extraCallback(String!, android.os.Bundle!);
+    method public void onMessageChannelReady(android.os.Bundle!);
+    method public void onNavigationEvent(int, android.os.Bundle!);
+    method public void onPostMessage(String!, android.os.Bundle!);
+    method public void onRelationshipValidationResult(@androidx.browser.customtabs.CustomTabsService.Relation int, android.net.Uri!, boolean, android.os.Bundle!);
+    field public static final int NAVIGATION_ABORTED = 4; // 0x4
+    field public static final int NAVIGATION_FAILED = 3; // 0x3
+    field public static final int NAVIGATION_FINISHED = 2; // 0x2
+    field public static final int NAVIGATION_STARTED = 1; // 0x1
+    field public static final int TAB_HIDDEN = 6; // 0x6
+    field public static final int TAB_SHOWN = 5; // 0x5
+  }
+
+  public class CustomTabsClient {
+    method public static boolean bindCustomTabsService(android.content.Context, String?, androidx.browser.customtabs.CustomTabsServiceConnection);
+    method public static boolean connectAndInitialize(android.content.Context, String);
+    method public android.os.Bundle? extraCommand(String, android.os.Bundle?);
+    method public static String? getPackageName(android.content.Context, java.util.List<java.lang.String!>?);
+    method public static String? getPackageName(android.content.Context, java.util.List<java.lang.String!>?, boolean);
+    method public androidx.browser.customtabs.CustomTabsSession? newSession(androidx.browser.customtabs.CustomTabsCallback?);
+    method public androidx.browser.customtabs.CustomTabsSession? newSession(androidx.browser.customtabs.CustomTabsCallback?, int);
+    method public boolean warmup(long);
+  }
+
+  public final class CustomTabsIntent {
+    method public static androidx.browser.customtabs.CustomTabColorSchemeParams getColorSchemeParams(android.content.Intent, @androidx.browser.customtabs.CustomTabsIntent.ColorScheme int);
+    method public static int getMaxToolbarItems();
+    method public void launchUrl(android.content.Context!, android.net.Uri!);
+    method public static android.content.Intent! setAlwaysUseBrowserUI(android.content.Intent!);
+    method public static boolean shouldAlwaysUseBrowserUI(android.content.Intent!);
+    field public static final int COLOR_SCHEME_DARK = 2; // 0x2
+    field public static final int COLOR_SCHEME_LIGHT = 1; // 0x1
+    field public static final int COLOR_SCHEME_SYSTEM = 0; // 0x0
+    field public static final String EXTRA_ACTION_BUTTON_BUNDLE = "android.support.customtabs.extra.ACTION_BUTTON_BUNDLE";
+    field public static final String EXTRA_CLOSE_BUTTON_ICON = "android.support.customtabs.extra.CLOSE_BUTTON_ICON";
+    field public static final String EXTRA_COLOR_SCHEME = "androidx.browser.customtabs.extra.COLOR_SCHEME";
+    field public static final String EXTRA_COLOR_SCHEME_PARAMS = "androidx.browser.customtabs.extra.COLOR_SCHEME_PARAMS";
+    field public static final String EXTRA_DEFAULT_SHARE_MENU_ITEM = "android.support.customtabs.extra.SHARE_MENU_ITEM";
+    field public static final String EXTRA_ENABLE_INSTANT_APPS = "android.support.customtabs.extra.EXTRA_ENABLE_INSTANT_APPS";
+    field public static final String EXTRA_ENABLE_URLBAR_HIDING = "android.support.customtabs.extra.ENABLE_URLBAR_HIDING";
+    field public static final String EXTRA_EXIT_ANIMATION_BUNDLE = "android.support.customtabs.extra.EXIT_ANIMATION_BUNDLE";
+    field public static final String EXTRA_MENU_ITEMS = "android.support.customtabs.extra.MENU_ITEMS";
+    field public static final String EXTRA_NAVIGATION_BAR_COLOR = "androidx.browser.customtabs.extra.NAVIGATION_BAR_COLOR";
+    field public static final String EXTRA_REMOTEVIEWS = "android.support.customtabs.extra.EXTRA_REMOTEVIEWS";
+    field public static final String EXTRA_REMOTEVIEWS_CLICKED_ID = "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_CLICKED_ID";
+    field public static final String EXTRA_REMOTEVIEWS_PENDINGINTENT = "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_PENDINGINTENT";
+    field public static final String EXTRA_REMOTEVIEWS_VIEW_IDS = "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_VIEW_IDS";
+    field public static final String EXTRA_SECONDARY_TOOLBAR_COLOR = "android.support.customtabs.extra.SECONDARY_TOOLBAR_COLOR";
+    field public static final String EXTRA_SESSION = "android.support.customtabs.extra.SESSION";
+    field public static final String EXTRA_TINT_ACTION_BUTTON = "android.support.customtabs.extra.TINT_ACTION_BUTTON";
+    field public static final String EXTRA_TITLE_VISIBILITY_STATE = "android.support.customtabs.extra.TITLE_VISIBILITY";
+    field public static final String EXTRA_TOOLBAR_COLOR = "android.support.customtabs.extra.TOOLBAR_COLOR";
+    field public static final String EXTRA_TOOLBAR_ITEMS = "android.support.customtabs.extra.TOOLBAR_ITEMS";
+    field public static final String KEY_DESCRIPTION = "android.support.customtabs.customaction.DESCRIPTION";
+    field public static final String KEY_ICON = "android.support.customtabs.customaction.ICON";
+    field public static final String KEY_ID = "android.support.customtabs.customaction.ID";
+    field public static final String KEY_MENU_ITEM_TITLE = "android.support.customtabs.customaction.MENU_ITEM_TITLE";
+    field public static final String KEY_PENDING_INTENT = "android.support.customtabs.customaction.PENDING_INTENT";
+    field public static final int NO_TITLE = 0; // 0x0
+    field public static final int SHOW_PAGE_TITLE = 1; // 0x1
+    field public static final int TOOLBAR_ACTION_BUTTON_ID = 0; // 0x0
+    field public final android.content.Intent intent;
+    field public final android.os.Bundle? startAnimationBundle;
+  }
+
+  public static final class CustomTabsIntent.Builder {
+    ctor public CustomTabsIntent.Builder();
+    ctor public CustomTabsIntent.Builder(androidx.browser.customtabs.CustomTabsSession?);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder addDefaultShareMenuItem();
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder addMenuItem(String, android.app.PendingIntent);
+    method @Deprecated public androidx.browser.customtabs.CustomTabsIntent.Builder addToolbarItem(int, android.graphics.Bitmap, String, android.app.PendingIntent!) throws java.lang.IllegalStateException;
+    method public androidx.browser.customtabs.CustomTabsIntent build();
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder enableUrlBarHiding();
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setActionButton(android.graphics.Bitmap, String, android.app.PendingIntent, boolean);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setActionButton(android.graphics.Bitmap, String, android.app.PendingIntent);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setCloseButtonIcon(android.graphics.Bitmap);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setColorScheme(@androidx.browser.customtabs.CustomTabsIntent.ColorScheme int);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setColorSchemeParams(@androidx.browser.customtabs.CustomTabsIntent.ColorScheme int, androidx.browser.customtabs.CustomTabColorSchemeParams);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setExitAnimations(android.content.Context, @AnimRes int, @AnimRes int);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setInstantAppsEnabled(boolean);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setNavigationBarColor(@ColorInt int);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setSecondaryToolbarColor(@ColorInt int);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setSecondaryToolbarViews(android.widget.RemoteViews, int[]?, android.app.PendingIntent?);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setSession(androidx.browser.customtabs.CustomTabsSession);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setShowTitle(boolean);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setStartAnimations(android.content.Context, @AnimRes int, @AnimRes int);
+    method public androidx.browser.customtabs.CustomTabsIntent.Builder setToolbarColor(@ColorInt int);
+  }
+
+
+  public abstract class CustomTabsService extends android.app.Service {
+    ctor public CustomTabsService();
+    method protected boolean cleanUpSession(androidx.browser.customtabs.CustomTabsSessionToken!);
+    method protected abstract android.os.Bundle! extraCommand(String!, android.os.Bundle!);
+    method protected abstract boolean mayLaunchUrl(androidx.browser.customtabs.CustomTabsSessionToken!, android.net.Uri!, android.os.Bundle!, java.util.List<android.os.Bundle!>!);
+    method protected abstract boolean newSession(androidx.browser.customtabs.CustomTabsSessionToken!);
+    method public android.os.IBinder! onBind(android.content.Intent!);
+    method @androidx.browser.customtabs.CustomTabsService.Result protected abstract int postMessage(androidx.browser.customtabs.CustomTabsSessionToken!, String!, android.os.Bundle!);
+    method protected abstract boolean receiveFile(androidx.browser.customtabs.CustomTabsSessionToken, android.net.Uri, @androidx.browser.customtabs.CustomTabsService.FilePurpose int, android.os.Bundle?);
+    method protected abstract boolean requestPostMessageChannel(androidx.browser.customtabs.CustomTabsSessionToken!, android.net.Uri!);
+    method protected abstract boolean updateVisuals(androidx.browser.customtabs.CustomTabsSessionToken!, android.os.Bundle!);
+    method protected abstract boolean validateRelationship(androidx.browser.customtabs.CustomTabsSessionToken!, @androidx.browser.customtabs.CustomTabsService.Relation int, android.net.Uri!, android.os.Bundle!);
+    method protected abstract boolean warmup(long);
+    field public static final String ACTION_CUSTOM_TABS_CONNECTION = "android.support.customtabs.action.CustomTabsService";
+    field public static final String CATEGORY_COLOR_SCHEME_CUSTOMIZATION = "androidx.browser.customtabs.category.ColorSchemeCustomization";
+    field public static final String CATEGORY_NAVBAR_COLOR_CUSTOMIZATION = "androidx.browser.customtabs.category.NavBarColorCustomization";
+    field public static final int FILE_PURPOSE_TRUSTED_WEB_ACTIVITY_SPLASH_IMAGE = 1; // 0x1
+    field public static final String KEY_URL = "android.support.customtabs.otherurls.URL";
+    field public static final int RELATION_HANDLE_ALL_URLS = 2; // 0x2
+    field public static final int RELATION_USE_AS_ORIGIN = 1; // 0x1
+    field public static final int RESULT_FAILURE_DISALLOWED = -1; // 0xffffffff
+    field public static final int RESULT_FAILURE_MESSAGING_ERROR = -3; // 0xfffffffd
+    field public static final int RESULT_FAILURE_REMOTE_ERROR = -2; // 0xfffffffe
+    field public static final int RESULT_SUCCESS = 0; // 0x0
+    field public static final String TRUSTED_WEB_ACTIVITY_CATEGORY = "androidx.browser.trusted.category.TrustedWebActivities";
+  }
+
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({androidx.browser.customtabs.CustomTabsService.RELATION_USE_AS_ORIGIN, androidx.browser.customtabs.CustomTabsService.RELATION_HANDLE_ALL_URLS}) public static @interface CustomTabsService.Relation {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({androidx.browser.customtabs.CustomTabsService.RESULT_SUCCESS, androidx.browser.customtabs.CustomTabsService.RESULT_FAILURE_DISALLOWED, androidx.browser.customtabs.CustomTabsService.RESULT_FAILURE_REMOTE_ERROR, androidx.browser.customtabs.CustomTabsService.RESULT_FAILURE_MESSAGING_ERROR}) public static @interface CustomTabsService.Result {
+  }
+
+  public abstract class CustomTabsServiceConnection implements android.content.ServiceConnection {
+    ctor public CustomTabsServiceConnection();
+    method public abstract void onCustomTabsServiceConnected(android.content.ComponentName!, androidx.browser.customtabs.CustomTabsClient!);
+    method public final void onServiceConnected(android.content.ComponentName!, android.os.IBinder!);
+  }
+
+  public final class CustomTabsSession {
+    method @VisibleForTesting public static androidx.browser.customtabs.CustomTabsSession createMockSessionForTesting(android.content.ComponentName);
+    method public boolean mayLaunchUrl(android.net.Uri, android.os.Bundle?, java.util.List<android.os.Bundle!>?);
+    method @androidx.browser.customtabs.CustomTabsService.Result public int postMessage(String, android.os.Bundle?);
+    method public boolean receiveFile(android.net.Uri, @androidx.browser.customtabs.CustomTabsService.FilePurpose int, android.os.Bundle?);
+    method public boolean requestPostMessageChannel(android.net.Uri);
+    method public boolean setActionButton(android.graphics.Bitmap, String);
+    method public boolean setSecondaryToolbarViews(android.widget.RemoteViews?, int[]?, android.app.PendingIntent?);
+    method @Deprecated public boolean setToolbarItem(int, android.graphics.Bitmap, String);
+    method public boolean validateRelationship(@androidx.browser.customtabs.CustomTabsService.Relation int, android.net.Uri, android.os.Bundle?);
+  }
+
+
+  public class CustomTabsSessionToken {
+    method public static androidx.browser.customtabs.CustomTabsSessionToken createMockSessionTokenForTesting();
+    method public androidx.browser.customtabs.CustomTabsCallback? getCallback();
+    method public static androidx.browser.customtabs.CustomTabsSessionToken? getSessionTokenFromIntent(android.content.Intent);
+    method public boolean isAssociatedWith(androidx.browser.customtabs.CustomTabsSession);
+  }
+
+
+  public class PostMessageService extends android.app.Service {
+    ctor public PostMessageService();
+    method public android.os.IBinder! onBind(android.content.Intent!);
+  }
+
+  public abstract class PostMessageServiceConnection implements androidx.browser.customtabs.PostMessageBackend android.content.ServiceConnection {
+    ctor public PostMessageServiceConnection(androidx.browser.customtabs.CustomTabsSessionToken!);
+    method public boolean bindSessionToPostMessageService(android.content.Context!, String!);
+    method public final boolean notifyMessageChannelReady(android.os.Bundle!);
+    method public void onPostMessageServiceConnected();
+    method public void onPostMessageServiceDisconnected();
+    method public final void onServiceConnected(android.content.ComponentName!, android.os.IBinder!);
+    method public final void onServiceDisconnected(android.content.ComponentName!);
+    method public final boolean postMessage(String!, android.os.Bundle!);
+    method public void unbindFromContext(android.content.Context!);
+  }
+
+  public class TrustedWebUtils {
+    method @Deprecated public static void launchAsTrustedWebActivity(android.content.Context, androidx.browser.customtabs.CustomTabsIntent, android.net.Uri);
+    method public static boolean splashScreensAreSupported(android.content.Context, String, String);
+    method @WorkerThread public static boolean transferSplashImage(android.content.Context, java.io.File, String, String, androidx.browser.customtabs.CustomTabsSession);
+    field public static final String EXTRA_LAUNCH_AS_TRUSTED_WEB_ACTIVITY = "android.support.customtabs.extra.LAUNCH_AS_TRUSTED_WEB_ACTIVITY";
+  }
+
+}
+
+package androidx.browser.trusted {
+
+
+  public final class TrustedWebActivityIntent {
+    method public android.content.Intent getIntent();
+    method public void launchTrustedWebActivity(android.content.Context);
+  }
+
+  public class TrustedWebActivityIntentBuilder {
+    ctor public TrustedWebActivityIntentBuilder(android.net.Uri);
+    method public androidx.browser.trusted.TrustedWebActivityIntent build(androidx.browser.customtabs.CustomTabsSession);
+    method public androidx.browser.customtabs.CustomTabsIntent buildCustomTabsIntent();
+    method public android.net.Uri getUrl();
+    method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setAdditionalTrustedOrigins(java.util.List<java.lang.String!>);
+    method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setColorScheme(int);
+    method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setColorSchemeParams(int, androidx.browser.customtabs.CustomTabColorSchemeParams);
+    method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setNavigationBarColor(@ColorInt int);
+    method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setShareParams(androidx.browser.trusted.sharing.ShareTarget, androidx.browser.trusted.sharing.ShareData);
+    method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setSplashScreenParams(android.os.Bundle);
+    method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setToolbarColor(@ColorInt int);
+    field public static final String EXTRA_ADDITIONAL_TRUSTED_ORIGINS = "android.support.customtabs.extra.ADDITIONAL_TRUSTED_ORIGINS";
+    field public static final String EXTRA_SHARE_DATA = "androidx.browser.trusted.extra.SHARE_DATA";
+    field public static final String EXTRA_SHARE_TARGET = "androidx.browser.trusted.extra.SHARE_TARGET";
+    field public static final String EXTRA_SPLASH_SCREEN_PARAMS = "androidx.browser.trusted.EXTRA_SPLASH_SCREEN_PARAMS";
+  }
+
+  public class TrustedWebActivityService extends android.app.Service {
+    ctor public TrustedWebActivityService();
+    method public boolean areNotificationsEnabled(String);
+    method public void cancelNotification(String, int);
+    method public android.os.Bundle getSmallIconBitmap();
+    method public int getSmallIconId();
+    method public boolean notifyNotificationWithChannel(String, int, android.app.Notification, String);
+    method public final android.os.IBinder? onBind(android.content.Intent?);
+    method public final boolean onUnbind(android.content.Intent?);
+    method public static final void setVerifiedProvider(android.content.Context, String?);
+    field public static final String ACTION_TRUSTED_WEB_ACTIVITY_SERVICE = "android.support.customtabs.trusted.TRUSTED_WEB_ACTIVITY_SERVICE";
+    field public static final String KEY_SMALL_ICON_BITMAP = "android.support.customtabs.trusted.SMALL_ICON_BITMAP";
+    field public static final String META_DATA_NAME_SMALL_ICON = "android.support.customtabs.trusted.SMALL_ICON";
+    field public static final int SMALL_ICON_NOT_SET = -1; // 0xffffffff
+  }
+
+  public class TrustedWebActivityServiceConnectionManager {
+    ctor public TrustedWebActivityServiceConnectionManager(android.content.Context);
+    method @MainThread public boolean execute(android.net.Uri, String, androidx.browser.trusted.TrustedWebActivityServiceConnectionManager.ExecutionCallback);
+    method public static java.util.Set<java.lang.String!> getVerifiedPackages(android.content.Context, String);
+    method public static void registerClient(android.content.Context, String, String);
+    method @MainThread public boolean serviceExistsForScope(android.net.Uri, String);
+  }
+
+  public static interface TrustedWebActivityServiceConnectionManager.ExecutionCallback {
+    method public void onConnected(androidx.browser.trusted.TrustedWebActivityServiceWrapper?) throws android.os.RemoteException;
+  }
+
+  public class TrustedWebActivityServiceWrapper {
+    method public boolean areNotificationsEnabled(String);
+    method public void cancel(String, int);
+    method public android.content.ComponentName getComponentName();
+    method public android.graphics.Bitmap? getSmallIconBitmap();
+    method public int getSmallIconId();
+    method public boolean notify(String, int, android.app.Notification, String);
+  }
+
+}
+
+package androidx.browser.trusted.sharing {
+
+  public final class ShareData {
+    ctor public ShareData(String?, String?, java.util.List<android.net.Uri!>?);
+    method public static androidx.browser.trusted.sharing.ShareData fromBundle(android.os.Bundle);
+    method public android.os.Bundle toBundle();
+    field public static final String KEY_TEXT = "androidx.browser.trusted.sharing.KEY_TEXT";
+    field public static final String KEY_TITLE = "androidx.browser.trusted.sharing.KEY_TITLE";
+    field public static final String KEY_URIS = "androidx.browser.trusted.sharing.KEY_URIS";
+    field public final String? text;
+    field public final String? title;
+    field public final java.util.List<android.net.Uri!>? uris;
+  }
+
+  public final class ShareTarget {
+    ctor public ShareTarget(String, @androidx.browser.trusted.sharing.ShareTarget.RequestMethod String?, @androidx.browser.trusted.sharing.ShareTarget.EncodingType String?, androidx.browser.trusted.sharing.ShareTarget.Params);
+    method public static androidx.browser.trusted.sharing.ShareTarget? fromBundle(android.os.Bundle);
+    method public android.os.Bundle toBundle();
+    field public static final String ENCODING_TYPE_MULTIPART = "multipart/form-data";
+    field public static final String ENCODING_TYPE_URL_ENCODED = "application/x-www-form-urlencoded";
+    field public static final String KEY_ACTION = "androidx.browser.trusted.sharing.KEY_ACTION";
+    field public static final String KEY_ENCTYPE = "androidx.browser.trusted.sharing.KEY_ENCTYPE";
+    field public static final String KEY_METHOD = "androidx.browser.trusted.sharing.KEY_METHOD";
+    field public static final String KEY_PARAMS = "androidx.browser.trusted.sharing.KEY_PARAMS";
+    field public static final String METHOD_GET = "GET";
+    field public static final String METHOD_POST = "POST";
+    field public final String action;
+    field @androidx.browser.trusted.sharing.ShareTarget.EncodingType public final String? encodingType;
+    field @androidx.browser.trusted.sharing.ShareTarget.RequestMethod public final String? method;
+    field public final androidx.browser.trusted.sharing.ShareTarget.Params params;
+  }
+
+
+  public static class ShareTarget.FileFormField {
+    ctor public ShareTarget.FileFormField(String, java.util.List<java.lang.String!>);
+    field public static final String KEY_ACCEPTED_TYPES = "androidx.browser.trusted.sharing.KEY_ACCEPTED_TYPES";
+    field public static final String KEY_NAME = "androidx.browser.trusted.sharing.KEY_FILE_NAME";
+    field public final java.util.List<java.lang.String!> acceptedTypes;
+    field public final String name;
+  }
+
+  public static class ShareTarget.Params {
+    ctor public ShareTarget.Params(String?, String?, java.util.List<androidx.browser.trusted.sharing.ShareTarget.FileFormField!>?);
+    field public static final String KEY_FILES = "androidx.browser.trusted.sharing.KEY_FILES";
+    field public static final String KEY_TEXT = "androidx.browser.trusted.sharing.KEY_TEXT";
+    field public static final String KEY_TITLE = "androidx.browser.trusted.sharing.KEY_TITLE";
+    field public final java.util.List<androidx.browser.trusted.sharing.ShareTarget.FileFormField!>? files;
+    field public final String? text;
+    field public final String? title;
+  }
+
+
+}
+
+package androidx.browser.trusted.splashscreens {
+
+  public final class SplashScreenParamKey {
+    field public static final String BACKGROUND_COLOR = "androidx.browser.trusted.trusted.KEY_SPLASH_SCREEN_BACKGROUND_COLOR";
+    field public static final String FADE_OUT_DURATION_MS = "androidx.browser.trusted.KEY_SPLASH_SCREEN_FADE_OUT_DURATION";
+    field public static final String IMAGE_TRANSFORMATION_MATRIX = "androidx.browser.trusted.KEY_SPLASH_SCREEN_TRANSFORMATION_MATRIX";
+    field public static final String SCALE_TYPE = "androidx.browser.trusted.KEY_SPLASH_SCREEN_SCALE_TYPE";
+    field public static final String VERSION = "androidx.browser.trusted.KEY_SPLASH_SCREEN_VERSION";
+  }
+
+  public final class SplashScreenVersion {
+    field public static final String V1 = "androidx.browser.trusted.category.TrustedWebActivitySplashScreensV1";
+  }
+
+}
+
diff --git a/browser/api/restricted_current.txt b/browser/api/restricted_current.txt
index 9cdf40e..ae6035ea 100644
--- a/browser/api/restricted_current.txt
+++ b/browser/api/restricted_current.txt
@@ -213,10 +213,10 @@
 
   public final class CustomTabsSession {
     method @VisibleForTesting public static androidx.browser.customtabs.CustomTabsSession createMockSessionForTesting(android.content.ComponentName);
-    method public boolean mayLaunchUrl(android.net.Uri!, android.os.Bundle!, java.util.List<android.os.Bundle!>!);
-    method @androidx.browser.customtabs.CustomTabsService.Result public int postMessage(String!, android.os.Bundle!);
+    method public boolean mayLaunchUrl(android.net.Uri, android.os.Bundle?, java.util.List<android.os.Bundle!>?);
+    method @androidx.browser.customtabs.CustomTabsService.Result public int postMessage(String, android.os.Bundle?);
     method public boolean receiveFile(android.net.Uri, @androidx.browser.customtabs.CustomTabsService.FilePurpose int, android.os.Bundle?);
-    method public boolean requestPostMessageChannel(android.net.Uri!);
+    method public boolean requestPostMessageChannel(android.net.Uri);
     method public boolean setActionButton(android.graphics.Bitmap, String);
     method public boolean setSecondaryToolbarViews(android.widget.RemoteViews?, int[]?, android.app.PendingIntent?);
     method @Deprecated public boolean setToolbarItem(int, android.graphics.Bitmap, String);
@@ -261,18 +261,26 @@
 package androidx.browser.trusted {
 
 
+  public final class TrustedWebActivityIntent {
+    method public android.content.Intent getIntent();
+    method public void launchTrustedWebActivity(android.content.Context);
+  }
+
   public class TrustedWebActivityIntentBuilder {
     ctor public TrustedWebActivityIntentBuilder(android.net.Uri);
-    method public android.content.Intent build(androidx.browser.customtabs.CustomTabsSession);
+    method public androidx.browser.trusted.TrustedWebActivityIntent build(androidx.browser.customtabs.CustomTabsSession);
     method public androidx.browser.customtabs.CustomTabsIntent buildCustomTabsIntent();
     method public android.net.Uri getUrl();
     method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setAdditionalTrustedOrigins(java.util.List<java.lang.String!>);
     method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setColorScheme(int);
     method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setColorSchemeParams(int, androidx.browser.customtabs.CustomTabColorSchemeParams);
     method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setNavigationBarColor(@ColorInt int);
+    method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setShareParams(androidx.browser.trusted.sharing.ShareTarget, androidx.browser.trusted.sharing.ShareData);
     method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setSplashScreenParams(android.os.Bundle);
     method public androidx.browser.trusted.TrustedWebActivityIntentBuilder setToolbarColor(@ColorInt int);
     field public static final String EXTRA_ADDITIONAL_TRUSTED_ORIGINS = "android.support.customtabs.extra.ADDITIONAL_TRUSTED_ORIGINS";
+    field public static final String EXTRA_SHARE_DATA = "androidx.browser.trusted.extra.SHARE_DATA";
+    field public static final String EXTRA_SHARE_TARGET = "androidx.browser.trusted.extra.SHARE_TARGET";
     field public static final String EXTRA_SPLASH_SCREEN_PARAMS = "androidx.browser.trusted.EXTRA_SPLASH_SCREEN_PARAMS";
   }
 
@@ -315,6 +323,60 @@
 
 }
 
+package androidx.browser.trusted.sharing {
+
+  public final class ShareData {
+    ctor public ShareData(String?, String?, java.util.List<android.net.Uri!>?);
+    method public static androidx.browser.trusted.sharing.ShareData fromBundle(android.os.Bundle);
+    method public android.os.Bundle toBundle();
+    field public static final String KEY_TEXT = "androidx.browser.trusted.sharing.KEY_TEXT";
+    field public static final String KEY_TITLE = "androidx.browser.trusted.sharing.KEY_TITLE";
+    field public static final String KEY_URIS = "androidx.browser.trusted.sharing.KEY_URIS";
+    field public final String? text;
+    field public final String? title;
+    field public final java.util.List<android.net.Uri!>? uris;
+  }
+
+  public final class ShareTarget {
+    ctor public ShareTarget(String, @androidx.browser.trusted.sharing.ShareTarget.RequestMethod String?, @androidx.browser.trusted.sharing.ShareTarget.EncodingType String?, androidx.browser.trusted.sharing.ShareTarget.Params);
+    method public static androidx.browser.trusted.sharing.ShareTarget? fromBundle(android.os.Bundle);
+    method public android.os.Bundle toBundle();
+    field public static final String ENCODING_TYPE_MULTIPART = "multipart/form-data";
+    field public static final String ENCODING_TYPE_URL_ENCODED = "application/x-www-form-urlencoded";
+    field public static final String KEY_ACTION = "androidx.browser.trusted.sharing.KEY_ACTION";
+    field public static final String KEY_ENCTYPE = "androidx.browser.trusted.sharing.KEY_ENCTYPE";
+    field public static final String KEY_METHOD = "androidx.browser.trusted.sharing.KEY_METHOD";
+    field public static final String KEY_PARAMS = "androidx.browser.trusted.sharing.KEY_PARAMS";
+    field public static final String METHOD_GET = "GET";
+    field public static final String METHOD_POST = "POST";
+    field public final String action;
+    field @androidx.browser.trusted.sharing.ShareTarget.EncodingType public final String? encodingType;
+    field @androidx.browser.trusted.sharing.ShareTarget.RequestMethod public final String? method;
+    field public final androidx.browser.trusted.sharing.ShareTarget.Params params;
+  }
+
+
+  public static class ShareTarget.FileFormField {
+    ctor public ShareTarget.FileFormField(String, java.util.List<java.lang.String!>);
+    field public static final String KEY_ACCEPTED_TYPES = "androidx.browser.trusted.sharing.KEY_ACCEPTED_TYPES";
+    field public static final String KEY_NAME = "androidx.browser.trusted.sharing.KEY_FILE_NAME";
+    field public final java.util.List<java.lang.String!> acceptedTypes;
+    field public final String name;
+  }
+
+  public static class ShareTarget.Params {
+    ctor public ShareTarget.Params(String?, String?, java.util.List<androidx.browser.trusted.sharing.ShareTarget.FileFormField!>?);
+    field public static final String KEY_FILES = "androidx.browser.trusted.sharing.KEY_FILES";
+    field public static final String KEY_TEXT = "androidx.browser.trusted.sharing.KEY_TEXT";
+    field public static final String KEY_TITLE = "androidx.browser.trusted.sharing.KEY_TITLE";
+    field public final java.util.List<androidx.browser.trusted.sharing.ShareTarget.FileFormField!>? files;
+    field public final String? text;
+    field public final String? title;
+  }
+
+
+}
+
 package androidx.browser.trusted.splashscreens {
 
   public final class SplashScreenParamKey {
diff --git a/browser/src/main/java/androidx/browser/customtabs/CustomTabsClient.java b/browser/src/main/java/androidx/browser/customtabs/CustomTabsClient.java
index 8e41774..b52bbb3 100644
--- a/browser/src/main/java/androidx/browser/customtabs/CustomTabsClient.java
+++ b/browser/src/main/java/androidx/browser/customtabs/CustomTabsClient.java
@@ -239,10 +239,19 @@
     private @Nullable CustomTabsSession newSessionInternal(final CustomTabsCallback callback,
                 @Nullable PendingIntent sessionId) {
         ICustomTabsCallback.Stub wrapper = createCallbackWrapper(callback);
-        Bundle extras = new Bundle();
-        if (sessionId != null) extras.putParcelable(CustomTabsIntent.EXTRA_SESSION_ID, sessionId);
+
         try {
-            if (!mService.newSessionWithExtras(wrapper, extras)) return null;
+            boolean success;
+
+            if (sessionId != null) {
+                Bundle extras = new Bundle();
+                extras.putParcelable(CustomTabsIntent.EXTRA_SESSION_ID, sessionId);
+                success = mService.newSessionWithExtras(wrapper, extras);
+            } else {
+                success = mService.newSession(wrapper);
+            }
+
+            if (!success) return null;
         } catch (RemoteException e) {
             return null;
         }
diff --git a/browser/src/main/java/androidx/browser/customtabs/CustomTabsService.java b/browser/src/main/java/androidx/browser/customtabs/CustomTabsService.java
index 5212a28..dbb41ab 100644
--- a/browser/src/main/java/androidx/browser/customtabs/CustomTabsService.java
+++ b/browser/src/main/java/androidx/browser/customtabs/CustomTabsService.java
@@ -182,8 +182,8 @@
         }
 
         @Override
-        public boolean mayLaunchUrl(ICustomTabsCallback callback, Uri url,
-                Bundle extras, List<Bundle> otherLikelyBundles) {
+        public boolean mayLaunchUrl(@Nullable ICustomTabsCallback callback, @NonNull Uri url,
+                @Nullable Bundle extras, @Nullable List<Bundle> otherLikelyBundles) {
             return CustomTabsService.this.mayLaunchUrl(
                     new CustomTabsSessionToken(callback, getSessionIdFromBundle(extras)),
                     url, extras, otherLikelyBundles);
diff --git a/browser/src/main/java/androidx/browser/customtabs/CustomTabsSession.java b/browser/src/main/java/androidx/browser/customtabs/CustomTabsSession.java
index 2746f1b..e9ff667 100644
--- a/browser/src/main/java/androidx/browser/customtabs/CustomTabsSession.java
+++ b/browser/src/main/java/androidx/browser/customtabs/CustomTabsSession.java
@@ -98,8 +98,9 @@
      *                           {@link Bundle#putParcelable(String, android.os.Parcelable)}.
      * @return                   true for success.
      */
-    public boolean mayLaunchUrl(Uri url, Bundle extras, List<Bundle> otherLikelyBundles) {
-        addIdToBundle(extras);
+    public boolean mayLaunchUrl(@NonNull Uri url, @Nullable Bundle extras,
+            @Nullable List<Bundle> otherLikelyBundles) {
+        extras = createBundleWithId(extras);
         try {
             return mService.mayLaunchUrl(mCallback, url, extras, otherLikelyBundles);
         } catch (RemoteException e) {
@@ -190,7 +191,7 @@
      *         here doesn't mean an origin has already been assigned as the validation is
      *         asynchronous.
      */
-    public boolean requestPostMessageChannel(Uri postMessageOrigin) {
+    public boolean requestPostMessageChannel(@NonNull Uri postMessageOrigin) {
         Bundle extras = new Bundle();
         addIdToBundle(extras);
         try {
@@ -214,8 +215,8 @@
      *        {@link CustomTabsService#RESULT_SUCCESS} if successful.
      */
     @Result
-    public int postMessage(String message, Bundle extras) {
-        addIdToBundle(extras);
+    public int postMessage(@NonNull String message, @Nullable Bundle extras) {
+        extras = createBundleWithId(extras);
         synchronized (mLock) {
             try {
                 return mService.postMessage(mCallback, message, extras);
@@ -251,10 +252,7 @@
                 || relation > CustomTabsService.RELATION_HANDLE_ALL_URLS) {
             return false;
         }
-        if (extras == null) {
-            extras = new Bundle();
-        }
-        addIdToBundle(extras);
+        extras = createBundleWithId(extras);
         try {
             return mService.validateRelationship(mCallback, relation, origin, extras);
         } catch (RemoteException e) {
@@ -280,10 +278,7 @@
      */
     public boolean receiveFile(@NonNull Uri uri, @CustomTabsService.FilePurpose int purpose,
             @Nullable Bundle extras) {
-        if (extras == null) {
-            extras = new Bundle();
-        }
-        addIdToBundle(extras);
+        extras = createBundleWithId(extras);
         try {
             return mService.receiveFile(mCallback, uri, purpose, extras);
         } catch (RemoteException e) {
@@ -291,6 +286,13 @@
         }
     }
 
+    private Bundle createBundleWithId(@Nullable Bundle bundle) {
+        Bundle bundleWithId = new Bundle();
+        if (bundle != null) bundleWithId.putAll(bundle);
+        addIdToBundle(bundleWithId);
+        return bundleWithId;
+    }
+
     private void addIdToBundle(Bundle bundle) {
         if (mId != null) bundle.putParcelable(CustomTabsIntent.EXTRA_SESSION_ID, mId);
     }
diff --git a/browser/src/main/java/androidx/browser/trusted/TrustedWebActivityIntent.java b/browser/src/main/java/androidx/browser/trusted/TrustedWebActivityIntent.java
new file mode 100644
index 0000000..3f29c2b
--- /dev/null
+++ b/browser/src/main/java/androidx/browser/trusted/TrustedWebActivityIntent.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2019 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.browser.trusted;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+
+import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
+
+import java.util.List;
+
+/**
+ * Holds an {@link Intent} and other data necessary to start a Trusted Web Activity.
+ */
+public final class TrustedWebActivityIntent {
+    @NonNull
+    private final Intent mIntent;
+
+    @NonNull
+    private final List<Uri> mSharedFileUris;
+
+    TrustedWebActivityIntent(@NonNull Intent intent, @NonNull List<Uri> sharedFileUris) {
+        mIntent = intent;
+        mSharedFileUris = sharedFileUris;
+    }
+
+    /**
+     * Launches a Trusted Web Activity.
+     */
+    public void launchTrustedWebActivity(@NonNull Context context) {
+        grantUriPermissionToProvider(context);
+        ContextCompat.startActivity(context, mIntent, null);
+    }
+
+    private void grantUriPermissionToProvider(Context context) {
+        for (Uri uri : mSharedFileUris) {
+            context.grantUriPermission(mIntent.getPackage(), uri,
+                    Intent.FLAG_GRANT_READ_URI_PERMISSION);
+        }
+    }
+
+    /**
+     * Returns the held {@link Intent}. For launching a Trusted Web Activity prefer using
+     * {@link #launchTrustedWebActivity}.
+     */
+    @NonNull
+    public Intent getIntent() {
+        return mIntent;
+    }
+}
diff --git a/browser/src/main/java/androidx/browser/trusted/TrustedWebActivityIntentBuilder.java b/browser/src/main/java/androidx/browser/trusted/TrustedWebActivityIntentBuilder.java
index b87fea5..1364512 100644
--- a/browser/src/main/java/androidx/browser/trusted/TrustedWebActivityIntentBuilder.java
+++ b/browser/src/main/java/androidx/browser/trusted/TrustedWebActivityIntentBuilder.java
@@ -28,14 +28,17 @@
 import androidx.browser.customtabs.CustomTabsIntent;
 import androidx.browser.customtabs.CustomTabsSession;
 import androidx.browser.customtabs.TrustedWebUtils;
+import androidx.browser.trusted.sharing.ShareData;
+import androidx.browser.trusted.sharing.ShareTarget;
 import androidx.browser.trusted.splashscreens.SplashScreenParamKey;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 /**
- * Constructs an intent to start a Trusted Web Activity (see {@link TrustedWebUtils} for more
- * details).
+ * Constructs instances of {@link TrustedWebActivityIntent} that can be used to start Trusted Web
+ * Activities (see {@link TrustedWebUtils} for more details).
  */
 public class TrustedWebActivityIntentBuilder {
     /**
@@ -60,12 +63,21 @@
     public static final String EXTRA_ADDITIONAL_TRUSTED_ORIGINS =
             "android.support.customtabs.extra.ADDITIONAL_TRUSTED_ORIGINS";
 
+    /** Extra for the share target, see {@link #setShareParams}. */
+    public static final String EXTRA_SHARE_TARGET = "androidx.browser.trusted.extra.SHARE_TARGET";
+
+    /** Extra for the share data, see {@link #setShareParams}. */
+    public static final String EXTRA_SHARE_DATA = "androidx.browser.trusted.extra.SHARE_DATA";
+
     @NonNull private final Uri mUri;
     @NonNull private final CustomTabsIntent.Builder mIntentBuilder = new CustomTabsIntent.Builder();
 
     @Nullable private List<String> mAdditionalTrustedOrigins;
     @Nullable private Bundle mSplashScreenParams;
 
+    @Nullable private ShareData mShareData;
+    @Nullable private ShareTarget mShareTarget;
+
     /**
      * Creates a Builder given the required parameters.
      * @param uri The web page to launch as Trusted Web Activity.
@@ -165,12 +177,27 @@
     }
 
     /**
-     * Builds the Intent.
+     * Sets the parameters for delivering data to a Web Share Target via a Trusted Web Activity.
+     *
+     * @param shareTarget A {@link ShareTarget} object describing the Web Share Target.
+     * @param shareData A {@link ShareData} object containing the data to be sent to the Web Share
+     * Target.
+     */
+    @NonNull
+    public TrustedWebActivityIntentBuilder setShareParams(@NonNull ShareTarget shareTarget,
+            @NonNull ShareData shareData) {
+        mShareTarget = shareTarget;
+        mShareData = shareData;
+        return this;
+    }
+
+    /**
+     * Builds an instance of {@link TrustedWebActivityIntent].
      *
      * @param session The {@link CustomTabsSession} to use for launching a Trusted Web Activity.
      */
     @NonNull
-    public Intent build(@NonNull CustomTabsSession session) {
+    public TrustedWebActivityIntent build(@NonNull CustomTabsSession session) {
         if (session == null) {
             throw new NullPointerException("CustomTabsSession is required for launching a TWA");
         }
@@ -187,7 +214,15 @@
         if (mSplashScreenParams != null) {
             intent.putExtra(EXTRA_SPLASH_SCREEN_PARAMS, mSplashScreenParams);
         }
-        return intent;
+        List<Uri> sharedUris = Collections.emptyList();
+        if (mShareTarget != null && mShareData != null) {
+            intent.putExtra(EXTRA_SHARE_TARGET, mShareTarget.toBundle());
+            intent.putExtra(EXTRA_SHARE_DATA, mShareData.toBundle());
+            if (mShareData.uris != null) {
+                sharedUris = mShareData.uris;
+            }
+        }
+        return new TrustedWebActivityIntent(intent, sharedUris);
     }
 
     /**
diff --git a/browser/src/main/java/androidx/browser/trusted/sharing/ShareData.java b/browser/src/main/java/androidx/browser/trusted/sharing/ShareData.java
new file mode 100644
index 0000000..c74ab4c
--- /dev/null
+++ b/browser/src/main/java/androidx/browser/trusted/sharing/ShareData.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2019 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.browser.trusted.sharing;
+
+import android.net.Uri;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Contains data to be delivered to a Web Share Target via a Trusted Web Activity.
+ * See {@link androidx.browser.trusted.TrustedWebActivityIntentBuilder#setShareParams}.
+ */
+public final class ShareData {
+    /** Bundle key for {@link #title}. */
+    public static final String KEY_TITLE = "androidx.browser.trusted.sharing.KEY_TITLE";
+
+    /** Bundle key for {@link #text}. */
+    public static final String KEY_TEXT = "androidx.browser.trusted.sharing.KEY_TEXT";
+
+    /** Bundle key for {@link #uris}. */
+    public static final String KEY_URIS = "androidx.browser.trusted.sharing.KEY_URIS";
+
+    /** Title of the shared message. */
+    @Nullable
+    public final String title;
+
+    /** Text of the shared message. */
+    @Nullable
+    public final String text;
+
+    /** URIs of files to be shared. */
+    @Nullable
+    public final List<Uri> uris;
+
+    /** Constructor. */
+    public ShareData(@Nullable String title, @Nullable String text, @Nullable List<Uri> uris) {
+        this.title = title;
+        this.text = text;
+        this.uris = uris;
+    }
+
+    /** Packs the object into a {@link Bundle} */
+    @NonNull
+    public Bundle toBundle() {
+        Bundle bundle = new Bundle();
+        bundle.putString(KEY_TITLE, title);
+        bundle.putString(KEY_TEXT, text);
+        if (uris != null) {
+            bundle.putParcelableArrayList(KEY_URIS, new ArrayList<>(uris));
+        }
+        return bundle;
+    }
+
+    /** Unpacks the object from a {@link Bundle}. */
+    @NonNull
+    public static ShareData fromBundle(@NonNull Bundle bundle) {
+        return new ShareData(bundle.getString(KEY_TITLE),
+                bundle.getString(KEY_TEXT),
+                bundle.getParcelableArrayList(KEY_URIS));
+    }
+}
diff --git a/browser/src/main/java/androidx/browser/trusted/sharing/ShareTarget.java b/browser/src/main/java/androidx/browser/trusted/sharing/ShareTarget.java
new file mode 100644
index 0000000..acc05ff
--- /dev/null
+++ b/browser/src/main/java/androidx/browser/trusted/sharing/ShareTarget.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright 2019 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.browser.trusted.sharing;
+
+import android.annotation.SuppressLint;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.annotation.StringDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Describes a Web Share Target associated with a Trusted Web Activity.
+ *
+ * The structure of a ShareTarget object follows the specification [1] of the "share_target" object
+ * within web manifest json, with the following exceptions:
+ * - The "action" field specifies the full URL of the Share Target, and not only the path.
+ * - There is no "url" field in the "params" object, since urls are not supplied separately from
+ * text in Android's ACTION_SEND and ACTION_SEND_MULTIPLE intents.
+ *
+ * [1] https://wicg.github.io/web-share-target/level-2/
+ */
+public final class ShareTarget  {
+
+    /** Bundle key for {@link #action}. */
+    @SuppressLint("IntentName")
+    public static final String KEY_ACTION = "androidx.browser.trusted.sharing.KEY_ACTION";
+
+    /** Bundle key for {@link #method}. */
+    public static final String KEY_METHOD = "androidx.browser.trusted.sharing.KEY_METHOD";
+
+    /** Bundle key for {@link #encodingType}. */
+    public static final String KEY_ENCTYPE = "androidx.browser.trusted.sharing.KEY_ENCTYPE";
+
+    /** Bundle key for {@link #params}. */
+    public static final String KEY_PARAMS = "androidx.browser.trusted.sharing.KEY_PARAMS";
+
+    /** @hide */
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @StringDef({METHOD_GET, METHOD_POST})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RequestMethod {}
+
+    /** See {@link #method}. */
+    public static final String METHOD_GET = "GET";
+
+    /** See {@link #method}. */
+    public static final String METHOD_POST = "POST";
+
+    /** @hide */
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @StringDef({ENCODING_TYPE_URL_ENCODED, ENCODING_TYPE_MULTIPART})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EncodingType {}
+
+    /** See {@link #encodingType} */
+    public static final String ENCODING_TYPE_URL_ENCODED = "application/x-www-form-urlencoded";
+
+    /** See {@link #encodingType} */
+    public static final String ENCODING_TYPE_MULTIPART = "multipart/form-data";
+
+    /**
+     * URL of the Web Share Target. Must belong to an origin associated with the Trusted Web
+     * Activity. For example, assuming the origin is "https://mypwa.com", the action could be
+     * "https://mypwa.com/share.html".
+     */
+    @NonNull
+    public final String action;
+
+    /**
+     * HTTP request method for the Web Share Target. Must be {@link #METHOD_GET} or
+     * {@link #METHOD_POST}. Default is {@link #METHOD_GET}.
+     */
+    @Nullable
+    @RequestMethod
+    public final String method;
+
+    /**
+     * Specifies how the shared data should be encoded in the body of a POST request. Must be
+     * {@link #ENCODING_TYPE_MULTIPART} or {@link #ENCODING_TYPE_URL_ENCODED}. Default is
+     * {@link #ENCODING_TYPE_URL_ENCODED}.
+     */
+    @Nullable
+    @EncodingType
+    public final String encodingType;
+
+    /**
+     * Contains the parameter names, see {@link Params}.
+     */
+    @NonNull
+    public final Params params;
+
+    /** Constructor, see field descriptions above. */
+    public ShareTarget(@NonNull String action, @Nullable @RequestMethod String method,
+            @Nullable @EncodingType String encodingType, @NonNull Params params) {
+        this.action = action;
+        this.method = method;
+        this.encodingType = encodingType;
+        this.params = params;
+    }
+
+    /** Packs the object into a {@link Bundle}. */
+    @NonNull
+    public Bundle toBundle() {
+        Bundle bundle = new Bundle();
+        bundle.putString(KEY_ACTION, action);
+        bundle.putString(KEY_METHOD, method);
+        bundle.putString(KEY_ENCTYPE, encodingType);
+        bundle.putBundle(KEY_PARAMS, params.toBundle());
+        return bundle;
+    }
+
+    /** Unpacks the object from a {@link Bundle}. */
+    @Nullable
+    public static ShareTarget fromBundle(@NonNull Bundle bundle) {
+        String action = bundle.getString(KEY_ACTION);
+        String method = bundle.getString(KEY_METHOD);
+        String encType = bundle.getString(KEY_ENCTYPE);
+        Params params = Params.fromBundle(bundle.getBundle(KEY_PARAMS));
+        if (action == null || params == null) {
+            return null;
+        }
+        return new ShareTarget(action, method, encType, params);
+    }
+
+    /** Contains parameter names to be used for the data being shared. */
+    public static class Params {
+        /** Bundle key for {@link #title}. */
+        public static final String KEY_TITLE = "androidx.browser.trusted.sharing.KEY_TITLE";
+
+        /** Bundle key for {@link #text}. */
+        public static final String KEY_TEXT = "androidx.browser.trusted.sharing.KEY_TEXT";
+
+        /** Bundle key for {@link #files}. */
+        public static final String KEY_FILES = "androidx.browser.trusted.sharing.KEY_FILES";
+
+        /** The name of the query parameter used for the title of the message being shared. */
+        @Nullable
+        public final String title;
+
+        /** The name of the query parameter used for the body of the message being shared. */
+        @Nullable
+        public final String text;
+
+        /**
+         * Defines form fields for the files being shared, see {@link FileFormField}.
+         * Web Share Target can have multiple form fields associated with different MIME types.
+         * If a file passes the MIME type filters of several {@link FileFormField}s,
+         * the one that has the lowest index in this list is picked; see [1] for details.
+         *
+         * [1] https://wicg.github.io/web-share-target/level-2/#launching-the-web-share-target
+         */
+        @Nullable
+        public final List<FileFormField> files;
+
+        /** Constructor, see field descriptions above. */
+        public Params(@Nullable String title, @Nullable String text,
+                @Nullable List<FileFormField> files) {
+            this.title = title;
+            this.text = text;
+            this.files = files;
+        }
+
+        @SuppressWarnings("WeakerAccess") /* synthetic access */
+        @NonNull
+        Bundle toBundle() {
+            Bundle bundle = new Bundle();
+            bundle.putString(KEY_TITLE, title);
+            bundle.putString(KEY_TEXT, text);
+            if (files != null) {
+                ArrayList<Bundle> fileBundles = new ArrayList<>();
+                for (FileFormField file : files) {
+                    fileBundles.add(file.toBundle());
+                }
+                bundle.putParcelableArrayList(KEY_FILES, fileBundles);
+            }
+
+            return bundle;
+        }
+
+        @SuppressWarnings("WeakerAccess") /* synthetic access */
+        @Nullable
+        static Params fromBundle(@Nullable Bundle bundle) {
+            if (bundle == null) {
+                return null;
+            }
+            List<FileFormField> files = null;
+            List<Bundle> fileBundles = bundle.getParcelableArrayList(KEY_FILES);
+            if (fileBundles != null) {
+                files = new ArrayList<>();
+                for (Bundle fileBundle : fileBundles) {
+                    files.add(FileFormField.fromBundle(fileBundle));
+                }
+            }
+            return new Params(bundle.getString(KEY_TITLE), bundle.getString(KEY_TEXT),
+                    files);
+        }
+    }
+
+    /** Defines a form field for sharing files. */
+    public static class FileFormField {
+        /** Bundle key for {@link #name}. */
+        public static final String KEY_NAME = "androidx.browser.trusted.sharing.KEY_FILE_NAME";
+
+        /** Bundle key for {@link #acceptedTypes}. */
+        public static final String KEY_ACCEPTED_TYPES =
+                "androidx.browser.trusted.sharing.KEY_ACCEPTED_TYPES";
+
+        /** Name of the form field. */
+        @NonNull
+        public final String name;
+
+        /**
+         * List of MIME types or file extensions to be sent in this field. The MIME type matching
+         * algorithm is specified by
+         * https://wicg.github.io/web-share-target/level-2/#determining-if-a-file-is-accepted.
+         */
+        @NonNull
+        public final List<String> acceptedTypes;
+
+        /** Constructor, see field descriptions above. */
+        public FileFormField(@NonNull String name, @NonNull List<String> acceptedTypes) {
+            this.name = name;
+            this.acceptedTypes = acceptedTypes;
+        }
+
+        @SuppressWarnings("WeakerAccess") /* synthetic access */
+        @NonNull
+        Bundle toBundle() {
+            Bundle bundle = new Bundle();
+            bundle.putString(KEY_NAME, name);
+            bundle.putStringArrayList(KEY_ACCEPTED_TYPES, new ArrayList<>(acceptedTypes));
+            return bundle;
+        }
+
+        @SuppressWarnings("WeakerAccess") /* synthetic access */
+        @Nullable
+        static FileFormField fromBundle(@Nullable Bundle bundle) {
+            if (bundle == null) {
+                return null;
+            }
+            String name = bundle.getString(KEY_NAME);
+            ArrayList<String> acceptedTypes = bundle.getStringArrayList(KEY_ACCEPTED_TYPES);
+            if (name == null || acceptedTypes == null) {
+                return null;
+            }
+            return new FileFormField(name, acceptedTypes);
+        }
+    }
+}
diff --git a/browser/src/main/res/values-af/strings.xml b/browser/src/main/res/values-af/strings.xml
new file mode 100644
index 0000000..e59ccd1
--- /dev/null
+++ b/browser/src/main/res/values-af/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Maak in blaaier oop"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopieer skakel"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Deel skakel"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Skakel is na knipbord gekopieer"</string>
+</resources>
diff --git a/browser/src/main/res/values-am/strings.xml b/browser/src/main/res/values-am/strings.xml
new file mode 100644
index 0000000..d5c7fb4
--- /dev/null
+++ b/browser/src/main/res/values-am/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"በአሳሽ ውስጥ ክፈት"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"አገናኝ ቅዳ"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"አገናኝ አጋራ"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"አገናኝ ወደ ቅንጥብ ሰሌዳ ተቀድቷል"</string>
+</resources>
diff --git a/browser/src/main/res/values-ar/strings.xml b/browser/src/main/res/values-ar/strings.xml
new file mode 100644
index 0000000..649645f
--- /dev/null
+++ b/browser/src/main/res/values-ar/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"فتح في المتصفح"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"نسخ الرابط"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"مشاركة الرابط"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"تم نسخ الرابط إلى الحافظة."</string>
+</resources>
diff --git a/browser/src/main/res/values-as/strings.xml b/browser/src/main/res/values-as/strings.xml
new file mode 100644
index 0000000..23b6bca
--- /dev/null
+++ b/browser/src/main/res/values-as/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"ব্ৰাউজাৰত খোলক"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"লিংক প্ৰতিলিপি কৰক"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"লিংক শ্বেয়াৰ কৰক"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"লিংক ক্লিপব’ৰ্ডত প্ৰতিলিপি কৰা হ’ল"</string>
+</resources>
diff --git a/browser/src/main/res/values-az/strings.xml b/browser/src/main/res/values-az/strings.xml
new file mode 100644
index 0000000..e3d1ae5
--- /dev/null
+++ b/browser/src/main/res/values-az/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Brauzerdə açın"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Linki kopyalayın"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Linki paylaşın"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Link buferə kopyalandı"</string>
+</resources>
diff --git a/browser/src/main/res/values-b+sr+Latn/strings.xml b/browser/src/main/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..1af7e1e
--- /dev/null
+++ b/browser/src/main/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Otvori u pregledaču"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopiraj link"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Deli link"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Link je kopiran u privremenu memoriju"</string>
+</resources>
diff --git a/browser/src/main/res/values-be/strings.xml b/browser/src/main/res/values-be/strings.xml
new file mode 100644
index 0000000..087969c
--- /dev/null
+++ b/browser/src/main/res/values-be/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Адкрыць у браўзеры"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Скапіраваць спасылку"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Абагуліць спасылку"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Спасылка скапіравана ў буфер абмену"</string>
+</resources>
diff --git a/browser/src/main/res/values-bg/strings.xml b/browser/src/main/res/values-bg/strings.xml
new file mode 100644
index 0000000..2b0eb5f
--- /dev/null
+++ b/browser/src/main/res/values-bg/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Отваряне в браузър"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Копиране на връзката"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Споделяне на връзката"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Връзката е копирана в буферната памет"</string>
+</resources>
diff --git a/browser/src/main/res/values-bn/strings.xml b/browser/src/main/res/values-bn/strings.xml
new file mode 100644
index 0000000..5644768
--- /dev/null
+++ b/browser/src/main/res/values-bn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"ব্রাউজারে খুলুন"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"লিঙ্ক কপি করুন"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"লিঙ্ক শেয়ার করুন"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"লিঙ্ক ক্লিপবোর্ডে কপি করা হয়েছে"</string>
+</resources>
diff --git a/browser/src/main/res/values-bs/strings.xml b/browser/src/main/res/values-bs/strings.xml
new file mode 100644
index 0000000..08a68e5
--- /dev/null
+++ b/browser/src/main/res/values-bs/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Otvori u pregledniku"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopiraj link"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Dijeli link"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Link je kopiran u međumemoriju"</string>
+</resources>
diff --git a/browser/src/main/res/values-ca/strings.xml b/browser/src/main/res/values-ca/strings.xml
new file mode 100644
index 0000000..eec60c9
--- /dev/null
+++ b/browser/src/main/res/values-ca/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Obre al navegador"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Copia l\'enllaç"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Comparteix l\'enllaç"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"S\'ha copiat l\'enllaç al porta-retalls"</string>
+</resources>
diff --git a/browser/src/main/res/values-cs/strings.xml b/browser/src/main/res/values-cs/strings.xml
new file mode 100644
index 0000000..f877d4c
--- /dev/null
+++ b/browser/src/main/res/values-cs/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Otevřít v prohlížeči"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopírovat odkaz"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Sdílet odkaz"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Odkaz zkopírován do schránky"</string>
+</resources>
diff --git a/browser/src/main/res/values-da/strings.xml b/browser/src/main/res/values-da/strings.xml
new file mode 100644
index 0000000..9df467b
--- /dev/null
+++ b/browser/src/main/res/values-da/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Åbn i browser"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopiér link"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Del link"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Linket er kopieret til udklipsholderen"</string>
+</resources>
diff --git a/browser/src/main/res/values-de/strings.xml b/browser/src/main/res/values-de/strings.xml
new file mode 100644
index 0000000..775b002
--- /dev/null
+++ b/browser/src/main/res/values-de/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Im Browser öffnen"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Link kopieren"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Link teilen"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Link in Zwischenablage kopiert"</string>
+</resources>
diff --git a/browser/src/main/res/values-el/strings.xml b/browser/src/main/res/values-el/strings.xml
new file mode 100644
index 0000000..69b36794
--- /dev/null
+++ b/browser/src/main/res/values-el/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Άνοιγμα σε πρόγραμμα περιήγησης"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Αντιγραφή συνδέσμου"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Κοινοποίηση συνδέσμου"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Ο σύνδεσμος αντιγράφηκε στο πρόχειρο"</string>
+</resources>
diff --git a/browser/src/main/res/values-en-rAU/strings.xml b/browser/src/main/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..ea0b092
--- /dev/null
+++ b/browser/src/main/res/values-en-rAU/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Open in browser"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Copy link"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Share link"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Link copied to clipboard"</string>
+</resources>
diff --git a/browser/src/main/res/values-en-rGB/strings.xml b/browser/src/main/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..ea0b092
--- /dev/null
+++ b/browser/src/main/res/values-en-rGB/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Open in browser"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Copy link"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Share link"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Link copied to clipboard"</string>
+</resources>
diff --git a/browser/src/main/res/values-en-rIN/strings.xml b/browser/src/main/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..ea0b092
--- /dev/null
+++ b/browser/src/main/res/values-en-rIN/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Open in browser"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Copy link"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Share link"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Link copied to clipboard"</string>
+</resources>
diff --git a/browser/src/main/res/values-es-rUS/strings.xml b/browser/src/main/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..22197c9
--- /dev/null
+++ b/browser/src/main/res/values-es-rUS/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Abrir en el navegador"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Copiar vínculo"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Compartir vínculo"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Se copió el vínculo al portapapeles"</string>
+</resources>
diff --git a/browser/src/main/res/values-es/strings.xml b/browser/src/main/res/values-es/strings.xml
new file mode 100644
index 0000000..8eeb751
--- /dev/null
+++ b/browser/src/main/res/values-es/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Abrir en el navegador"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Copiar enlace"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Compartir enlace"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Enlace copiado en el portapapeles"</string>
+</resources>
diff --git a/browser/src/main/res/values-et/strings.xml b/browser/src/main/res/values-et/strings.xml
new file mode 100644
index 0000000..42a6eae
--- /dev/null
+++ b/browser/src/main/res/values-et/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Ava brauseris"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopeeri link"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Jaga linki"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Link kopeeriti lõikelauale"</string>
+</resources>
diff --git a/browser/src/main/res/values-eu/strings.xml b/browser/src/main/res/values-eu/strings.xml
new file mode 100644
index 0000000..8d89547
--- /dev/null
+++ b/browser/src/main/res/values-eu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Ireki arakatzailean"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopiatu esteka"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Partekatu esteka"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Arbelean kopiatu da esteka"</string>
+</resources>
diff --git a/browser/src/main/res/values-fa/strings.xml b/browser/src/main/res/values-fa/strings.xml
new file mode 100644
index 0000000..2cfea67
--- /dev/null
+++ b/browser/src/main/res/values-fa/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"بازکردن در مرورگر"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"کپی پیوند"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"هم‌رسانی پیوند"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"پیوند در بریده‌دان کپی شد"</string>
+</resources>
diff --git a/browser/src/main/res/values-fi/strings.xml b/browser/src/main/res/values-fi/strings.xml
new file mode 100644
index 0000000..cb34407
--- /dev/null
+++ b/browser/src/main/res/values-fi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Avaa selaimessa"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopioi linkki"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Jaa linkki"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Linkki kopioitu leikepöydälle"</string>
+</resources>
diff --git a/browser/src/main/res/values-fr-rCA/strings.xml b/browser/src/main/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..43eee31
--- /dev/null
+++ b/browser/src/main/res/values-fr-rCA/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Ouvrir dans le navigateur"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Copier le lien"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Partager le lien"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Lien copié dans le presse-papiers"</string>
+</resources>
diff --git a/browser/src/main/res/values-fr/strings.xml b/browser/src/main/res/values-fr/strings.xml
new file mode 100644
index 0000000..3569c1c
--- /dev/null
+++ b/browser/src/main/res/values-fr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Ouvrir dans un navigateur"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Copier le lien"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Partager le lien"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Lien copié dans le presse-papiers"</string>
+</resources>
diff --git a/browser/src/main/res/values-gl/strings.xml b/browser/src/main/res/values-gl/strings.xml
new file mode 100644
index 0000000..7e45ef2
--- /dev/null
+++ b/browser/src/main/res/values-gl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Abrir no navegador"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Copiar ligazón"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Compartir ligazón"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Copiouse a ligazón no portapapeis"</string>
+</resources>
diff --git a/browser/src/main/res/values-gu/strings.xml b/browser/src/main/res/values-gu/strings.xml
new file mode 100644
index 0000000..fe498b0
--- /dev/null
+++ b/browser/src/main/res/values-gu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"બ્રાઉઝરમાં ખોલો"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"લિંક કૉપિ કરો"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"લિંક શેર કરો"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"ક્લિપબોર્ડ પર લિંક કૉપિ કરી"</string>
+</resources>
diff --git a/browser/src/main/res/values-hi/strings.xml b/browser/src/main/res/values-hi/strings.xml
new file mode 100644
index 0000000..62db794
--- /dev/null
+++ b/browser/src/main/res/values-hi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"ब्राउज़र में खोलें"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"लिंक कॉपी करें"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"लिंक शेयर करें"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"लिंक क्लिपबोर्ड पर कॉपी किया गया"</string>
+</resources>
diff --git a/browser/src/main/res/values-hr/strings.xml b/browser/src/main/res/values-hr/strings.xml
new file mode 100644
index 0000000..750455f
--- /dev/null
+++ b/browser/src/main/res/values-hr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Otvori u pregledniku"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopiraj vezu"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Podijeli vezu"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Veza je kopirana u međuspremnik"</string>
+</resources>
diff --git a/browser/src/main/res/values-hu/strings.xml b/browser/src/main/res/values-hu/strings.xml
new file mode 100644
index 0000000..796b869
--- /dev/null
+++ b/browser/src/main/res/values-hu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Megnyitás böngészőben"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Link másolása"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Link megosztása"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Link vágólapra másolva"</string>
+</resources>
diff --git a/browser/src/main/res/values-hy/strings.xml b/browser/src/main/res/values-hy/strings.xml
new file mode 100644
index 0000000..44a74d5
--- /dev/null
+++ b/browser/src/main/res/values-hy/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Բացել դիտարկիչում"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Պատճենել հղումը"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Կիսվել հղումով"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Հղումը պատճենվեց սեղմատախտակին"</string>
+</resources>
diff --git a/browser/src/main/res/values-in/strings.xml b/browser/src/main/res/values-in/strings.xml
new file mode 100644
index 0000000..944cf16
--- /dev/null
+++ b/browser/src/main/res/values-in/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Buka di browser"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Salin link"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Bagikan link"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Link disalin ke papan klip"</string>
+</resources>
diff --git a/browser/src/main/res/values-is/strings.xml b/browser/src/main/res/values-is/strings.xml
new file mode 100644
index 0000000..273b5e1
--- /dev/null
+++ b/browser/src/main/res/values-is/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Opna í vafra"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Afrita tengil"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Deila tengli"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Tengill afritaður á klippiborð"</string>
+</resources>
diff --git a/browser/src/main/res/values-it/strings.xml b/browser/src/main/res/values-it/strings.xml
new file mode 100644
index 0000000..f01fb6f
--- /dev/null
+++ b/browser/src/main/res/values-it/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Apri nel browser"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Copia link"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Condividi link"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Link copiato negli appunti"</string>
+</resources>
diff --git a/browser/src/main/res/values-iw/strings.xml b/browser/src/main/res/values-iw/strings.xml
new file mode 100644
index 0000000..63ed4d8
--- /dev/null
+++ b/browser/src/main/res/values-iw/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"פתיחה בדפדפן"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"להעתקת הקישור"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"לשיתוף הקישור"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"הקישור הועתק ללוח"</string>
+</resources>
diff --git a/browser/src/main/res/values-ja/strings.xml b/browser/src/main/res/values-ja/strings.xml
new file mode 100644
index 0000000..fa9ef93
--- /dev/null
+++ b/browser/src/main/res/values-ja/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"ブラウザで開く"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"リンクをコピー"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"リンクの共有"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"リンクをクリップボードにコピーしました"</string>
+</resources>
diff --git a/browser/src/main/res/values-ka/strings.xml b/browser/src/main/res/values-ka/strings.xml
new file mode 100644
index 0000000..d471a7e
--- /dev/null
+++ b/browser/src/main/res/values-ka/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"ბრაუზერში გახსნა"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"ბმულის კოპირება"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"ბმულის გაზიარება"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"გაცვლის ბუფერში კოპირებული ბმული"</string>
+</resources>
diff --git a/browser/src/main/res/values-kk/strings.xml b/browser/src/main/res/values-kk/strings.xml
new file mode 100644
index 0000000..1b61c7b
--- /dev/null
+++ b/browser/src/main/res/values-kk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Браузерден ашу"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Сілтемені көшіру"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Сілтемені бөлісу"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Сілтеме буферге көшірілді."</string>
+</resources>
diff --git a/browser/src/main/res/values-km/strings.xml b/browser/src/main/res/values-km/strings.xml
new file mode 100644
index 0000000..36b6717
--- /dev/null
+++ b/browser/src/main/res/values-km/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"បើក​នៅក្នុង​កម្មវិធី​រុករកតាម​អ៊ីនធឺណិត"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"ចម្លង​តំណ"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"តំណចែករំលែក"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"បាន​ចម្លង​តំណ​ទៅឃ្លីបបត"</string>
+</resources>
diff --git a/browser/src/main/res/values-kn/strings.xml b/browser/src/main/res/values-kn/strings.xml
new file mode 100644
index 0000000..515f7db2c
--- /dev/null
+++ b/browser/src/main/res/values-kn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"ಬ್ರೌಸರ್‌ನಲ್ಲಿ ತೆರೆಯಿರಿ"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"ಲಿಂಕ್ ನಕಲಿಸಿ"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"ಲಿಂಕ್ ಹಂಚಿರಿ"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ಗೆ ಲಿಂಕ್ ಅನ್ನು ನಕಲಿಸಲಾಗಿದೆ"</string>
+</resources>
diff --git a/browser/src/main/res/values-ko/strings.xml b/browser/src/main/res/values-ko/strings.xml
new file mode 100644
index 0000000..1b2ce04
--- /dev/null
+++ b/browser/src/main/res/values-ko/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"브라우저에서 열기"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"링크 복사"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"링크 공유"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"클립보드에 링크 복사됨"</string>
+</resources>
diff --git a/browser/src/main/res/values-ky/strings.xml b/browser/src/main/res/values-ky/strings.xml
new file mode 100644
index 0000000..0f8f958
--- /dev/null
+++ b/browser/src/main/res/values-ky/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Серепчиден ачуу"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Шилтемени көчүрүү"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Шилтемени бөлүшүү"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Шилтеме буферге көчүрүлдү"</string>
+</resources>
diff --git a/browser/src/main/res/values-lo/strings.xml b/browser/src/main/res/values-lo/strings.xml
new file mode 100644
index 0000000..cdf8ec5
--- /dev/null
+++ b/browser/src/main/res/values-lo/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"ເປີດໃນໂປຣແກຣມທ່ອງເວັບ"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"ສຳເນົາລິ້ງ"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"ແບ່ງປັນລິ້ງ"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"ສຳເນົາລິ້ງໃສ່ຄລິບບອດແລ້ວ"</string>
+</resources>
diff --git a/browser/src/main/res/values-lt/strings.xml b/browser/src/main/res/values-lt/strings.xml
new file mode 100644
index 0000000..5e7f6f5
--- /dev/null
+++ b/browser/src/main/res/values-lt/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Atidaryti naršyklėje"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopijuoti nuorodą"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Bendrinti nuorodą"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Nuoroda nukopijuota į iškarpinę"</string>
+</resources>
diff --git a/browser/src/main/res/values-lv/strings.xml b/browser/src/main/res/values-lv/strings.xml
new file mode 100644
index 0000000..57d916a
--- /dev/null
+++ b/browser/src/main/res/values-lv/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Atvērt pārlūkprogrammā"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopēt saiti"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Kopīgot saiti"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Saite ir kopēta starpliktuvē."</string>
+</resources>
diff --git a/browser/src/main/res/values-mk/strings.xml b/browser/src/main/res/values-mk/strings.xml
new file mode 100644
index 0000000..1377c26
--- /dev/null
+++ b/browser/src/main/res/values-mk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Отвори во прелистувач"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Копирај го линкот"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Сподели линк"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Линкот е копиран во привремена меморија"</string>
+</resources>
diff --git a/browser/src/main/res/values-ml/strings.xml b/browser/src/main/res/values-ml/strings.xml
new file mode 100644
index 0000000..1bff1ef
--- /dev/null
+++ b/browser/src/main/res/values-ml/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"ബ്രൗസറിൽ തുറക്കുക"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"ലിങ്ക് പകർത്തുക"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"ലിങ്ക് പങ്കിടുക"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"ക്ലിപ്പ്‌ബോർഡിലേക്ക് ലിങ്ക് പകർത്തി"</string>
+</resources>
diff --git a/browser/src/main/res/values-mn/strings.xml b/browser/src/main/res/values-mn/strings.xml
new file mode 100644
index 0000000..3cd50a0
--- /dev/null
+++ b/browser/src/main/res/values-mn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Хөтчид нээх"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Холбоосыг хуулах"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Холбоосыг хуваалцах"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Холбоосыг түр санах ойд хуулсан"</string>
+</resources>
diff --git a/browser/src/main/res/values-mr/strings.xml b/browser/src/main/res/values-mr/strings.xml
new file mode 100644
index 0000000..f45c36b
--- /dev/null
+++ b/browser/src/main/res/values-mr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"ब्राउझरमध्ये उघडा"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"लिंक कॉपी करा"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"लिंक शेअर करा"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"लिंक क्लिपबोर्डवर कॉपी केली"</string>
+</resources>
diff --git a/browser/src/main/res/values-ms/strings.xml b/browser/src/main/res/values-ms/strings.xml
new file mode 100644
index 0000000..2ca4b9f
--- /dev/null
+++ b/browser/src/main/res/values-ms/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Buka dalam penyemak imbas"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Salin pautan"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Kongsi pautan"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Pautan disalin ke papan keratan"</string>
+</resources>
diff --git a/browser/src/main/res/values-my/strings.xml b/browser/src/main/res/values-my/strings.xml
new file mode 100644
index 0000000..bd80be0
--- /dev/null
+++ b/browser/src/main/res/values-my/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"ဘရောင်ဇာတွင် ဖွင့်ရန်"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"လင့်ခ်ကို ကူးယူရန်"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"လင့်ခ်ကို မျှဝေရန်"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"လင့်ခ်ကို ကလစ်ဘုတ်သို့ ကူးပြီးပါပြီ"</string>
+</resources>
diff --git a/browser/src/main/res/values-nb/strings.xml b/browser/src/main/res/values-nb/strings.xml
new file mode 100644
index 0000000..77990ce
--- /dev/null
+++ b/browser/src/main/res/values-nb/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Åpne i nettleseren"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopiér linken"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Del link"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Linken er kopiert til utklippstavlen"</string>
+</resources>
diff --git a/browser/src/main/res/values-ne/strings.xml b/browser/src/main/res/values-ne/strings.xml
new file mode 100644
index 0000000..e7bdb2a
--- /dev/null
+++ b/browser/src/main/res/values-ne/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"ब्राउजरमा खोल्नुहोस्"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"लिंक प्रतिलिपि गर्नुहोस्"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"लिंक आदान प्रदान गर्नुहोस्"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"क्लिपबोर्डमा लिंक प्रतिलिपि गरियो"</string>
+</resources>
diff --git a/browser/src/main/res/values-nl/strings.xml b/browser/src/main/res/values-nl/strings.xml
new file mode 100644
index 0000000..db7a2fd
--- /dev/null
+++ b/browser/src/main/res/values-nl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Openen in browser"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Link kopiëren"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Link delen"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Link naar klembord gekopieerd"</string>
+</resources>
diff --git a/browser/src/main/res/values-or/strings.xml b/browser/src/main/res/values-or/strings.xml
new file mode 100644
index 0000000..921fd03
--- /dev/null
+++ b/browser/src/main/res/values-or/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"ବ୍ରାଉଜର୍‌ରେ ଖୋଲନ୍ତୁ"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"ଲିଙ୍କ୍ କପି କରନ୍ତୁ"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"ଲିଙ୍କ୍ ସେୟାର୍ କରନ୍ତୁ"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"ଲିଙ୍କକୁ କ୍ଲିପ୍‍‍ବୋର୍ଡରେ କପି କରାଯାଇଛି"</string>
+</resources>
diff --git a/browser/src/main/res/values-pa/strings.xml b/browser/src/main/res/values-pa/strings.xml
new file mode 100644
index 0000000..987092e
--- /dev/null
+++ b/browser/src/main/res/values-pa/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"ਬ੍ਰਾਊਜ਼ਰ ਵਿੱਚ ਖੋਲ੍ਹੋ"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"ਲਿੰਕ ਕਾਪੀ ਕਰੋ"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"ਲਿੰਕ ਸਾਂਝਾ ਕਰੋ"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"ਲਿੰਕ ਕਲਿੱਪਬੋਰਡ \'ਤੇ ਕਾਪੀ ਹੋ ਗਿਆ"</string>
+</resources>
diff --git a/browser/src/main/res/values-pl/strings.xml b/browser/src/main/res/values-pl/strings.xml
new file mode 100644
index 0000000..0e62e42
--- /dev/null
+++ b/browser/src/main/res/values-pl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Otwórz w przeglądarce"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopiuj link"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Udostępnij link"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Link skopiowany do schowka"</string>
+</resources>
diff --git a/browser/src/main/res/values-pt-rBR/strings.xml b/browser/src/main/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..dd438f1
--- /dev/null
+++ b/browser/src/main/res/values-pt-rBR/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Abrir no navegador"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Copiar link"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Compartilhar link"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Link copiado para a área de transferência"</string>
+</resources>
diff --git a/browser/src/main/res/values-pt-rPT/strings.xml b/browser/src/main/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..08390ad
--- /dev/null
+++ b/browser/src/main/res/values-pt-rPT/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Abrir no navegador"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Copiar link"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Partilhar link"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Link copiado para a área de transferência."</string>
+</resources>
diff --git a/browser/src/main/res/values-pt/strings.xml b/browser/src/main/res/values-pt/strings.xml
new file mode 100644
index 0000000..dd438f1
--- /dev/null
+++ b/browser/src/main/res/values-pt/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Abrir no navegador"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Copiar link"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Compartilhar link"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Link copiado para a área de transferência"</string>
+</resources>
diff --git a/browser/src/main/res/values-ro/strings.xml b/browser/src/main/res/values-ro/strings.xml
new file mode 100644
index 0000000..65b7700
--- /dev/null
+++ b/browser/src/main/res/values-ro/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Deschideți în browser"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Copiați linkul"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Trimiteți linkul"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Linkul a fost copiat în clipboard"</string>
+</resources>
diff --git a/browser/src/main/res/values-ru/strings.xml b/browser/src/main/res/values-ru/strings.xml
new file mode 100644
index 0000000..694c46c
--- /dev/null
+++ b/browser/src/main/res/values-ru/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Открыть в браузере"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Копировать ссылку"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Отправить ссылку"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Ссылка скопирована в буфер обмена."</string>
+</resources>
diff --git a/browser/src/main/res/values-si/strings.xml b/browser/src/main/res/values-si/strings.xml
new file mode 100644
index 0000000..2b6f22f
--- /dev/null
+++ b/browser/src/main/res/values-si/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"බ්‍රව්සරයේ විවෘත කරන්න"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"සබැඳිය පිටපත් කරන්න"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"සබැඳිය බෙදා ගන්න"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"සබැඳිය පසුරු පුවරුවට පිටපත් කෙරිණි"</string>
+</resources>
diff --git a/browser/src/main/res/values-sk/strings.xml b/browser/src/main/res/values-sk/strings.xml
new file mode 100644
index 0000000..4489ab4
--- /dev/null
+++ b/browser/src/main/res/values-sk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Otvoriť v prehliadači"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopírovať odkaz"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Zdieľať odkaz"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Odkaz bol skopírovaný do schránky"</string>
+</resources>
diff --git a/browser/src/main/res/values-sl/strings.xml b/browser/src/main/res/values-sl/strings.xml
new file mode 100644
index 0000000..0d53238
--- /dev/null
+++ b/browser/src/main/res/values-sl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Odpri v brskalniku"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopiraj povezavo"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Deli povezavo"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Povezava je kopirana v odložišče"</string>
+</resources>
diff --git a/browser/src/main/res/values-sq/strings.xml b/browser/src/main/res/values-sq/strings.xml
new file mode 100644
index 0000000..7855f3d
--- /dev/null
+++ b/browser/src/main/res/values-sq/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Hape në shfletues"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopjo lidhjen"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Ndaj lidhjen"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Lidhja u kopjua në kujtesën e fragmenteve"</string>
+</resources>
diff --git a/browser/src/main/res/values-sr/strings.xml b/browser/src/main/res/values-sr/strings.xml
new file mode 100644
index 0000000..e3fe39a
--- /dev/null
+++ b/browser/src/main/res/values-sr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Отвори у прегледачу"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Копирај линк"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Дели линк"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Линк је копиран у привремену меморију"</string>
+</resources>
diff --git a/browser/src/main/res/values-sv/strings.xml b/browser/src/main/res/values-sv/strings.xml
new file mode 100644
index 0000000..3d96572
--- /dev/null
+++ b/browser/src/main/res/values-sv/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Öppna i webbläsaren"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopiera länk"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Dela länk"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Länk kopierad till Urklipp"</string>
+</resources>
diff --git a/browser/src/main/res/values-sw/strings.xml b/browser/src/main/res/values-sw/strings.xml
new file mode 100644
index 0000000..c8c9c31
--- /dev/null
+++ b/browser/src/main/res/values-sw/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Fungua katika kivinjari"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Nakili kiungo"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Shiriki kiungo"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Imenakili kiungo kwenye ubao wa kunakili"</string>
+</resources>
diff --git a/browser/src/main/res/values-ta/strings.xml b/browser/src/main/res/values-ta/strings.xml
new file mode 100644
index 0000000..7885a21
--- /dev/null
+++ b/browser/src/main/res/values-ta/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"உலாவியில் திற"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"இணைப்பை நகலெடு"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"இணைப்பைப் பகிர்"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"கிளிப்-போர்டுக்கு இணைப்பு நகலெடுக்கப்பட்டது"</string>
+</resources>
diff --git a/browser/src/main/res/values-te/strings.xml b/browser/src/main/res/values-te/strings.xml
new file mode 100644
index 0000000..6132419
--- /dev/null
+++ b/browser/src/main/res/values-te/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"బ్రౌజర్‌లో తెరువు"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"లింక్‌ను కాపీ చేయి"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"లింక్‌ను షేర్ చేయి"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"క్లిప్‌బోర్డ్‌కు లింక్ కాపీ చేయబడింది"</string>
+</resources>
diff --git a/browser/src/main/res/values-th/strings.xml b/browser/src/main/res/values-th/strings.xml
new file mode 100644
index 0000000..d1e538a
--- /dev/null
+++ b/browser/src/main/res/values-th/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"เปิดในเบราว์เซอร์"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"คัดลอกลิงก์"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"แชร์ลิงก์"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"คัดลอกลิงก์ไปยังคลิปบอร์ดแล้ว"</string>
+</resources>
diff --git a/browser/src/main/res/values-tl/strings.xml b/browser/src/main/res/values-tl/strings.xml
new file mode 100644
index 0000000..0fdfc6c
--- /dev/null
+++ b/browser/src/main/res/values-tl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Buksan sa browser"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopyahin ang link"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Ibahagi ang link"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Nakopya sa clipboard ang link"</string>
+</resources>
diff --git a/browser/src/main/res/values-tr/strings.xml b/browser/src/main/res/values-tr/strings.xml
new file mode 100644
index 0000000..6ab3ec2
--- /dev/null
+++ b/browser/src/main/res/values-tr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Tarayıcıda aç"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Bağlantıyı kopyala"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Bağlantıyı paylaş"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Bağlantı panoya kopyalandı"</string>
+</resources>
diff --git a/browser/src/main/res/values-uk/strings.xml b/browser/src/main/res/values-uk/strings.xml
new file mode 100644
index 0000000..b40badb
--- /dev/null
+++ b/browser/src/main/res/values-uk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Відкрити у веб-переглядачі"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Копіювати посилання"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Надіслати посилання"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Посилання скопійовано в буфер обміну"</string>
+</resources>
diff --git a/browser/src/main/res/values-ur/strings.xml b/browser/src/main/res/values-ur/strings.xml
new file mode 100644
index 0000000..e6dc0a2
--- /dev/null
+++ b/browser/src/main/res/values-ur/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"براؤزر میں کھولیں"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"لنک کاپی کریں"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"لنک کا اشتراک کریں"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"لنک کلپ بورڈ پر کاپی ہو گیا"</string>
+</resources>
diff --git a/browser/src/main/res/values-uz/strings.xml b/browser/src/main/res/values-uz/strings.xml
new file mode 100644
index 0000000..d33562f
--- /dev/null
+++ b/browser/src/main/res/values-uz/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Brauzerda ochish"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Havoladan nusxa olish"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Havolani ulashish"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Havoladan vaqtinchalik xotiraga nusxa olindi"</string>
+</resources>
diff --git a/browser/src/main/res/values-vi/strings.xml b/browser/src/main/res/values-vi/strings.xml
new file mode 100644
index 0000000..d494c98
--- /dev/null
+++ b/browser/src/main/res/values-vi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Mở trong trình duyệt"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Sao chép liên kết"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Chia sẻ liên kết"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Đã sao chép liên kết vào khay nhớ tạm"</string>
+</resources>
diff --git a/browser/src/main/res/values-zh-rCN/strings.xml b/browser/src/main/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..63c639d
--- /dev/null
+++ b/browser/src/main/res/values-zh-rCN/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"在浏览器中打开"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"复制链接"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"分享链接"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"链接已复制到剪贴板"</string>
+</resources>
diff --git a/browser/src/main/res/values-zh-rHK/strings.xml b/browser/src/main/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..8d4feb3
--- /dev/null
+++ b/browser/src/main/res/values-zh-rHK/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"在瀏覽器中開啟"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"複製連結"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"分享連結"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"連結已複製到剪貼簿"</string>
+</resources>
diff --git a/browser/src/main/res/values-zh-rTW/strings.xml b/browser/src/main/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..b60673f
--- /dev/null
+++ b/browser/src/main/res/values-zh-rTW/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"在瀏覽器中開啟"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"複製連結"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"分享連結"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"已將連結複製到剪貼簿"</string>
+</resources>
diff --git a/browser/src/main/res/values-zu/strings.xml b/browser/src/main/res/values-zu/strings.xml
new file mode 100644
index 0000000..0740ead
--- /dev/null
+++ b/browser/src/main/res/values-zu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright 2018 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
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fallback_menu_item_open_in_browser" msgid="8984733760067120953">"Vula kusiphequluli"</string>
+    <string name="fallback_menu_item_copy_link" msgid="2615365786337886368">"Kopisha isixhumanisi"</string>
+    <string name="fallback_menu_item_share_link" msgid="271185644269364308">"Yabelana ngesixhumanisi"</string>
+    <string name="copy_toast_msg" msgid="8230469354668895088">"Isixhumanisi sikopishelwe ku-clipboard"</string>
+</resources>
diff --git a/browser/src/test/java/androidx/browser/trusted/TrustedWebActivityIntentBuilderTest.java b/browser/src/test/java/androidx/browser/trusted/TrustedWebActivityIntentBuilderTest.java
index c86da1d9..bdfdfa0 100644
--- a/browser/src/test/java/androidx/browser/trusted/TrustedWebActivityIntentBuilderTest.java
+++ b/browser/src/test/java/androidx/browser/trusted/TrustedWebActivityIntentBuilderTest.java
@@ -31,6 +31,8 @@
 import androidx.browser.customtabs.CustomTabsIntent;
 import androidx.browser.customtabs.CustomTabsSession;
 import androidx.browser.customtabs.TestUtil;
+import androidx.browser.trusted.sharing.ShareData;
+import androidx.browser.trusted.sharing.ShareTarget;
 import androidx.browser.trusted.splashscreens.SplashScreenParamKey;
 import androidx.test.filters.SmallTest;
 
@@ -63,12 +65,15 @@
 
         Bundle splashScreenParams = new Bundle();
         int splashBgColor = 0x112233;
-        splashScreenParams.putInt(
-                SplashScreenParamKey.BACKGROUND_COLOR, splashBgColor);
+        splashScreenParams.putInt(SplashScreenParamKey.BACKGROUND_COLOR, splashBgColor);
 
         CustomTabColorSchemeParams colorSchemeParams = new CustomTabColorSchemeParams.Builder()
                     .setToolbarColor(0xff112233).build();
 
+        ShareData shareData = new ShareData("share_title", "share_text", null);
+        ShareTarget shareTarget = new ShareTarget("action", null, null,
+                new ShareTarget.Params(null, null, null));
+
         CustomTabsSession session = TestUtil.makeMockSession();
 
         Intent intent = new TrustedWebActivityIntentBuilder(url)
@@ -78,7 +83,9 @@
                         .setColorSchemeParams(COLOR_SCHEME_DARK, colorSchemeParams)
                         .setAdditionalTrustedOrigins(additionalTrustedOrigins)
                         .setSplashScreenParams(splashScreenParams)
-                        .build(session);
+                        .setShareParams(shareTarget, shareData)
+                        .build(session)
+                        .getIntent();
 
         assertTrue(intent.getBooleanExtra(EXTRA_LAUNCH_AS_TRUSTED_WEB_ACTIVITY, false));
         TestUtil.assertIntentHasSession(intent, session);
@@ -99,5 +106,15 @@
         // No need to test every splash screen param: they are sent in as-is in provided Bundle.
         assertEquals(splashBgColor, splashScreenParamsReceived.getInt(
                 SplashScreenParamKey.BACKGROUND_COLOR));
+
+        ShareData shareDataFromIntent = ShareData.fromBundle(intent.getBundleExtra(
+                TrustedWebActivityIntentBuilder.EXTRA_SHARE_DATA));
+        // Bundling-unbundling of the ShareData and ShareTarget is tested in more detail elsewhere.
+        // Here we only check that the Builder correctly added the extras.
+        assertEquals(shareData.title, shareDataFromIntent.title);
+
+        ShareTarget shareTargetFromIntent = ShareTarget.fromBundle(intent.getBundleExtra(
+                TrustedWebActivityIntentBuilder.EXTRA_SHARE_TARGET));
+        assertEquals(shareTarget.action, shareTargetFromIntent.action);
     }
 }
diff --git a/browser/src/test/java/androidx/browser/trusted/sharing/ShareDataTest.java b/browser/src/test/java/androidx/browser/trusted/sharing/ShareDataTest.java
new file mode 100644
index 0000000..c239fe8
--- /dev/null
+++ b/browser/src/test/java/androidx/browser/trusted/sharing/ShareDataTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2019 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.browser.trusted.sharing;
+
+import static org.junit.Assert.assertEquals;
+
+import android.net.Uri;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.ParameterizedRobolectricTestRunner;
+import org.robolectric.annotation.internal.DoNotInstrument;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Tests for {@link ShareData}.
+ */
+@RunWith(ParameterizedRobolectricTestRunner.class)
+@DoNotInstrument
+@SmallTest
+public class ShareDataTest {
+
+    private static final List<Uri> URIS = Arrays.asList(Uri.parse("http://foo"),
+            Uri.parse("http://bar"));
+
+    @ParameterizedRobolectricTestRunner.Parameters(name = "{1}")
+    public static Collection<Object[]> parameters() {
+        return Arrays.asList(
+                new Object[]{new ShareData("foo", "bar", URIS), "All included"},
+                new Object[]{new ShareData("foo", "bar", null), "No URIs"},
+                new Object[]{new ShareData(null, "bar", URIS), "No title"},
+                new Object[]{new ShareData("foo", null, URIS), "No text"});
+    }
+
+    private final ShareData mShareData;
+
+    public ShareDataTest(ShareData shareData, String testName) {
+        mShareData = shareData;
+    }
+
+    @Test
+    public void bundlingAndUnbundlingYieldsOriginalObject() {
+        assertShareDataEquals(mShareData, ShareData.fromBundle(mShareData.toBundle()));
+    }
+
+    private void assertShareDataEquals(ShareData expected, ShareData actual) {
+        assertEquals(expected.title, actual.title);
+        assertEquals(expected.text, actual.text);
+        assertEquals(expected.uris, actual.uris);
+    }
+}
diff --git a/browser/src/test/java/androidx/browser/trusted/sharing/ShareTargetTest.java b/browser/src/test/java/androidx/browser/trusted/sharing/ShareTargetTest.java
new file mode 100644
index 0000000..bc59dd6
--- /dev/null
+++ b/browser/src/test/java/androidx/browser/trusted/sharing/ShareTargetTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2019 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.browser.trusted.sharing;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import androidx.browser.trusted.sharing.ShareTarget.FileFormField;
+import androidx.browser.trusted.sharing.ShareTarget.Params;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.ParameterizedRobolectricTestRunner;
+import org.robolectric.annotation.internal.DoNotInstrument;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Tests for {@link ShareTarget}.
+ */
+@RunWith(ParameterizedRobolectricTestRunner.class)
+@DoNotInstrument
+@SmallTest
+public class ShareTargetTest {
+
+    private static final String ACTION = "action.html";
+    private static final String METHOD = "POST";
+    private static final String ENCODING_TYPE = "multipart/form-data";
+
+    private static final FileFormField FILE_FIELD_1 =
+            new FileFormField("file1", Arrays.asList("type1", "type2"));
+
+    private static final FileFormField FILE_FIELD_2 =
+            new FileFormField("file2", Arrays.asList("type3", "type4"));
+
+    private static final List<FileFormField> FILES =
+            Arrays.asList(FILE_FIELD_1, FILE_FIELD_2);
+
+    private static final Params DEFAULT_PARAMS = new Params("title", "text", FILES);
+    private static final Params PARAMS_NO_FILES = new Params("title", "text", null);
+    private static final Params PARAMS_NO_TITLE = new Params(null, "text", FILES);
+    private static final Params PARAMS_NO_TEXT = new Params("title", null, FILES);
+
+    @ParameterizedRobolectricTestRunner.Parameters(name = "{1}")
+    public static Collection<Object[]> parameters() {
+        return Arrays.asList(
+                new Object[]{new ShareTarget(ACTION, METHOD, ENCODING_TYPE, DEFAULT_PARAMS),
+                        "All included"},
+                new Object[]{new ShareTarget(ACTION, METHOD, ENCODING_TYPE, PARAMS_NO_FILES),
+                        "No files"},
+                new Object[]{new ShareTarget(ACTION, METHOD, ENCODING_TYPE, PARAMS_NO_TITLE),
+                        "No title"},
+                new Object[]{new ShareTarget(ACTION, METHOD, ENCODING_TYPE, PARAMS_NO_TEXT),
+                        "No text"},
+                new Object[]{new ShareTarget(ACTION, null, ENCODING_TYPE, DEFAULT_PARAMS),
+                        "No method"},
+                new Object[]{new ShareTarget(ACTION, METHOD, null, DEFAULT_PARAMS),
+                        "No enc type"}
+        );
+    }
+
+    private final ShareTarget mShareTarget;
+
+    public ShareTargetTest(ShareTarget shareTarget, String testName) {
+        mShareTarget = shareTarget;
+    }
+
+    @Test
+    public void bundlingAndUnbundlingYieldsOriginalObject() {
+        assertShareTargetEquals(mShareTarget, ShareTarget.fromBundle(mShareTarget.toBundle()));
+    }
+
+    private void assertShareTargetEquals(ShareTarget expected, ShareTarget actual) {
+        assertEquals(expected.action, actual.action);
+        assertEquals(expected.encodingType, actual.encodingType);
+        assertEquals(expected.method, actual.method);
+        assertParamsEqual(expected.params, actual.params);
+    }
+
+    private void assertParamsEqual(Params expected, Params actual) {
+        assertEquals(expected.text, actual.text);
+        assertEquals(expected.title, actual.title);
+        assertFilesEqual(expected.files, actual.files);
+    }
+
+    private void assertFilesEqual(List<FileFormField> expected,
+            List<FileFormField> actual) {
+        if (expected == null) {
+            assertNull(actual);
+            return;
+        }
+        assertEquals(expected.size(), actual.size());
+        for (int i = 0; i < expected.size(); i++) {
+            assertFileEquals(expected.get(i), actual.get(i));
+        }
+    }
+
+    private void assertFileEquals(FileFormField expected,
+            FileFormField actual) {
+        assertEquals(expected.name, actual.name);
+        assertEquals(expected.acceptedTypes, actual.acceptedTypes);
+    }
+}
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/AffectedModuleDetectorImplTest.kt b/buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/AffectedModuleDetectorImplTest.kt
index c84eebb..77e7421 100644
--- a/buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/AffectedModuleDetectorImplTest.kt
+++ b/buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/AffectedModuleDetectorImplTest.kt
@@ -16,6 +16,8 @@
 
 package androidx.build.dependencyTracker
 
+import androidx.build.gitclient.Commit
+import androidx.build.gitclient.GitClient
 import org.gradle.api.Project
 import org.gradle.api.plugins.ExtraPropertiesExtension
 import org.gradle.testfixtures.ProjectBuilder
@@ -833,5 +835,13 @@
         ) = changedFiles
 
         override fun findPreviousMergeCL() = lastMergeSha
+
+        // Implement unused abstract method
+        override fun getGitLog(
+            sha: String,
+            top: String,
+            keepMerges: Boolean,
+            fullProjectDir: File
+        ): List<Commit> = listOf()
     }
 }
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/GitClientImplTest.kt b/buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/GitClientImplTest.kt
index 6c6034f..768e4a7 100644
--- a/buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/GitClientImplTest.kt
+++ b/buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/GitClientImplTest.kt
@@ -16,8 +16,12 @@
 
 package androidx.build.dependencyTracker
 
-import androidx.build.dependencyTracker.GitClientImpl.Companion.CHANGED_FILES_CMD_PREFIX
-import androidx.build.dependencyTracker.GitClientImpl.Companion.PREV_MERGE_CMD
+import androidx.build.gitclient.Commit
+import androidx.build.gitclient.CommitType
+import androidx.build.gitclient.GitClient
+import androidx.build.gitclient.GitClientImpl
+import androidx.build.gitclient.GitClientImpl.Companion.CHANGED_FILES_CMD_PREFIX
+import androidx.build.gitclient.GitClientImpl.Companion.PREV_MERGE_CMD
 import junit.framework.TestCase.assertEquals
 import junit.framework.TestCase.assertNull
 import org.junit.Rule
@@ -33,10 +37,15 @@
     val attachLogsRule = AttachLogsTestRule()
     private val logger = attachLogsRule.logger
     private val commandRunner = MockCommandRunner(logger)
+    /** The [GitClientImpl.workingDir] uses `System.getProperty("user.dir")` because the working
+     * directory passed to the [GitClientImpl] constructor needs to contain the a .git
+     * directory somewhere in the parent directory tree.  @see [GitClientImpl]
+     */
     private val client = GitClientImpl(
-            workingDir = File("."),
-            logger = logger,
-            commandRunner = commandRunner)
+        workingDir = File(System.getProperty("user.dir")),
+        logger = logger,
+        commandRunner = commandRunner
+    )
 
     @Test
     fun findMerge() {
@@ -92,6 +101,316 @@
                         includeUncommitted = false))
     }
 
+    @Test
+    fun parseAPICommitWithDefaultDelimiters() {
+        val commitWithApiChangeString: String =
+            """
+                _CommitStart
+                _CommitSHA:mySha
+                _Author:anemail@google.com
+                _Date:Tue Aug 6 15:05:55 2019 -0700
+                _Subject:Added a new API!
+                _Body:Also fixed some other bugs
+
+                Here is an explanation of my commit
+
+                Bug: 123456
+                Bug: b/1234567
+                Fixes: 123123
+                Test: ./gradlew buildOnServer
+
+                Change-Id: myChangeId
+
+                projectdir/a.java
+                projectdir/b.java
+                projectdir/androidTest/c.java
+                projectdir/api/some_api_file.txt
+                projectdir/api/current.txt
+            """
+        val commitWithApiChange: Commit = Commit(commitWithApiChangeString, "/projectdir/")
+        assertEquals("mySha", commitWithApiChange.sha)
+        assertEquals("anemail@google.com", commitWithApiChange.authorEmail)
+        assertEquals("myChangeId", commitWithApiChange.changeId)
+        assertEquals("Added a new API!", commitWithApiChange.summary)
+        assertEquals(CommitType.API_CHANGE, commitWithApiChange.type)
+        assertEquals(mutableListOf(123456, 1234567, 123123), commitWithApiChange.bugs)
+        assertEquals(
+            mutableListOf(
+                "projectdir/a.java",
+                "projectdir/b.java",
+                "projectdir/androidTest/c.java",
+                "projectdir/api/some_api_file.txt",
+                "projectdir/api/current.txt"
+            ),
+            commitWithApiChange.files
+        )
+    }
+
+    @Test
+    fun parseBugFixCommitWithCustomDelimiters() {
+        val commitSHADelimiter: String = "_MyCommitSHA:"
+        val subjectDelimiter: String = "_MySubject:"
+        val authorEmailDelimiter: String = "_MyAuthor:"
+        val projectDir: String = "group/artifact"
+        val commitWithABugFixString: String =
+            """
+                _CommitStart
+                ${commitSHADelimiter}mySha
+                ${authorEmailDelimiter}anemail@google.com
+                _Date:Tue Aug 6 15:05:55 2019 -0700
+                ${subjectDelimiter}Fixed a bug!
+                _Body:Also fixed some other bugs
+
+                Here is an explanation of my commit that changes a kotlin file
+
+                Bug: 111111, 222222
+                Test: ./gradlew buildOnServer
+
+                Change-Id: myChangeId
+
+                $projectDir/a.java
+                $projectDir/b.kt
+                $projectDir/androidTest/c.java
+            """
+        val commitWithABugFix: Commit = Commit(
+            commitWithABugFixString,
+            projectDir,
+            commitSHADelimiter = commitSHADelimiter,
+            subjectDelimiter = subjectDelimiter,
+            authorEmailDelimiter = authorEmailDelimiter
+        )
+        assertEquals("mySha", commitWithABugFix.sha)
+        assertEquals("anemail@google.com", commitWithABugFix.authorEmail)
+        assertEquals("myChangeId", commitWithABugFix.changeId)
+        assertEquals("Fixed a bug!", commitWithABugFix.summary)
+        assertEquals(CommitType.BUG_FIX, commitWithABugFix.type)
+        assertEquals(mutableListOf(111111, 222222), commitWithABugFix.bugs)
+        assertEquals(
+            mutableListOf(
+                "$projectDir/a.java",
+                "$projectDir/b.kt",
+                "$projectDir/androidTest/c.java"
+            ),
+            commitWithABugFix.files
+        )
+    }
+
+    @Test
+    fun parseExternalContributorCommitWithCustomDelimiters() {
+        val commitSHADelimiter: String = "_MyCommitSHA:"
+        val subjectDelimiter: String = "_MySubject:"
+        val authorEmailDelimiter: String = "_MyAuthor:"
+        val projectDir: String = "group/artifact"
+        val commitFromExternalContributorString: String =
+            """
+                _CommitStart
+                ${commitSHADelimiter}mySha
+                ${authorEmailDelimiter}externalcontributor@gmail.com
+                _Date:Thurs Aug 8 15:05:55 2019 -0700
+                ${subjectDelimiter}New compat API!
+                _Body:Also fixed some other bugs
+
+                Here is an explanation of my commit that changes a java file
+
+                Bug: 111111, 222222
+                Test: ./gradlew buildOnServer
+
+                Change-Id: myChangeId
+
+                $projectDir/a.java
+                $projectDir/b.java
+                $projectDir/androidTest/c.java
+                $projectDir/api/current.txt
+                $projectDir/api/1.2.0-alpha04.txt
+            """
+        val commitFromExternalContributor: Commit = Commit(
+            commitFromExternalContributorString,
+            projectDir,
+            commitSHADelimiter = commitSHADelimiter,
+            subjectDelimiter = subjectDelimiter,
+            authorEmailDelimiter = authorEmailDelimiter
+        )
+        assertEquals("mySha", commitFromExternalContributor.sha)
+        assertEquals("externalcontributor@gmail.com", commitFromExternalContributor.authorEmail)
+        assertEquals("myChangeId", commitFromExternalContributor.changeId)
+        assertEquals("New compat API!", commitFromExternalContributor.summary)
+        assertEquals(CommitType.EXTERNAL_CONTRIBUTION, commitFromExternalContributor.type)
+        assertEquals(mutableListOf(111111, 222222), commitFromExternalContributor.bugs)
+        assertEquals(
+            mutableListOf(
+                "$projectDir/a.java",
+                "$projectDir/b.java",
+                "$projectDir/androidTest/c.java",
+                "$projectDir/api/current.txt",
+                "$projectDir/api/1.2.0-alpha04.txt"
+            ),
+            commitFromExternalContributor.files
+        )
+    }
+
+    @Test
+    fun parseGitLog() {
+        /*
+         * This is the default set-up boilerplate from `GitClientImpl.getGitLog` to set up the
+         * default git log command (val gitLogCmd)
+         */
+        val commitStartDelimiter: String = "_CommitStart"
+        val commitSHADelimiter: String = "_CommitSHA:"
+        val subjectDelimiter: String = "_Subject:"
+        val authorEmailDelimiter: String = "_Author:"
+        val dateDelimiter: String = "_Date:"
+        val bodyDelimiter: String = "_Body:"
+        val projectDir: String = "group/artifact"
+        val gitLogOptions: String =
+            "--pretty=format:$commitStartDelimiter%n" +
+                    "$commitSHADelimiter%H%n" +
+                    "$authorEmailDelimiter%ae%n" +
+                    "$dateDelimiter%ad%n" +
+                    "$subjectDelimiter%s%n" +
+                    "$bodyDelimiter%b" +
+                    " --no-merges"
+        val gitLogCmd: String = "${GitClientImpl.GIT_LOG_CMD_PREFIX} " +
+                "$gitLogOptions sha..topSha $projectDir"
+
+        // Check with default delimiters
+        val gitLogString: String =
+            """
+                _CommitStart
+                _CommitSHA:topSha
+                _Author:anemail@google.com
+                _Date:Tue Aug 6 15:05:55 2019 -0700
+                _Subject:Added a new API!
+                _Body:Also fixed some other bugs
+
+                Here is an explanation of my commit
+
+                Bug: 123456
+                Bug: b/1234567
+                Fixes: 123123
+                Test: ./gradlew buildOnServer
+
+                Change-Id: myChangeId
+
+                $projectDir/a.java
+                $projectDir/b.java
+                $projectDir/androidTest/c.java
+                $projectDir/api/some_api_file.txt
+                $projectDir/api/current.txt
+
+                _CommitStart
+                _CommitSHA:midSha
+                _Author:anemail@google.com
+                _Date:Tue Aug 6 15:05:55 2019 -0700
+                _Subject:Fixed a bug!
+                _Body:Also fixed some other bugs
+
+                Here is an explanation of my commit
+
+                Bug: 111111, 222222
+                Test: ./gradlew buildOnServer
+
+                Change-Id: myChangeId
+
+                $projectDir/a.java
+                $projectDir/b.java
+                $projectDir/androidTest/c.java
+
+                _CommitStart
+                _CommitSHA:sha
+                _Author:externalcontributor@gmail.com
+                _Date:Thurs Aug 8 15:05:55 2019 -0700
+                _Subject:New compat API!
+                _Body:Also fixed some other bugs
+
+                Here is an explanation of my commit
+
+                Bug: 111111, 222222
+                Test: ./gradlew buildOnServer
+
+                Change-Id: myChangeId
+
+                $projectDir/a.java
+                $projectDir/b.java
+                $projectDir/androidTest/c.java
+                $projectDir/api/current.txt
+                $projectDir/api/1.2.0-alpha04.txt
+            """
+
+        commandRunner.addReply(
+            gitLogCmd,
+            gitLogString
+        )
+
+        val commitWithAPIChange: Commit = Commit("", projectDir)
+        commitWithAPIChange.sha = "topSha"
+        commitWithAPIChange.authorEmail = "anemail@google.com"
+        commitWithAPIChange.changeId = "myChangeId"
+        commitWithAPIChange.summary = "Added a new API!"
+        commitWithAPIChange.type = CommitType.API_CHANGE
+        commitWithAPIChange.bugs = mutableListOf(123456, 1234567, 123123)
+        commitWithAPIChange.files = mutableListOf(
+            "$projectDir/a.java",
+            "$projectDir/b.java",
+            "$projectDir/androidTest/c.java",
+            "$projectDir/api/some_api_file.txt",
+            "$projectDir/api/current.txt"
+        )
+
+        val commitWithBugFix: Commit = Commit("", projectDir)
+        commitWithBugFix.sha = "midSha"
+        commitWithBugFix.authorEmail = "anemail@google.com"
+        commitWithBugFix.changeId = "myChangeId"
+        commitWithBugFix.summary = "Fixed a bug!"
+        commitWithBugFix.type = CommitType.BUG_FIX
+        commitWithBugFix.bugs = mutableListOf(111111, 222222)
+        commitWithBugFix.files = mutableListOf(
+            "$projectDir/a.java",
+            "$projectDir/b.java",
+            "$projectDir/androidTest/c.java"
+        )
+
+        val commitFromExternalContributor: Commit = Commit("", projectDir)
+        commitFromExternalContributor.sha = "sha"
+        commitFromExternalContributor.authorEmail = "externalcontributor@gmail.com"
+        commitFromExternalContributor.changeId = "myChangeId"
+        commitFromExternalContributor.summary = "New compat API!"
+        commitFromExternalContributor.type = CommitType.EXTERNAL_CONTRIBUTION
+        commitFromExternalContributor.bugs = mutableListOf(111111, 222222)
+        commitFromExternalContributor.files = mutableListOf(
+            "$projectDir/a.java",
+            "$projectDir/b.java",
+            "$projectDir/androidTest/c.java",
+            "$projectDir/api/current.txt",
+            "$projectDir/api/1.2.0-alpha04.txt"
+        )
+
+        val gitLogList: List<Commit> = client.getGitLog(
+            top = "topSha",
+            sha = "sha",
+            keepMerges = false,
+            fullProjectDir = File(projectDir)
+        )
+        gitLogList.forEach { commit ->
+            when (commit.sha) {
+                "topSha" -> assertCommitsAreEqual(commitWithAPIChange, commit)
+                "midSha" -> assertCommitsAreEqual(commitWithBugFix, commit)
+                "sha" -> assertCommitsAreEqual(commitFromExternalContributor, commit)
+                else -> throw RuntimeException("Incorrectly parsed commit: $commit")
+            }
+        }
+    }
+
+    fun assertCommitsAreEqual(commitA: Commit, commitB: Commit) {
+        assertEquals(commitA.summary, commitB.summary)
+        assertEquals(commitA.files, commitB.files)
+        assertEquals(commitA.sha, commitB.sha)
+        assertEquals(commitA.changeId, commitB.changeId)
+        assertEquals(commitA.authorEmail, commitB.authorEmail)
+        assertEquals(commitA.type, commitB.type)
+        assertEquals(commitA.projectDir, commitB.projectDir)
+        assertEquals(commitA.summary, commitB.summary)
+    }
+
     // For both Linux/Windows
     fun convertToFilePath(vararg list: String): String {
         return list.toList().joinToString(File.separator)
@@ -105,7 +424,14 @@
             replies[command] = response.split(System.lineSeparator())
         }
 
-        override fun execute(command: String): List<String> {
+        override fun execute(command: String): String {
+            return replies.getOrDefault(command, emptyList())
+                .joinToString(System.lineSeparator()).also {
+                    logger.info("cmd: $command response: $it")
+            }
+        }
+
+        override fun executeAndParse(command: String): List<String> {
             return replies.getOrDefault(command, emptyList()).also {
                 logger.info("cmd: $command response: $it")
             }
diff --git a/buildSrc/lint.xml b/buildSrc/lint.xml
new file mode 100644
index 0000000..e780a7a
--- /dev/null
+++ b/buildSrc/lint.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+    <issue id="LintBaseline" severity="ignore">
+        <ignore regexp=".* filtered out because .* listed in the baseline file.*"/>
+    </issue>
+</lint>
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt b/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
index d77740c..a69919f 100644
--- a/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
@@ -41,6 +41,7 @@
 import androidx.build.metalava.MetalavaTasks.configureAndroidProjectForMetalava
 import androidx.build.metalava.MetalavaTasks.configureJavaProjectForMetalava
 import androidx.build.metalava.UpdateApiTask
+import androidx.build.releasenotes.GenerateReleaseNotesTask
 import com.android.build.gradle.AppExtension
 import com.android.build.gradle.AppPlugin
 import com.android.build.gradle.LibraryExtension
@@ -63,13 +64,18 @@
 import org.gradle.kotlin.dsl.apply
 import org.gradle.kotlin.dsl.configure
 import org.gradle.kotlin.dsl.extra
+import org.gradle.kotlin.dsl.findByType
 import org.gradle.kotlin.dsl.getPlugin
 import org.gradle.testing.jacoco.plugins.JacocoPluginExtension
 import org.gradle.testing.jacoco.tasks.JacocoReport
-import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
+import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension
+import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
 import org.jetbrains.kotlin.gradle.plugin.KotlinBasePluginWrapper
+import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginWrapper
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 import java.io.File
+import java.time.LocalDate
+import java.time.format.DateTimeFormatter
 import java.util.concurrent.ConcurrentHashMap
 
 /**
@@ -78,6 +84,7 @@
  */
 const val USE_MAX_DEP_VERSIONS = "useMaxDepVersions"
 const val BUILD_INFO_DIR = "build-info"
+const val BUILD_ON_SERVER_DEPENDENT_ACTIONS = "buildOnServerDependentActions"
 
 /**
  * A plugin which enables all of the Gradle customizations for AndroidX.
@@ -126,6 +133,7 @@
                     if (verifyDependencyVersionsTask != null) {
                         project.createCheckReleaseReadyTask(listOf(verifyDependencyVersionsTask))
                     }
+                    project.createGenerateReleaseNotesTask()
                     project.configureNonAndroidProjectForLint(androidXExtension)
                     project.configureJavaProjectForDokka(androidXExtension)
                     project.configureJavaProjectForMetalava(androidXExtension)
@@ -153,6 +161,7 @@
                     if (checkReleaseReadyTasks.isNotEmpty()) {
                         project.createCheckReleaseReadyTask(checkReleaseReadyTasks)
                     }
+                    project.createGenerateReleaseNotesTask()
                     val reportLibraryMetrics = project.tasks.register(
                         REPORT_LIBRARY_METRICS, ReportLibraryMetricsTask::class.java
                     )
@@ -166,8 +175,10 @@
                             task.dependsOn(libraryVariant.javaCompileProvider)
                         }
                         libraryVariant.javaCompileProvider.configure { task ->
-                            task.options.compilerArgs.add("-Werror")
-                            task.options.compilerArgs.add("-Xlint:unchecked")
+                            project.runIfPartOfBuildOnServer {
+                                task.options.compilerArgs.add("-Werror")
+                                task.options.compilerArgs.add("-Xlint:unchecked")
+                            }
                         }
                     }
                     project.configureLint(extension.lintOptions, androidXExtension)
@@ -183,8 +194,15 @@
                 }
                 is KotlinBasePluginWrapper -> {
                     project.tasks.withType(KotlinCompile::class.java).configureEach { compile ->
-                        compile.kotlinOptions.allWarningsAsErrors = true
                         compile.kotlinOptions.jvmTarget = "1.8"
+                        project.runIfPartOfBuildOnServer {
+                            compile.kotlinOptions.allWarningsAsErrors = true
+                        }
+                    }
+                    if (plugin is KotlinMultiplatformPluginWrapper) {
+                        project.extensions.findByType<LibraryExtension>()?.apply {
+                            configureAndroidLibraryWithMultiplatformPluginOptions()
+                        }
                     }
                 }
             }
@@ -343,6 +361,14 @@
                 }
             }
         }
+        // If we are running buildOnServer, run all actions in buildOnServerDependentActions after
+        // the task graph has been resolved, before we are in the execution phase.
+        project.gradle.taskGraph.whenReady { taskExecutionGraph ->
+            // hasTask requires the task path, so we are looking for the root :buildOnServer task
+            if (taskExecutionGraph.hasTask(":$BUILD_ON_SERVER_TASK")) {
+                buildOnServerDependentActions.forEach { it() }
+            }
+        }
     }
 
     private fun TestedExtension.configureAndroidCommonOptions(
@@ -446,12 +472,25 @@
     }
 
     private fun hasAndroidTestSourceCode(project: Project, extension: TestedExtension): Boolean {
-        val javaSourceSet = extension.sourceSets.findByName("androidTest") ?: return false
-        val hasJava = !javaSourceSet.java.sourceFiles.isEmpty
-        val kotlinExtension =
-            project.extensions.findByType(KotlinProjectExtension::class.java) ?: return hasJava
-        val kotlinSourceSet = kotlinExtension.sourceSets.findByName("androidTest") ?: return hasJava
-        return hasJava || kotlinSourceSet.kotlin.files.isNotEmpty()
+        // check Java androidTest source set
+        extension.sourceSets.findByName("androidTest")?.let { sourceSet ->
+            if (!sourceSet.java.sourceFiles.isEmpty) return true
+        }
+
+        // check kotlin-android androidTest source set
+        project.extensions.findByType(KotlinAndroidProjectExtension::class.java)
+            ?.sourceSets?.findByName("androidTest")?.let {
+            if (it.kotlin.files.isNotEmpty()) return true
+        }
+
+        // check kotlin-multiplatform androidAndroidTest source set
+        project.multiplatformExtension?.apply {
+            sourceSets.findByName("androidAndroidTest")?.let {
+                if (it.kotlin.files.isNotEmpty()) return true
+            }
+        }
+
+        return false
     }
 
     private fun ApkVariant.configureApkCopy(
@@ -525,6 +564,12 @@
         }
     }
 
+    private fun TestedExtension.configureAndroidLibraryWithMultiplatformPluginOptions() {
+        sourceSets.findByName("main")!!.manifest.srcFile("src/androidMain/AndroidManifest.xml")
+        sourceSets.findByName("androidTest")!!
+            .manifest.srcFile("src/androidAndroidTest/AndroidManifest.xml")
+    }
+
     private fun AppExtension.configureAndroidApplicationOptions(project: Project) {
         defaultConfig.apply {
             versionCode = 1
@@ -565,6 +610,37 @@
                 VerifyDependencyVersionsTask::class.java)
     }
 
+    // Task that creates release notes
+    private fun Project.createGenerateReleaseNotesTask() {
+        tasks.register(
+            GENERATE_RELEASE_NOTES_TASK,
+            GenerateReleaseNotesTask::class.java
+        ) { task ->
+            if (project.hasProperty("startCommit")) {
+                task.startSHA = project.property("startCommit").toString()
+            } else {
+                task.startSHA = ""
+            }
+            if (project.hasProperty("endCommit")) {
+                task.endSHA = project.property("endCommit").toString()
+            } else {
+                task.endSHA = "HEAD"
+            }
+            val formatter = DateTimeFormatter.ofPattern("MM-d-yyyy")
+            if (project.hasProperty("releaseDate")) {
+                task.date = LocalDate.parse(project.property("releaseDate").toString(), formatter)
+            } else {
+                task.date = LocalDate.now()
+            }
+            task.outputFile.set(
+                File(
+                    project.getReleaseNotesDirectory(),
+                    "${group}_${name}_release_notes.txt"
+                )
+            )
+        }
+    }
+
     // Task that creates a json file of a project's dependencies
     private fun Project.addCreateLibraryBuildInfoFileTask(extension: AndroidXExtension) {
         afterEvaluate {
@@ -623,6 +699,7 @@
         const val CHECK_SAME_VERSION_LIBRARY_GROUPS = "checkSameVersionLibraryGroups"
         const val CREATE_LIBRARY_BUILD_INFO_FILES_TASK = "createLibraryBuildInfoFiles"
         const val CREATE_AGGREGATE_BUILD_INFO_FILES_TASK = "createAggregateBuildInfoFiles"
+        const val GENERATE_RELEASE_NOTES_TASK = "generateReleaseNotes"
         const val REPORT_LIBRARY_METRICS = "reportLibraryMetrics"
     }
 }
@@ -653,6 +730,9 @@
     }
 }
 
+val Project.multiplatformExtension
+    get() = extensions.findByType(KotlinMultiplatformExtension::class.java)
+
 private fun Project.createCheckResourceApiTask(): DefaultTask {
     return tasks.createWithConfig("checkResourceApi",
             CheckResourceApiTask::class.java) {
@@ -708,3 +788,24 @@
     return File(buildDir, "intermediates/public_res/release" +
             "/packageReleaseResources/public.txt")
 }
+
+/**
+ * Delays execution of the given [action] until the task graph is ready, and we know whether
+ * we are running buildOnServer
+ */
+private fun Project.runIfPartOfBuildOnServer(action: () -> Unit) {
+    buildOnServerDependentActions.add(action)
+}
+
+/**
+ * A list of configuration actions that will only be applied if buildOnServer is part of
+ * the task graph, essentially when we are running ./gradlew buildOnServer
+ */
+private val Project.buildOnServerDependentActions: MutableList<() -> Unit> get() {
+    val extraProperties = rootProject.extensions.extraProperties
+    if (!extraProperties.has(BUILD_ON_SERVER_DEPENDENT_ACTIONS)) {
+        extraProperties.set(BUILD_ON_SERVER_DEPENDENT_ACTIONS, mutableListOf<() -> Unit>())
+    }
+    @Suppress("UNCHECKED_CAST")
+    return extraProperties.get(BUILD_ON_SERVER_DEPENDENT_ACTIONS) as MutableList<() -> Unit>
+}
diff --git a/buildSrc/src/main/kotlin/androidx/build/BuildServerConfiguration.kt b/buildSrc/src/main/kotlin/androidx/build/BuildServerConfiguration.kt
index aa1f726..e273562 100644
--- a/buildSrc/src/main/kotlin/androidx/build/BuildServerConfiguration.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/BuildServerConfiguration.kt
@@ -59,6 +59,12 @@
         File(getDistributionDirectory(), "build-info")
 
 /**
+ * Directory to put release note files for generate release note tasks.
+ */
+fun Project.getReleaseNotesDirectory(): File =
+    File(getDistributionDirectory(), "release-notes")
+
+/**
  * Directory to put host test results so they can be consumed by the testing dashboard.
  */
 fun Project.getHostTestResultDirectory(): File =
diff --git a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
index 9dacda3..ad6816e 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
@@ -20,8 +20,8 @@
  * The list of versions codes of all the libraries in this project.
  */
 object LibraryVersions {
-    val ACTIVITY = Version("1.1.0-alpha02")
-    val ADS_IDENTIFIER = Version("1.0.0-alpha01")
+    val ACTIVITY = Version("1.1.0-alpha03")
+    val ADS_IDENTIFIER = Version("1.0.0-alpha02")
     val ANIMATION = Version("1.0.0-alpha01")
     val ANIMATION_TESTING = Version("1.1.0-alpha01")
     val ANNOTATION = Version("1.2.0-alpha01")
@@ -31,13 +31,13 @@
     val ARCH_CORE_TESTING = ARCH_CORE
     val ARCH_RUNTIME = Version("2.2.0-alpha01")
     val ASYNCLAYOUTINFLATER = Version("1.1.0-alpha01")
-    val AUTOFILL = Version("1.0.0-alpha02")
+    val AUTOFILL = Version("1.0.0-alpha03")
     val BENCHMARK = Version("1.0.0-alpha04")
     val BIOMETRIC = Version("1.0.0-beta01")
-    val BROWSER = Version("1.2.0-alpha07")
-    val CAMERA = Version("1.0.0-alpha04")
-    val CAMERA_EXTENSIONS = Version("1.0.0-alpha01")
-    val CAMERA_VIEW = Version("1.0.0-alpha01")
+    val BROWSER = Version("1.2.0-alpha08")
+    val CAMERA = Version("1.0.0-alpha05")
+    val CAMERA_EXTENSIONS = Version("1.0.0-alpha02")
+    val CAMERA_VIEW = Version("1.0.0-alpha02")
     val CAR = Version("1.0.0-alpha8")
     val CAR_CLUSTER = Version("1.0.0-alpha6")
     val CAR_MODERATOR = Version("1.0.0-alpha1")
@@ -46,7 +46,7 @@
     val CONTENTPAGER = Version("1.1.0-alpha01")
     val COMPOSE = Version("1.0.0-alpha01")
     val COORDINATORLAYOUT = Version("1.1.0-beta02")
-    val CORE = Version("1.2.0-alpha03")
+    val CORE = Version("1.2.0-alpha04")
     val CORE_ROLE = Version("1.0.0-alpha02")
     val CURSORADAPTER = Version("1.1.0-alpha01")
     val CUSTOMVIEW = Version("1.1.0-alpha02")
@@ -55,31 +55,31 @@
     val DYNAMICANIMATION = Version("1.1.0-alpha03")
     val DYNAMICANIMATION_KTX = Version("1.0.0-alpha03")
     val EMOJI = Version("1.1.0-alpha01")
-    val ENTERPRISE = Version("1.0.0-alpha03")
+    val ENTERPRISE = Version("1.0.0-alpha04")
     val EXIFINTERFACE = Version("1.1.0-beta02")
-    val FRAGMENT = Version("1.2.0-alpha02")
+    val FRAGMENT = Version("1.2.0-alpha03")
     val FUTURES = Version("1.0.0-rc01")
     val GRIDLAYOUT = Version("1.1.0-alpha01")
     val HEIFWRITER = Version("1.1.0-alpha01")
     val INSPECTION = Version("1.0.0-alpha01")
     val INTERPOLATOR = Version("1.1.0-alpha01")
-    val JETIFIER = Version("1.0.0-rc01")
+    val JETIFIER = Version("1.0.0-beta06")
     val LEANBACK = Version("1.1.0-alpha03")
     val LEANBACK_PREFERENCE = Version("1.1.0-alpha03")
     val LEGACY = Version("1.1.0-alpha01")
     val LOCALBROADCASTMANAGER = Version("1.1.0-alpha02")
-    val LIFECYCLE = Version("2.2.0-alpha03")
+    val LIFECYCLE = Version("2.2.0-alpha04")
     val LIFECYCLE_EXTENSIONS = LIFECYCLE
-    val LIFECYCLES_SAVEDSTATE = Version("1.0.0-alpha03")
+    val LIFECYCLES_SAVEDSTATE = Version("1.0.0-alpha04")
     val LOADER = Version("1.2.0-alpha01")
     val MEDIA = Version("1.2.0-alpha01")
     val MEDIA2_COMMON = Version("1.1.0-alpha01")
     val MEDIA2_PLAYER = Version("1.1.0-alpha01")
     val MEDIA2_SESSION = Version("1.1.0-alpha01")
     val MEDIA2_EXOPLAYER = Version("1.0.0-rc01")
-    val MEDIA2_WIDGET = Version("1.0.0-beta02")
+    val MEDIA2_WIDGET = Version("1.0.0-rc02")
     val MEDIAROUTER = Version("1.2.0-alpha01")
-    val NAVIGATION = Version("2.2.0-alpha01")
+    val NAVIGATION = Version("2.2.0-alpha02")
     val NAVIGATION_TESTING = Version("1.0.0-alpha08") // Unpublished
     val PAGING = Version("3.0.0-alpha01")
     val PALETTE = Version("1.1.0-alpha01")
@@ -87,10 +87,10 @@
     val PERCENTLAYOUT = Version("1.1.0-alpha01")
     val PREFERENCE = Version("1.2.0-alpha01")
     val RECOMMENDATION = Version("1.1.0-alpha01")
-    val RECYCLERVIEW = Version("1.1.0-beta02")
+    val RECYCLERVIEW = Version("1.1.0-beta03")
     val RECYCLERVIEW_SELECTION = Version("1.1.0-alpha07")
     val REMOTECALLBACK = Version("1.0.0-alpha02")
-    val ROOM = Version("2.2.0-alpha02")
+    val ROOM = Version("2.2.0-alpha03")
     val SAVEDSTATE = Version("1.0.0-rc01")
     val SECURITY = Version("1.0.0-alpha03")
     val SECURITY_IDENTITY_CREDENTIAL = Version("1.0.0-alpha01")
@@ -110,8 +110,8 @@
     val VECTORDRAWABLE_ANIMATED = Version("1.2.0-alpha01")
     val VERSIONED_PARCELABLE = Version("1.2.0-alpha01")
     val VIEWPAGER = Version("1.1.0-alpha01")
-    val VIEWPAGER2 = Version("1.0.0-beta03")
+    val VIEWPAGER2 = Version("1.0.0-beta04")
     val WEAR = Version("1.1.0-alpha01")
-    val WEBKIT = Version("1.1.0-alpha02")
+    val WEBKIT = Version("1.1.0-alpha03")
     val WORK = Version("2.3.0-alpha01")
 }
diff --git a/buildSrc/src/main/kotlin/androidx/build/LintConfiguration.kt b/buildSrc/src/main/kotlin/androidx/build/LintConfiguration.kt
index 9717aec..0eb08b4 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LintConfiguration.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LintConfiguration.kt
@@ -82,9 +82,12 @@
                     fatal("UnusedResources")
                     fatal("KotlinPropertyAccess")
                     fatal("LambdaLast")
-                    fatal("NoHardKeywords")
                     fatal("UnknownNullness")
 
+                    // suppress warnings more specifically than issue-wide severity (regexes)
+                    // Currently suppresses warnings from baseline files working as intended
+                    lintConfig = project.rootProject.file("buildSrc/lint.xml")
+
                     // Only override if not set explicitly.
                     // Some Kotlin projects may wish to disable this.
                     if (lintOptions.severityOverrides["SyntheticAccessor"] == null) {
diff --git a/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt b/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt
index 810d38b..3b440fe 100644
--- a/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt
@@ -28,23 +28,23 @@
  * Rule set used to generate public documentation.
  */
 val RELEASE_RULE = docsRules("public", false) {
-    prebuilts(LibraryGroups.ACTIVITY, "1.1.0-alpha01")
+    prebuilts(LibraryGroups.ACTIVITY, "1.1.0-alpha02")
+    prebuilts(LibraryGroups.ADS, "1.0.0-alpha01")
     prebuilts(LibraryGroups.ANNOTATION, "annotation", "1.1.0")
     prebuilts(LibraryGroups.APPCOMPAT, "1.1.0-rc01")
-    prebuilts(LibraryGroups.ARCH_CORE, "2.1.0-rc01")
+    prebuilts(LibraryGroups.ARCH_CORE, "2.1.0")
     prebuilts(LibraryGroups.ASYNCLAYOUTINFLATER, "1.0.0")
-    prebuilts(LibraryGroups.AUTOFILL, "1.0.0-alpha01")
-    prebuilts(LibraryGroups.BENCHMARK, "benchmark", "1.0.0-alpha03")
-    ignore(LibraryGroups.BENCHMARK.group, "benchmark-common")
+    prebuilts(LibraryGroups.AUTOFILL, "1.0.0-alpha02")
     ignore(LibraryGroups.BENCHMARK.group, "benchmark-gradle-plugin")
-    prebuilts(LibraryGroups.BIOMETRIC, "biometric", "1.0.0-alpha04")
-    prebuilts(LibraryGroups.BROWSER, "1.0.0")
-    ignore(LibraryGroups.CAMERA.group, "camera-view")
+    prebuilts(LibraryGroups.BENCHMARK, "1.0.0-alpha04")
+    prebuilts(LibraryGroups.BIOMETRIC, "biometric", "1.0.0-beta01")
+    prebuilts(LibraryGroups.BROWSER, "1.2.0-alpha07")
     ignore(LibraryGroups.CAMERA.group, "camera-testing")
-    ignore(LibraryGroups.CAMERA.group, "camera-extensions")
     ignore(LibraryGroups.CAMERA.group, "camera-extensions-stub")
     ignore(LibraryGroups.CAMERA.group, "camera-testlib-extensions")
-    prebuilts(LibraryGroups.CAMERA, "1.0.0-alpha03")
+    prebuilts(LibraryGroups.CAMERA, "camera-view", "1.0.0-alpha01")
+    prebuilts(LibraryGroups.CAMERA, "camera-extensions", "1.0.0-alpha01")
+    prebuilts(LibraryGroups.CAMERA, "1.0.0-alpha04")
     ignore(LibraryGroups.CAR.group, "car-moderator")
     prebuilts(LibraryGroups.CAR, "car-cluster", "1.0.0-alpha5")
     prebuilts(LibraryGroups.CAR, "car", "1.0.0-alpha7")
@@ -54,19 +54,19 @@
     prebuilts(LibraryGroups.CONCURRENT, "1.0.0-rc01")
     prebuilts(LibraryGroups.CONTENTPAGER, "1.0.0")
     prebuilts(LibraryGroups.COORDINATORLAYOUT, "1.1.0-beta01")
-    prebuilts(LibraryGroups.CORE, "core", "1.2.0-alpha02")
-    prebuilts(LibraryGroups.CORE, "core-ktx", "1.2.0-alpha02")
+    prebuilts(LibraryGroups.CORE, "core", "1.2.0-alpha03")
+    prebuilts(LibraryGroups.CORE, "core-ktx", "1.2.0-alpha03")
     prebuilts(LibraryGroups.CORE, "core-role", "1.0.0-alpha01")
     prebuilts(LibraryGroups.CURSORADAPTER, "1.0.0")
     prebuilts(LibraryGroups.CUSTOMVIEW, "1.1.0-alpha01")
     prebuilts(LibraryGroups.DOCUMENTFILE, "1.0.0")
-    prebuilts(LibraryGroups.DRAWERLAYOUT, "1.1.0-alpha02")
+    prebuilts(LibraryGroups.DRAWERLAYOUT, "1.1.0-alpha03")
     prebuilts(LibraryGroups.DYNAMICANIMATION, "dynamicanimation-ktx", "1.0.0-alpha02")
     prebuilts(LibraryGroups.DYNAMICANIMATION, "1.1.0-alpha02")
     prebuilts(LibraryGroups.EMOJI, "1.0.0")
     prebuilts(LibraryGroups.ENTERPRISE, "1.0.0-alpha03")
     prebuilts(LibraryGroups.EXIFINTERFACE, "1.1.0-beta01")
-    prebuilts(LibraryGroups.FRAGMENT, "1.2.0-alpha01")
+    prebuilts(LibraryGroups.FRAGMENT, "1.2.0-alpha02")
     prebuilts(LibraryGroups.GRIDLAYOUT, "1.0.0")
     prebuilts(LibraryGroups.HEIFWRITER, "1.0.0")
     prebuilts(LibraryGroups.INTERPOLATOR, "1.0.0")
@@ -74,8 +74,8 @@
     prebuilts(LibraryGroups.LEGACY, "1.0.0")
     ignore(LibraryGroups.LIFECYCLE.group, "lifecycle-compiler")
     ignore(LibraryGroups.LIFECYCLE.group, "lifecycle-runtime-ktx-lint")
-    prebuilts(LibraryGroups.LIFECYCLE, "lifecycle-viewmodel-savedstate", "1.0.0-alpha02")
-    prebuilts(LibraryGroups.LIFECYCLE, "2.2.0-alpha02")
+    prebuilts(LibraryGroups.LIFECYCLE, "lifecycle-viewmodel-savedstate", "1.0.0-alpha03")
+    prebuilts(LibraryGroups.LIFECYCLE, "2.2.0-alpha03")
     ignore(LibraryGroups.LOADER.group, "loader-ktx")
     prebuilts(LibraryGroups.LOADER, "1.1.0-rc01")
     prebuilts(LibraryGroups.LOCALBROADCASTMANAGER, "1.1.0-alpha01")
@@ -87,7 +87,7 @@
     ignore(LibraryGroups.NAVIGATION.group, "navigation-testing")
     ignore(LibraryGroups.NAVIGATION.group, "navigation-safe-args-generator")
     ignore(LibraryGroups.NAVIGATION.group, "navigation-safe-args-gradle-plugin")
-    prebuilts(LibraryGroups.NAVIGATION, "2.1.0-beta02")
+    prebuilts(LibraryGroups.NAVIGATION, "2.2.0-alpha01")
     prebuilts(LibraryGroups.PAGING, "2.1.0")
     prebuilts(LibraryGroups.PALETTE, "1.0.0")
     prebuilts(LibraryGroups.PERCENTLAYOUT, "1.0.0")
@@ -95,11 +95,11 @@
     prebuilts(LibraryGroups.PREFERENCE, "1.1.0-rc01")
     prebuilts(LibraryGroups.PRINT, "1.0.0")
     prebuilts(LibraryGroups.RECOMMENDATION, "1.0.0")
-    prebuilts(LibraryGroups.RECYCLERVIEW, "recyclerview", "1.1.0-beta01")
+    prebuilts(LibraryGroups.RECYCLERVIEW, "recyclerview", "1.1.0-beta03")
     prebuilts(LibraryGroups.RECYCLERVIEW, "recyclerview-selection", "1.1.0-alpha06")
     prebuilts(LibraryGroups.REMOTECALLBACK, "1.0.0-alpha02")
-    prebuilts(LibraryGroups.ROOM, "2.2.0-alpha01")
-    prebuilts(LibraryGroups.SAVEDSTATE, "1.0.0-beta01")
+    prebuilts(LibraryGroups.ROOM, "2.2.0-alpha02")
+    prebuilts(LibraryGroups.SAVEDSTATE, "1.0.0")
     // TODO: Remove this ignore once androidx.security:security-identity-credential:1.0.0-alpha01 is released
     ignore(LibraryGroups.SECURITY.group, "security-identity-credential")
     prebuilts(LibraryGroups.SECURITY, "1.0.0-alpha02")
@@ -121,13 +121,13 @@
     prebuilts(LibraryGroups.VECTORDRAWABLE, "vectordrawable-animated", "1.1.0-rc01")
     prebuilts(LibraryGroups.VERSIONEDPARCELABLE, "1.1.0")
     prebuilts(LibraryGroups.VIEWPAGER, "1.0.0")
-    prebuilts(LibraryGroups.VIEWPAGER2, "1.0.0-beta02")
+    prebuilts(LibraryGroups.VIEWPAGER2, "1.0.0-beta03")
     prebuilts(LibraryGroups.WEAR, "1.0.0")
             .addStubs("wear/wear_stubs/com.google.android.wearable-stubs.jar")
-    prebuilts(LibraryGroups.WEBKIT, "1.1.0-alpha01")
+    prebuilts(LibraryGroups.WEBKIT, "1.1.0-alpha02")
     ignore(LibraryGroups.WORK.group, "work-gcm")
     ignore(LibraryGroups.WORK.group, "work-foreground")
-    prebuilts(LibraryGroups.WORK, "2.2.0-rc01")
+    prebuilts(LibraryGroups.WORK, "2.2.0")
     default(Ignore)
 }
 
diff --git a/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt b/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
index 7c83e43..c034033 100644
--- a/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
@@ -16,6 +16,7 @@
 
 package androidx.build.dependencies
 
+const val ANDROID_GRADLE_PLUGIN = "com.android.tools.build:gradle:3.4.2"
 const val ANDROIDX_TEST_CORE = "androidx.test:core:1.1.0"
 const val ANDROIDX_TEST_EXT_JUNIT = "androidx.test.ext:junit:1.1.0"
 const val ANDROIDX_TEST_EXT_KTX = "androidx.test.ext:junit-ktx:1.1.0"
@@ -39,8 +40,10 @@
 const val GCM_NETWORK_MANAGER = "com.google.android.gms:play-services-gcm:17.0.0"
 const val GOOGLE_COMPILE_TESTING = "com.google.testing.compile:compile-testing:0.18"
 const val GSON = "com.google.code.gson:gson:2.8.0"
-const val GUAVA = "com.google.guava:guava:27.0.1-jre"
-const val GUAVA_ANDROID = "com.google.guava:guava:27.0.1-android"
+const val GUAVA_VERSION = "27.0.1-jre"
+const val GUAVA = "com.google.guava:guava:$GUAVA_VERSION"
+const val GUAVA_ANDROID_VERSION = "27.0.1-android"
+const val GUAVA_ANDROID = "com.google.guava:guava:$GUAVA_ANDROID_VERSION"
 const val GUAVA_LISTENABLE_FUTURE = "com.google.guava:listenablefuture:1.0"
 const val INTELLIJ_ANNOTATIONS = "com.intellij:annotations:12.0"
 const val JAVAPOET = "com.squareup:javapoet:1.8.0"
@@ -49,6 +52,7 @@
 const val KOTLINPOET = "com.squareup:kotlinpoet:1.1.0"
 
 private const val KOTLIN_VERSION = "1.3.41"
+const val KOTLIN_GRADLE_PLUGIN = "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.20"
 const val KOTLIN_STDLIB = "org.jetbrains.kotlin:kotlin-stdlib:$KOTLIN_VERSION"
 const val KOTLIN_TEST_COMMON = "org.jetbrains.kotlin:kotlin-test:$KOTLIN_VERSION"
 const val COMPOSE_VERSION = "1.3.30-compose-20190520"
@@ -69,8 +73,14 @@
     "org.jetbrains.kotlinx:kotlinx-coroutines-guava:$KOTLIN_COROUTINES_VERSION"
 const val KOTLIN_COROUTINES_TEST =
     "org.jetbrains.kotlinx:kotlinx-coroutines-test:$KOTLIN_COROUTINES_VERSION"
+
+private const val KOTLIN_COROUTINES_PREVIEW_VERSION = "1.3.0-RC2"
 const val KOTLIN_COROUTINES_PREVIEW =
-    "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0-RC"
+    "org.jetbrains.kotlinx:kotlinx-coroutines-android:$KOTLIN_COROUTINES_PREVIEW_VERSION"
+const val KOTLIN_COROUTINES_CORE_PREVIEW =
+    "org.jetbrains.kotlinx:kotlinx-coroutines-core:$KOTLIN_COROUTINES_PREVIEW_VERSION"
+const val KOTLIN_COROUTINES_TEST_PREVIEW =
+    "org.jetbrains.kotlinx:kotlinx-coroutines-test:$KOTLIN_COROUTINES_PREVIEW_VERSION"
 
 const val LEAKCANARY_INSTRUMENTATION =
     "com.squareup.leakcanary:leakcanary-android-instrumentation:1.6.2"
@@ -117,10 +127,6 @@
 const val ARCH_CORE_RUNTIME = "androidx.arch.core:core-runtime:2.0.1"
 const val ARCH_CORE_TESTING = "androidx.arch.core:core-testing:2.0.1"
 
-const val SAFE_ARGS_ANDROID_GRADLE_PLUGIN = "com.android.tools.build:gradle:3.4.0"
-const val SAFE_ARGS_KOTLIN_GRADLE_PLUGIN = "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.20"
-const val SAFE_ARGS_NAVIGATION_COMMON = "androidx.navigation:navigation-common:2.0.0-rc02"
-
 const val ARCH_PAGING_COMMON = "androidx.paging:paging-common:2.0.0"
 const val ARCH_PAGING_RUNTIME = "androidx.paging:paging-runtime:2.0.0"
 const val ARCH_ROOM_RUNTIME = "androidx.room:room-runtime:2.0.0"
@@ -128,6 +134,8 @@
 const val ARCH_ROOM_RXJAVA = "androidx.room:room-rxjava2:2.0.0"
 const val ARCH_ROOM_TESTING = "androidx.room:room-testing:2.0.0"
 
+const val NAVIGATION_COMMON = "androidx.navigation:navigation-common:2.0.0-rc02"
+
 const val WORK_ARCH_CORE_RUNTIME = "androidx.arch.core:core-runtime:2.0.0"
 const val WORK_ARCH_CORE_TESTING = "androidx.arch.core:core-testing:2.0.0"
 const val WORK_ARCH_ROOM_RUNTIME = "androidx.room:room-runtime:2.1.0"
diff --git a/buildSrc/src/main/kotlin/androidx/build/dependencyTracker/AffectedModuleDetector.kt b/buildSrc/src/main/kotlin/androidx/build/dependencyTracker/AffectedModuleDetector.kt
index d3df2ff..a93b352 100644
--- a/buildSrc/src/main/kotlin/androidx/build/dependencyTracker/AffectedModuleDetector.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/dependencyTracker/AffectedModuleDetector.kt
@@ -20,6 +20,8 @@
 import androidx.build.dependencyTracker.AffectedModuleDetector.Companion.DEPENDENT_PROJECTS_ARG
 import androidx.build.dependencyTracker.AffectedModuleDetector.Companion.ENABLE_ARG
 import androidx.build.getDistributionDirectory
+import androidx.build.gitclient.GitClient
+import androidx.build.gitclient.GitClientImpl
 import androidx.build.gradle.isRoot
 import androidx.build.isRunningOnBuildServer
 import java.io.File
diff --git a/buildSrc/src/main/kotlin/androidx/build/dependencyTracker/GitClient.kt b/buildSrc/src/main/kotlin/androidx/build/dependencyTracker/GitClient.kt
deleted file mode 100644
index 486df04..0000000
--- a/buildSrc/src/main/kotlin/androidx/build/dependencyTracker/GitClient.kt
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright 2018 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.build.dependencyTracker
-
-import org.gradle.api.logging.Logger
-import java.io.File
-import java.util.concurrent.TimeUnit
-
-interface GitClient {
-    fun findChangedFilesSince(
-        sha: String,
-        top: String = "HEAD",
-        includeUncommitted: Boolean = false
-    ): List<String>
-    fun findPreviousMergeCL(): String?
-
-    /**
-     * Abstraction for running execution commands for testability
-     */
-    interface CommandRunner {
-        /**
-         * Executes the given shell command and returns the stdout by lines.
-         */
-        fun execute(command: String): List<String>
-    }
-}
-/**
- * A simple git client that uses system process commands to communicate with the git setup in the
- * given working directory.
- */
-class GitClientImpl(
-    /**
-     * The root location for git
-     */
-    private val workingDir: File,
-    private val logger: Logger? = null,
-    private val commandRunner: GitClient.CommandRunner = RealCommandRunner(
-            workingDir = workingDir,
-            logger = logger
-    )
-) : GitClient {
-    /**
-     * Finds changed file paths since the given sha
-     */
-    override fun findChangedFilesSince(
-        sha: String,
-        top: String,
-        includeUncommitted: Boolean
-    ): List<String> {
-        // use this if we don't want local changes
-        return if (includeUncommitted) {
-            "$CHANGED_FILES_CMD_PREFIX $sha"
-        } else {
-            "$CHANGED_FILES_CMD_PREFIX $top $sha"
-        }.runCommand()
-    }
-
-    /**
-     * checks the history to find the first merge CL.
-     */
-    override fun findPreviousMergeCL(): String? {
-        return PREV_MERGE_CMD
-                .runCommand()
-                .firstOrNull()
-                ?.split(" ")
-                ?.firstOrNull()
-    }
-
-    private fun String.runCommand() = commandRunner.execute(this)
-
-    private class RealCommandRunner(
-        private val workingDir: File,
-        private val logger: Logger?
-    ) : GitClient.CommandRunner {
-        override fun execute(command: String): List<String> {
-            val parts = command.split("\\s".toRegex())
-            logger?.info("running command $command")
-            val proc = ProcessBuilder(*parts.toTypedArray())
-                    .directory(workingDir)
-                    .redirectOutput(ProcessBuilder.Redirect.PIPE)
-                    .redirectError(ProcessBuilder.Redirect.PIPE)
-                    .start()
-
-            proc.waitFor(1, TimeUnit.MINUTES)
-            val response = proc
-                    .inputStream
-                    .bufferedReader()
-                    .readLines()
-                    .filterNot {
-                        it.isEmpty()
-                    }
-            logger?.info("Response: ${response.joinToString(System.lineSeparator())}")
-            return response
-        }
-    }
-
-    companion object {
-        const val PREV_MERGE_CMD = "git log -1 --merges --oneline"
-        const val CHANGED_FILES_CMD_PREFIX = "git diff --name-only"
-    }
-}
diff --git a/buildSrc/src/main/kotlin/androidx/build/dokka/Dokka.kt b/buildSrc/src/main/kotlin/androidx/build/dokka/Dokka.kt
index fd330de..4a5b2f7 100644
--- a/buildSrc/src/main/kotlin/androidx/build/dokka/Dokka.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/dokka/Dokka.kt
@@ -20,6 +20,7 @@
 
 import androidx.build.AndroidXExtension
 import androidx.build.DiffAndDocs
+import androidx.build.dependencies.GUAVA_VERSION
 import androidx.build.getBuildId
 import androidx.build.getDistributionDirectory
 import com.android.build.gradle.LibraryExtension
@@ -28,10 +29,12 @@
 import org.gradle.api.tasks.TaskProvider
 import org.gradle.api.tasks.bundling.Zip
 import org.gradle.kotlin.dsl.apply
+import org.jetbrains.dokka.DokkaConfiguration
 import org.jetbrains.dokka.gradle.DokkaAndroidPlugin
 import org.jetbrains.dokka.gradle.DokkaAndroidTask
 import org.jetbrains.dokka.gradle.PackageOptions
 import java.io.File
+import java.net.URL
 
 object Dokka {
     fun generatorTaskNameForType(docsType: String, language: String = ""): String {
@@ -105,6 +108,14 @@
 
         val docTaskName = generatorTaskNameForType(docsType, language)
 
+        val guavaDocLink = DokkaConfiguration.ExternalDocumentationLink.Builder().apply {
+            this.url = URL("https://guava.dev/releases/$GUAVA_VERSION/api/docs/")
+            // Guava documentation doesn't have the necessary package-list file to provide the packages
+            // to Dokka so we have to host a file internally as a workaround
+            this.packageListUrl = project.projectDir.toPath()
+                .resolve("guava-package.list").toUri().toURL()
+        }.build()
+
         return project.tasks.register(docTaskName, DokkaAndroidTask::class.java) { task ->
             task.moduleName = project.name
             task.outputDirectory = File(project.buildDir, docTaskName).absolutePath
@@ -114,6 +125,7 @@
             task.outlineRoot = "androidx/"
             task.dacRoot = dacRoot
             task.moduleName = ""
+            task.externalDocumentationLinks.add(guavaDocLink)
             for (hiddenPackage in hiddenPackages) {
                 val opts = PackageOptions()
                 opts.prefix = hiddenPackage
diff --git a/buildSrc/src/main/kotlin/androidx/build/dokka/DokkaPublicDocs.kt b/buildSrc/src/main/kotlin/androidx/build/dokka/DokkaPublicDocs.kt
index c793a8c..68670c0 100644
--- a/buildSrc/src/main/kotlin/androidx/build/dokka/DokkaPublicDocs.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/dokka/DokkaPublicDocs.kt
@@ -180,7 +180,7 @@
             configuration.resolvedConfiguration.resolvedArtifacts
         } catch (e: ResolveException) {
             runnerProject.logger.error("DokkaPublicDocs failed to find prebuilts for $mavenId. " +
-                    "specified in publichDocsRules.kt ." +
+                    "specified in PublishDocsRules.kt ." +
                     "You should either add a prebuilt sources jar, " +
                     "or add an overriding \"ignore\" rule into PublishDocsRules.kt")
             throw e
diff --git a/buildSrc/src/main/kotlin/androidx/build/dokka/DokkaSourceDocs.kt b/buildSrc/src/main/kotlin/androidx/build/dokka/DokkaSourceDocs.kt
index 80826b3..459596b 100644
--- a/buildSrc/src/main/kotlin/androidx/build/dokka/DokkaSourceDocs.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/dokka/DokkaSourceDocs.kt
@@ -89,7 +89,7 @@
         }
         library.defaultPublishVariant { variant ->
             project.afterEvaluate {
-                val inputs = JavaCompileInputs.fromLibraryVariant(library, variant)
+                val inputs = JavaCompileInputs.fromLibraryVariant(library, variant, project)
                 registerInputs(inputs, project)
             }
         }
diff --git a/buildSrc/src/main/kotlin/androidx/build/gitclient/GitClient.kt b/buildSrc/src/main/kotlin/androidx/build/gitclient/GitClient.kt
new file mode 100644
index 0000000..7419cc0
--- /dev/null
+++ b/buildSrc/src/main/kotlin/androidx/build/gitclient/GitClient.kt
@@ -0,0 +1,347 @@
+/*
+ * Copyright 2018 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.build.gitclient
+
+import androidx.build.releasenotes.getAOSPLink
+import androidx.build.releasenotes.getBuganizerLink
+import org.gradle.api.logging.Logger
+import java.io.File
+import java.util.concurrent.TimeUnit
+
+interface GitClient {
+    fun findChangedFilesSince(
+        sha: String,
+        top: String = "HEAD",
+        includeUncommitted: Boolean = false
+    ): List<String>
+    fun findPreviousMergeCL(): String?
+
+    fun getGitLog(
+        sha: String,
+        top: String = "HEAD",
+        keepMerges: Boolean,
+        fullProjectDir: File
+    ): List<Commit>
+
+    /**
+     * Abstraction for running execution commands for testability
+     */
+    interface CommandRunner {
+        /**
+         * Executes the given shell command and returns the stdout as a string.
+         */
+        fun execute(command: String): String
+        /**
+         * Executes the given shell command and returns the stdout by lines.
+         */
+        fun executeAndParse(command: String): List<String>
+    }
+}
+/**
+ * A simple git client that uses system process commands to communicate with the git setup in the
+ * given working directory.
+ */
+class GitClientImpl(
+    /**
+     * The root location for git
+     */
+    private val workingDir: File,
+    private val logger: Logger? = null,
+    private val commandRunner: GitClient.CommandRunner = RealCommandRunner(
+            workingDir = workingDir,
+            logger = logger
+    )
+) : GitClient {
+
+    private val gitRoot: File = findGitDirInParentFilepath(workingDir) ?: workingDir
+
+    /**
+     * Finds changed file paths since the given sha
+     */
+    override fun findChangedFilesSince(
+        sha: String,
+        top: String,
+        includeUncommitted: Boolean
+    ): List<String> {
+        // use this if we don't want local changes
+        return commandRunner.executeAndParse(if (includeUncommitted) {
+            "$CHANGED_FILES_CMD_PREFIX $sha"
+        } else {
+            "$CHANGED_FILES_CMD_PREFIX $top $sha"
+        })
+    }
+
+    /**
+     * checks the history to find the first merge CL.
+     */
+    override fun findPreviousMergeCL(): String? {
+        return commandRunner.executeAndParse(PREV_MERGE_CMD)
+                .firstOrNull()
+                ?.split(" ")
+                ?.firstOrNull()
+    }
+
+    private fun findGitDirInParentFilepath(filepath: File): File? {
+        var curDirectory: File = filepath
+        while (curDirectory.path != "/") {
+            if (File("$curDirectory/.git").exists()) {
+                return curDirectory
+            }
+            curDirectory = curDirectory.parentFile
+        }
+        return null
+    }
+
+    /**
+     * Converts a diff log command into a [List<Commit>]
+     *
+     * @param sha the SHA at which the git log starts.
+     * @param top the last SHA included in the git log.
+     * @param keepMerges boolean for whether or not to add merges to the return [List<Commit>].
+     * @param fullProjectDir a [File] object that represents the full project directory.
+     */
+    override fun getGitLog(
+        sha: String,
+        top: String,
+        keepMerges: Boolean,
+        fullProjectDir: File
+    ): List<Commit> {
+        val commitStartDelimiter: String = "_CommitStart"
+        val commitSHADelimiter: String = "_CommitSHA:"
+        val subjectDelimiter: String = "_Subject:"
+        val authorEmailDelimiter: String = "_Author:"
+        val dateDelimiter: String = "_Date:"
+        val bodyDelimiter: String = "_Body:"
+        val localProjectDir: String = fullProjectDir.toString()
+            .removePrefix(gitRoot.toString())
+
+        var gitLogOptions: String =
+            "--pretty=format:$commitStartDelimiter%n" +
+                    "$commitSHADelimiter%H%n" +
+                    "$authorEmailDelimiter%ae%n" +
+                    "$dateDelimiter%ad%n" +
+                    "$subjectDelimiter%s%n" +
+                    "$bodyDelimiter%b" +
+                    if (!keepMerges) {
+                        " --no-merges"
+                    } else {
+                        ""
+                    }
+        val gitLogCmd: String = "$GIT_LOG_CMD_PREFIX $gitLogOptions $sha..$top $fullProjectDir"
+        val gitLogString: String = commandRunner.execute(gitLogCmd)
+
+        // Split commits string out into individual commits (note: this removes the deliminter)
+        val gitLogStringList: List<String>? = gitLogString.split(commitStartDelimiter)
+        var commitLog: MutableList<Commit> = mutableListOf()
+        gitLogStringList?.filter { gitCommit ->
+            gitCommit.trim() != ""
+        }?.forEach { gitCommit ->
+            commitLog.add(
+                Commit(
+                    gitCommit,
+                    localProjectDir,
+                    commitSHADelimiter = commitSHADelimiter,
+                    subjectDelimiter = subjectDelimiter,
+                    authorEmailDelimiter = authorEmailDelimiter
+                ))
+        }
+        return commitLog.toList()
+    }
+
+    private class RealCommandRunner(
+        private val workingDir: File,
+        private val logger: Logger?
+    ) : GitClient.CommandRunner {
+        override fun execute(command: String): String {
+            val parts = command.split("\\s".toRegex())
+            logger?.info("running command $command")
+            val proc = ProcessBuilder(*parts.toTypedArray())
+                .directory(workingDir)
+                .redirectOutput(ProcessBuilder.Redirect.PIPE)
+                .redirectError(ProcessBuilder.Redirect.PIPE)
+                .start()
+
+            proc.waitFor(1, TimeUnit.MINUTES)
+            val response = proc
+                .inputStream
+                .bufferedReader()
+                .readText()
+            logger?.info("Response: $response")
+            return response
+        }
+        override fun executeAndParse(command: String): List<String> {
+            val response = execute(command)
+                .split(System.lineSeparator())
+                .filterNot {
+                    it.isEmpty()
+                }
+            return response
+        }
+    }
+
+    companion object {
+        const val PREV_MERGE_CMD = "git log -1 --merges --oneline"
+        const val CHANGED_FILES_CMD_PREFIX = "git diff --name-only"
+        const val GIT_LOG_CMD_PREFIX = "git log --name-only"
+    }
+}
+
+enum class CommitType {
+    NEW_FEATURE, API_CHANGE, BUG_FIX, EXTERNAL_CONTRIBUTION;
+    companion object {
+        fun getTitle(commitType: CommitType): String {
+            return when (commitType) {
+                NEW_FEATURE -> "New Features"
+                API_CHANGE -> "API Changes"
+                BUG_FIX -> "Bug Fixes"
+                EXTERNAL_CONTRIBUTION -> "External Contribution"
+            }
+        }
+    }
+}
+
+/**
+ * Class implementation of a git commit.  It uses the input delimiters to parse the commit
+ *
+ * @property gitCommit a string representation of a git commit
+ * @property projectDir the project directory for which to parse file paths from a commit
+ * @property commitSHADelimiter the term to use to search for the commit SHA
+ * @property subjectDelimiter the term to use to search for the subject (aka commit summary)
+ * @property changeIdDelimiter the term to use to search for the change-id in the body of the commit
+ *           message
+ * @property authorEmailDelimiter the term to use to search for the author email
+ */
+data class Commit(
+    val gitCommit: String,
+    val projectDir: String,
+    private val commitSHADelimiter: String = "_CommitSHA:",
+    private val subjectDelimiter: String = "_Subject:",
+    private val authorEmailDelimiter: String = "_Author:"
+) {
+    private val changeIdDelimiter: String = "Change-Id:"
+    var bugs: MutableList<Int> = mutableListOf()
+    var files: MutableList<String> = mutableListOf()
+    var sha: String = ""
+    var authorEmail: String = ""
+    var changeId: String = ""
+    var summary: String = ""
+    var type: CommitType = CommitType.BUG_FIX
+
+    init {
+        val listedCommit: List<String> = gitCommit.split('\n')
+        listedCommit.filter { line -> line.trim() != "" }.forEach { line ->
+            if (commitSHADelimiter in line) {
+                getSHAFromGitLine(line)
+            }
+            if (subjectDelimiter in line) {
+                getSummary(line)
+            }
+            if (changeIdDelimiter in line) {
+                getChangeIdFromGitLine(line)
+            }
+            if (authorEmailDelimiter in line) {
+                getAuthorEmailFromGitLine(line)
+            }
+            if ("Bug:" in line ||
+                "b/" in line ||
+                "bug:" in line ||
+                "Fixes:" in line ||
+                "fixes b/" in line
+            ) {
+                getBugsFromGitLine(line)
+            }
+            if (projectDir.trim('/') in line) {
+                getFileFromGitLine(line)
+            }
+        }
+    }
+
+    private fun isExternalAuthorEmail(authorEmail: String): Boolean {
+        return !(authorEmail.contains("@google.com"))
+    }
+
+    /**
+     * Parses SHAs from git commit line, with the format:
+     * [Commit.commitSHADelimiter] <commitSHA>
+     */
+    private fun getSHAFromGitLine(line: String) {
+        sha = line.substringAfter(commitSHADelimiter).trim()
+    }
+
+    /**
+     * Parses subject from git commit line, with the format:
+     * [Commit.subjectDelimiter]<commit subject>
+     */
+    private fun getSummary(line: String) {
+        summary = line.substringAfter(subjectDelimiter).trim()
+    }
+
+    /**
+     * Parses commit Change-Id lines, with the format:
+     * `commit.changeIdDelimiter` <changeId>
+     */
+    private fun getChangeIdFromGitLine(line: String) {
+        changeId = line.substringAfter(changeIdDelimiter).trim()
+    }
+
+    /**
+     * Parses commit author lines, with the format:
+     * [Commit.authorEmailDelimiter]email@google.com
+     */
+    private fun getAuthorEmailFromGitLine(line: String) {
+        authorEmail = line.substringAfter(authorEmailDelimiter).trim()
+        if (isExternalAuthorEmail(authorEmail)) {
+            type = CommitType.EXTERNAL_CONTRIBUTION
+        }
+    }
+
+    /**
+     * Parses filepath to get changed files from commit, with the format:
+     * {project_directory}/{filepath}
+     */
+    private fun getFileFromGitLine(filepath: String) {
+        files.add(filepath.trim())
+        if (filepath.contains("current.txt") && type != CommitType.EXTERNAL_CONTRIBUTION) {
+            type = CommitType.API_CHANGE
+        }
+    }
+
+    /**
+     *  Parses bugs from a git commit message line
+     */
+    private fun getBugsFromGitLine(line: String) {
+        var formattedLine = line.replace("b/", " ")
+        formattedLine = formattedLine.replace(":", " ")
+        formattedLine = formattedLine.replace(",", " ")
+        var words: List<String> = formattedLine.split(' ')
+        words.forEach { word ->
+            var possibleBug: Int? = word.toIntOrNull()
+            if (possibleBug != null && possibleBug > 1000) {
+                bugs.add(possibleBug)
+            }
+        }
+    }
+
+    override fun toString(): String {
+        var commitString: String = summary
+        commitString += " ${getAOSPLink(changeId)}"
+        bugs.forEach { bug ->
+            commitString += " ${getBuganizerLink(bug)}"
+        }
+        return commitString
+    }
+}
diff --git a/buildSrc/src/main/kotlin/androidx/build/java/JavaCompileInputs.kt b/buildSrc/src/main/kotlin/androidx/build/java/JavaCompileInputs.kt
index c0ceda8..f07cd0c 100644
--- a/buildSrc/src/main/kotlin/androidx/build/java/JavaCompileInputs.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/java/JavaCompileInputs.kt
@@ -17,6 +17,7 @@
 package androidx.build.java
 
 import androidx.build.androidJarFile
+import androidx.build.multiplatformExtension
 import com.android.build.gradle.LibraryExtension
 import com.android.build.gradle.api.BaseVariant
 import com.android.build.gradle.api.SourceKind
@@ -30,7 +31,7 @@
 // This can be helpful for creating Metalava and Dokka tasks with the same settings
 data class JavaCompileInputs(
     // Source files to process
-    val sourcePaths: Collection<File>,
+    val sourcePaths: FileCollection,
 
     // Dependencies of [sourcePaths].
     val dependencyClasspath: FileCollection,
@@ -40,12 +41,13 @@
 ) {
     companion object {
         // Constructs a JavaCompileInputs from a library and its variant
-        fun fromLibraryVariant(library: LibraryExtension, variant: BaseVariant): JavaCompileInputs {
-            val folders = variant.getSourceFolders(SourceKind.JAVA)
-            val sourcePaths: MutableCollection<File> = mutableListOf()
-            for (folder in folders) {
-                sourcePaths.add(folder.dir)
-            }
+        fun fromLibraryVariant(
+            library: LibraryExtension,
+            variant: BaseVariant,
+            project: Project
+        ): JavaCompileInputs {
+            val sourceCollection = project.files(getSourcePaths(variant, project))
+            sourceCollection.builtBy(variant.javaCompileProvider)
             val dependencyClasspath = variant.compileConfiguration.incoming.artifactView { config ->
                 config.attributes { container ->
                     container.attribute(Attribute.of("artifactType", String::class.java), "jar")
@@ -53,7 +55,7 @@
             }.artifacts.artifactFiles
 
             return JavaCompileInputs(
-                sourcePaths,
+                sourceCollection,
                 dependencyClasspath,
                 library.bootClasspath
             )
@@ -72,7 +74,23 @@
             project: Project
         ): JavaCompileInputs {
             val bootClasspath: Collection<File> = androidJarFile(project).files
-            return JavaCompileInputs(sourcePaths, dependencyClasspath, bootClasspath)
+            val sourceCollection = project.files(sourcePaths)
+            return JavaCompileInputs(sourceCollection, dependencyClasspath, bootClasspath)
+        }
+
+        private fun getSourcePaths(variant: BaseVariant, project: Project): Collection<File> {
+            // If the project has the kotlin-multiplatform plugin, we want to return a combined
+            // collection of all the source files inside '*main' source sets. I.e, given a module
+            // with a common and Android source set, this will look inside commonMain and
+            // androidMain.
+            return project.multiplatformExtension?.run {
+                sourceSets
+                    .filter { it.name.contains("main", ignoreCase = true) }
+                    .flatMap { it.kotlin.sourceDirectories }
+                    .also { require(it.isNotEmpty()) }
+            } ?: variant
+                .getSourceFolders(SourceKind.JAVA)
+                .map { folder -> folder.dir }
         }
     }
 }
diff --git a/buildSrc/src/main/kotlin/androidx/build/metalava/CheckApiEquivalenceTask.kt b/buildSrc/src/main/kotlin/androidx/build/metalava/CheckApiEquivalenceTask.kt
index 765edbf..1a20da1 100644
--- a/buildSrc/src/main/kotlin/androidx/build/metalava/CheckApiEquivalenceTask.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/metalava/CheckApiEquivalenceTask.kt
@@ -55,33 +55,43 @@
         return checkedInApis.get().map { it.publicApiFile }
     }
 
+    private fun summarizeDiff(a: File, b: File): String {
+        val process = ProcessBuilder(listOf("diff", a.toString(), b.toString()))
+                .redirectOutput(ProcessBuilder.Redirect.PIPE)
+                .start()
+        process.waitFor()
+        var diffLines = process.inputStream.bufferedReader().readLines().toMutableList()
+        val maxSummaryLines = 50
+        if (diffLines.size > maxSummaryLines) {
+            diffLines = diffLines.subList(0, maxSummaryLines)
+            diffLines.plusAssign("[long diff was truncated]")
+        }
+        return diffLines.joinToString("\n")
+    }
+
+    private fun checkEqual(expected: File, actual: File) {
+        if (!FileUtils.contentEquals(expected, actual)) {
+            val diff = summarizeDiff(expected, actual)
+            val message = """API definition has changed
+
+                    Declared definition is ${expected}
+                    True     definition is ${actual}
+
+                    Please run `./gradlew updateApi` to confirm these changes are
+                    intentional by updating the API definition.
+
+                    Difference between these files:
+                    $diff"""
+            throw GradleException(message)
+        }
+    }
+
     @TaskAction
     fun exec() {
         for (checkedInApi in checkedInApis.get()) {
-            if (!FileUtils.contentEquals(
-                    checkedInApi.publicApiFile,
-                    builtApi.get().publicApiFile
-                )) {
-                val message = "Public API definition has changed.\n\n" +
-                        "Declared definition is ${checkedInApi.publicApiFile}\n" +
-                        "True     definition is ${builtApi.get().publicApiFile}\n\n" +
-                        "Please run `./gradlew updateApi` to confirm these changes are " +
-                        "intentional by updating the public API definition"
-                throw GradleException(message)
-            }
+            checkEqual(checkedInApi.publicApiFile, builtApi.get().publicApiFile)
             if (checkRestrictedAPIs) {
-                if (!FileUtils.contentEquals(
-                        checkedInApi.restrictedApiFile,
-                        builtApi.get().restrictedApiFile
-                    )) {
-                    val message = "Restricted API definition (marked by the RestrictedTo " +
-                            "annotation) has changed.\n\n" +
-                            "Declared definition is ${checkedInApi.restrictedApiFile}\n" +
-                            "True     definition is ${builtApi.get().restrictedApiFile}\n" +
-                            "Please run `./gradlew updateApi` to confirm these changes are " +
-                            "intentional by updating the restricted API definition"
-                    throw GradleException(message)
-                }
+                checkEqual(checkedInApi.restrictedApiFile, builtApi.get().restrictedApiFile)
             }
         }
     }
diff --git a/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt b/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt
index ab64ddd..1067c50 100644
--- a/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt
@@ -110,10 +110,10 @@
     apiLintMode: ApiLintMode,
     includeRestrictedApis: Boolean
 ) {
-    generateApi(files.bootClasspath, files.dependencyClasspath, files.sourcePaths,
+    generateApi(files.bootClasspath, files.dependencyClasspath, files.sourcePaths.files,
         apiLocation.publicApiFile, tempDir, GenerateApiMode.PublicApi, apiLintMode)
     if (includeRestrictedApis) {
-        generateApi(files.bootClasspath, files.dependencyClasspath, files.sourcePaths,
+        generateApi(files.bootClasspath, files.dependencyClasspath, files.sourcePaths.files,
             apiLocation.restrictedApiFile, tempDir, GenerateApiMode.RestrictedApi, ApiLintMode.Skip)
     }
 }
diff --git a/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaTask.kt b/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaTask.kt
index a68fe6f..78480c81 100644
--- a/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaTask.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaTask.kt
@@ -27,6 +27,7 @@
 abstract class MetalavaTask : DefaultTask() {
     /** Configuration containing Metalava and its dependencies. */
     @get:Classpath
+    @get:InputFiles
     lateinit var configuration: Configuration
 
     /** Android's boot classpath. Obtained from [BaseExtension.getBootClasspath]. */
diff --git a/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaTasks.kt b/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaTasks.kt
index 51d97a4..022cb45 100644
--- a/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaTasks.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaTasks.kt
@@ -57,7 +57,7 @@
                     return@defaultPublishVariant
                 }
 
-                val javaInputs = JavaCompileInputs.fromLibraryVariant(library, variant)
+                val javaInputs = JavaCompileInputs.fromLibraryVariant(library, variant, project)
                 setupProject(this, javaInputs, extension)
                 setupStubs(this, javaInputs, variant)
             }
@@ -86,7 +86,8 @@
     }
 
     fun applyInputs(inputs: JavaCompileInputs, task: MetalavaTask) {
-        task.sourcePaths = inputs.sourcePaths
+        task.sourcePaths = inputs.sourcePaths.files
+        task.dependsOn(inputs.sourcePaths)
         task.dependencyClasspath = inputs.dependencyClasspath
         task.bootClasspath = inputs.bootClasspath
     }
@@ -182,6 +183,20 @@
                 }
             }
 
+        val regenerateOldApis = project.tasks.register("regenerateOldApis",
+                RegenerateOldApisTask::class.java) { task ->
+            task.group = "API"
+            task.description = "Regenerates historic API .txt files using the " +
+                "corresponding prebuilt and the latest Metalava"
+            // if checkApiRelease and regenerateOldApis both run, then checkApiRelease must
+            // be the second one run of the two (because checkApiRelease validates
+            // files modified by regenerateOldApis)
+            val cr = checkApiRelease
+            if (cr != null) {
+                cr.get().mustRunAfter(task)
+            }
+        }
+
         val updateApi = project.tasks.register("updateApi", UpdateApiTask::class.java) { task ->
             task.group = "API"
             task.description = "Updates the checked in API files to match source code API"
@@ -199,13 +214,11 @@
             }
         }
 
-        project.tasks.register("regenerateOldApis", RegenerateOldApisTask::class.java) { task ->
+        project.tasks.register("regenerateApis") { task ->
             task.group = "API"
             task.description = "Regenerates current and historic API .txt files using the " +
                 "corresponding prebuilt and the latest Metalava"
-            // Technically this doesn't need updateApi to happen first, but adding this dependency
-            // is a convenient way to make updateApi also happen when the user runs
-            // `./gradlew regenerateOldApis`
+            task.dependsOn(regenerateOldApis)
             task.dependsOn(updateApi)
         }
 
diff --git a/buildSrc/src/main/kotlin/androidx/build/releasenotes/GenerateReleaseNotesTask.kt b/buildSrc/src/main/kotlin/androidx/build/releasenotes/GenerateReleaseNotesTask.kt
new file mode 100644
index 0000000..8380060
--- /dev/null
+++ b/buildSrc/src/main/kotlin/androidx/build/releasenotes/GenerateReleaseNotesTask.kt
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2019 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.build.releasenotes
+
+import androidx.build.gitclient.Commit
+import androidx.build.gitclient.GitClientImpl
+import androidx.build.getReleaseNotesDirectory
+import org.gradle.api.DefaultTask
+import org.gradle.api.provider.Property
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.OutputFile
+import org.gradle.api.tasks.TaskAction
+import java.io.File
+import java.time.LocalDate
+
+/**
+ * Task for Generating Release notes for this specific project, based on a start SHA and an end SHA.
+ * It outputs release notes in the format of developer.android.com.  See [LibraryReleaseNotes] for
+ * more info about the formatting.
+ */
+open class GenerateReleaseNotesTask : DefaultTask() {
+
+    init {
+        group = "Documentation"
+        description = "Task for creating release notes for a specific library"
+    }
+
+    @Input
+    lateinit var startSHA: String
+    @Input
+    lateinit var endSHA: String
+    @Input
+    lateinit var date: LocalDate
+    @Input
+    var keepMerges: Boolean = false
+
+    @OutputFile
+    val outputFile: Property<File> = project.objects.property(File::class.java)
+
+    /**
+     * @return the local project directory without the full framework/support root directory path
+     * Example input: /Users/<username>/androidx-master-dev/frameworks/support/core/core
+     * Example output: /core/core
+     */
+    private fun getProjectSpecificDirectory(): String {
+        return project.projectDir.toString().removePrefix(project.rootDir.toString())
+    }
+
+    /**
+     * Check if an email address is a robot
+     *
+     * @param authorEmail email to check
+     */
+    fun isExcludedAuthorEmail(authorEmail: String): Boolean {
+        val excludedAuthorEmails = listOf(
+            "treehugger-gerrit@google.com",
+            "android-build-merger@google.com",
+            "noreply-gerritcodereview@google.com"
+        )
+        return excludedAuthorEmails.contains(authorEmail)
+    }
+
+    private fun writeReleaseNotesToFile(releaseNotes: LibraryReleaseNotes) {
+        if (!project.getReleaseNotesDirectory().exists()) {
+            if (!project.getReleaseNotesDirectory().mkdirs()) {
+                throw RuntimeException("Failed to create " +
+                        "output directory: ${project.getReleaseNotesDirectory()}")
+            }
+        }
+        var resolvedOutputFile: File = outputFile.get()
+        if (!resolvedOutputFile.exists()) {
+            if (!resolvedOutputFile.createNewFile()) {
+                throw RuntimeException("Failed to create " +
+                        "output dependency dump file: $outputFile")
+            }
+        }
+        resolvedOutputFile.writeText(releaseNotes.toString())
+    }
+
+    /**
+     * Given the [GenerateReleaseNotesTask.startSHA], [GenerateReleaseNotesTask.endSHA], and
+     * [GenerateReleaseNotesTask.date], creates release notes for this specific project, starting
+     * at [GenerateReleaseNotesTask.startSHA] and ending at [GenerateReleaseNotesTask.endSHA].
+     */
+    @TaskAction
+    fun createReleaseNotes() {
+        if (startSHA.isEmpty()) {
+            throw RuntimeException("The generate release notes task need a start SHA from" +
+                    "which to start generating release notes.  You can pass it a start SHA by" +
+                    "adding the argument -PstartCommit=<yourSHA>")
+        }
+
+        val commitList: List<Commit> = GitClientImpl(project.rootDir).getGitLog(
+            startSHA,
+            endSHA,
+            keepMerges,
+            project.projectDir
+        )
+
+        val releaseNotes = LibraryReleaseNotes(
+            project.group.toString(),
+            mutableListOf(project.name.toString()),
+            project.version.toString(),
+            date,
+            startSHA,
+            endSHA,
+            getProjectSpecificDirectory()
+        )
+
+        if (commitList.isEmpty()) {
+            logger.warn("WARNING: Found no commits for ${project.group}:${project.name} from " +
+                    "start SHA $startSHA to end SHA $endSHA.  To double check, you can run " +
+                    "`git log --no-merges $startSHA..$endSHA ${project.projectDir}`")
+        }
+
+        commitList.forEach { commit ->
+            if (!isExcludedAuthorEmail(commit.authorEmail)) {
+                releaseNotes.addCommit(commit)
+            }
+        }
+
+        writeReleaseNotesToFile(releaseNotes)
+    }
+}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/androidx/build/releasenotes/Markdown.kt b/buildSrc/src/main/kotlin/androidx/build/releasenotes/Markdown.kt
new file mode 100644
index 0000000..498e836
--- /dev/null
+++ b/buildSrc/src/main/kotlin/androidx/build/releasenotes/Markdown.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2019 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.build.releasenotes
+
+/** Classes for generating markdown */
+
+enum class HeaderType {
+    H1, H2, H3, H4, H5, H6;
+    companion object {
+        fun getHeaderTag(tag: HeaderType): String {
+            when (tag) {
+                H1 -> return("#")
+                H2 -> return("##")
+                H3 -> return("###")
+                H4 -> return("####")
+                H5 -> return("#####")
+                H6 -> return("######")
+            }
+        }
+    }
+}
+
+open class MarkdownHeader {
+    var markdownType: HeaderType = HeaderType.H1
+    var text: String = ""
+
+    @Override
+    override fun toString(): String {
+        return HeaderType.getHeaderTag(markdownType) + ' ' + text
+    }
+    fun print() {
+        println(toString())
+    }
+}
+
+open class MarkdownLink {
+    var linkText: String = ""
+    var linkUrl: String = ""
+
+    @Override
+    override fun toString(): String {
+        return "([$linkText]($linkUrl))"
+    }
+
+    fun print() {
+        println(toString())
+    }
+}
+
+open class MarkdownBoldText(
+    inputText: String
+) {
+    var text: String = ""
+    init {
+        text = inputText
+    }
+
+    override fun toString(): String {
+        return "**$text**"
+    }
+
+    fun print() {
+        println(toString())
+    }
+}
+
+open class MarkdownComment(
+    inputText: String
+) {
+    var text: String = ""
+    init {
+        text = inputText
+    }
+
+    override fun toString(): String {
+        return "{# $text #}"
+    }
+
+    fun print() {
+        println(toString())
+    }
+}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/androidx/build/releasenotes/ReleaseNoteMarkdown.kt b/buildSrc/src/main/kotlin/androidx/build/releasenotes/ReleaseNoteMarkdown.kt
new file mode 100644
index 0000000..c4856c1
--- /dev/null
+++ b/buildSrc/src/main/kotlin/androidx/build/releasenotes/ReleaseNoteMarkdown.kt
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2019 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.build.releasenotes
+
+import androidx.build.gitclient.Commit
+import androidx.build.gitclient.CommitType
+import java.time.LocalDate
+import java.time.format.DateTimeFormatter
+
+/**
+ * Classes for generating androidx release note specific markdown
+ */
+
+/**
+ * Markdown class for a Library Header in the format:
+ * ## Version <version> {:#<version>}
+ */
+class LibraryHeader(groupId: String, version: String) : MarkdownHeader() {
+    init {
+        markdownType = HeaderType.H2
+        text = "$groupId Version $version {:#$version}"
+    }
+}
+
+/**
+ * Generates the markdown list of commits with sections defined by enum [CommitType], in the format:
+ *
+ * **New Features**
+ *
+ * - <[Commit.summary]> <[getAOSPLink]> <[getBuganizerLink] 1> <[getBuganizerLink] 2>...
+ *
+ * **API Changes**
+ *
+ * - <[Commit.summary]> <[getAOSPLink]> <[getBuganizerLink] 1> <[getBuganizerLink] 2>...
+ *
+ * **Bug Fixes**
+ *
+ * - <[Commit.summary]> <[getAOSPLink]> <[getBuganizerLink] 1> <[getBuganizerLink] 2>...
+ *
+ * **External Contribution**
+ *
+ * - <[Commit.summary]> <[getAOSPLink]> <[getBuganizerLink] 1> <[getBuganizerLink] 2>...
+ *
+ */
+class CommitMarkdownList {
+    private var commits: MutableList<Commit> = mutableListOf()
+
+    fun add(commit: Commit) {
+        commits.add(commit)
+    }
+
+    fun getListItemStr(): String {
+        return "- "
+    }
+
+    private fun makeReleaseNotesSection(sectionCommitType: CommitType): String {
+        var sectionHeader: MarkdownBoldText = MarkdownBoldText(CommitType
+            .getTitle(sectionCommitType))
+        var markdownStringSection: String = ""
+        commits.filter { commit ->
+            commit.type == sectionCommitType
+        }.forEach { commit ->
+            markdownStringSection = "$markdownStringSection${getListItemStr()}$commit"
+            if (markdownStringSection.last() != '\n') {
+                markdownStringSection += '\n'
+            }
+        }
+        markdownStringSection = if (markdownStringSection.isEmpty()) {
+            "\n${MarkdownComment(sectionHeader.toString())}\n\n$markdownStringSection"
+        } else {
+            "\n$sectionHeader\n\n$markdownStringSection"
+        }
+        return markdownStringSection
+    }
+
+    @Override
+    override fun toString(): String {
+        var markdownString: String = ""
+        CommitType.values().forEach { commitType ->
+            markdownString += makeReleaseNotesSection(commitType)
+        }
+        return markdownString
+    }
+
+    fun print() {
+        println(toString())
+    }
+}
+
+/**
+ * @param startSHA the SHA at which to start the diff log (exclusive)
+ * @param endSHA the last SHA to include in the diff log (inclusive)
+ * @param projectDir the local directory of the project, in relation to frameworks/support
+ *
+ * @return A [MarkdownLink] to the public Gitiles diff log
+ */
+fun getGitilesDiffLogLink(startSHA: String, endSHA: String, projectDir: String): MarkdownLink {
+    val baseGitilesUrl: String =
+        "https://android.googlesource.com/platform/frameworks/support/+log/"
+    /* The root project directory is already existent in the url path, so the directory here
+     * should be relative to frameworks/support/.
+     */
+    if (projectDir.contains("frameworks/support")) {
+        throw RuntimeException("Gitiles directory should only contain the directory structure" +
+                "within frameworks/support/*, but received incorrect directory: $projectDir")
+    }
+    // Remove extra preceeding directory slashes, if they exist
+    var verifiedProjectDir = projectDir
+    while (verifiedProjectDir.first() == '/') {
+        verifiedProjectDir = verifiedProjectDir.removePrefix("/")
+    }
+    var gitilesLink: MarkdownLink = MarkdownLink()
+    gitilesLink.linkText = "here"
+    gitilesLink.linkUrl = "$baseGitilesUrl$startSHA..$endSHA/$verifiedProjectDir"
+    return gitilesLink
+}
+
+/**
+ * @param changeId The Gerrit Change-Id to link to
+ * @return A [MarkdownLink] to AOSP Gerrit
+ */
+fun getAOSPLink(changeId: String): MarkdownLink {
+    val baseAOSPUrl: String = "https://android-review.googlesource.com/#/q/"
+    var aospLink: MarkdownLink = MarkdownLink()
+    aospLink.linkText = "aosp/" + changeId.take(6)
+    aospLink.linkUrl = "$baseAOSPUrl$changeId"
+    return aospLink
+}
+
+/**
+ * @param bugId the Id of the buganizer issue
+ * @return A [MarkdownLink] to the public buganizer issue tracker
+ *
+ * Note: This method does not check if the bug is public
+ */
+fun getBuganizerLink(bugId: Int): MarkdownLink {
+    val baseBuganizerUrl: String = "https://issuetracker.google.com/issues/"
+    var buganizerLink: MarkdownLink = MarkdownLink()
+    buganizerLink.linkText = "b/$bugId"
+    buganizerLink.linkUrl = "$baseBuganizerUrl$bugId"
+    return buganizerLink
+}
+
+/**
+ * Structured release notes class, that connects all parts of the release notes.  Create release
+ * notes in the format:
+ * <pre>
+ * <[LibraryHeader]>
+ * <Date>
+ *
+ * `androidx.<groupId>:<artifactId>:<version>` is released.  The commits included in this version
+ * can be found <[MarkdownLink]>.
+ *
+ *  <[CommitMarkdownList]>
+ * </pre>
+ *
+ * @property groupId Library GroupId.
+ * @property artifactIds List of ArtifactIds included in these release notes.
+ * @property version Version of the library, assuming all artifactIds have the same version.
+ * @property releaseDate Date the release will go live.  Defaults to the current date.
+ * @param startSHA The first SHA to include in the release notes.
+ * @param endSHA The last SHA to be included in the release notes.
+ * @param projectDir The filepath relative to the parent directory of the .git directory.
+ */
+class LibraryReleaseNotes(
+    private val groupId: String,
+    private val artifactIds: MutableList<String>,
+    private val version: String,
+    private val releaseDate: LocalDate,
+    startSHA: String,
+    endSHA: String,
+    projectDir: String
+) {
+
+    private var diffLogLink: MarkdownLink
+    private var header: LibraryHeader
+    private var commits: MutableList<Commit> = mutableListOf()
+    private var commitMarkdownList: CommitMarkdownList = CommitMarkdownList()
+    private var summary: String = ""
+    private var bugsFixed: MutableList<Int> = mutableListOf()
+
+    init {
+        if (version == "" || groupId == "") {
+            throw RuntimeException("Tried to create Library Release Notes Header without setting" +
+                    "the groupId or version!")
+        }
+        if (startSHA == "" || endSHA == "") {
+            throw RuntimeException("Tried to create Library Release Notes with an empty SHA!")
+        }
+        header = LibraryHeader(groupId, version)
+        diffLogLink = getGitilesDiffLogLink(startSHA, endSHA, projectDir)
+    }
+
+    fun getFormattedDate(): String {
+        val formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy")
+        return formatter.format(releaseDate)
+    }
+
+    fun getFormattedReleaseSummary(): String {
+        val numberArtifacts = artifactIds.size
+        for (i: Int in 0..(numberArtifacts - 1)) {
+            var currentArtifactId: String = artifactIds[i]
+            when (numberArtifacts) {
+                1 -> {
+                    summary = "`$groupId:$currentArtifactId:$version` is released.  "
+                }
+                2 -> {
+                    if (i == 0) {
+                        summary = "`$groupId:$currentArtifactId:$version` and "
+                    }
+                    if (i == 1) {
+                        summary += "`$groupId:$currentArtifactId:$version` are released. "
+                    }
+                }
+                else -> {
+                    if (i < numberArtifacts - 1) {
+                        summary += "`$groupId:$currentArtifactId:$version`, "
+                    } else {
+                        summary += "and `$groupId:$currentArtifactId:$version` are released. "
+                    }
+                }
+            }
+        }
+
+        summary += "The commits included in this version can be found $diffLogLink.\n"
+        return summary
+    }
+
+    fun addCommit(newCommit: Commit) {
+        newCommit.bugs.forEach { bug ->
+            bugsFixed.add(bug)
+        }
+        commits.add(newCommit)
+        commitMarkdownList.add(newCommit)
+    }
+
+    override fun toString(): String {
+        return "$header\n" +
+                "${getFormattedDate()}\n\n" +
+                getFormattedReleaseSummary() +
+                "$commitMarkdownList"
+    }
+}
\ No newline at end of file
diff --git a/camera/camera-camera2/lint-baseline.xml b/camera/camera-camera2/lint-baseline.xml
index b864e7a..73145a2 100644
--- a/camera/camera-camera2/lint-baseline.xml
+++ b/camera/camera-camera2/lint-baseline.xml
@@ -224,61 +224,6 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="    public Camera2CameraFactory(Context context) {"
-        errorLine2="                                ~~~~~~~">
-        <location
-            file="src/main/java/androidx/camera/camera2/impl/Camera2CameraFactory.java"
-            line="59"
-            column="33"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="    public BaseCamera getCamera(String cameraId) {"
-        errorLine2="           ~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/camera/camera2/impl/Camera2CameraFactory.java"
-            line="64"
-            column="12"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="    public BaseCamera getCamera(String cameraId) {"
-        errorLine2="                                ~~~~~~">
-        <location
-            file="src/main/java/androidx/camera/camera2/impl/Camera2CameraFactory.java"
-            line="64"
-            column="33"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="    public Set&lt;String> getAvailableCameraIds() throws CameraInfoUnavailableException {"
-        errorLine2="           ~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/camera/camera2/impl/Camera2CameraFactory.java"
-            line="69"
-            column="12"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="    public String cameraIdForLensFacing(LensFacing lensFacing)"
-        errorLine2="                                        ~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/camera/camera2/impl/Camera2CameraFactory.java"
-            line="83"
-            column="41"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
         errorLine1="    public static CameraCaptureSession.CaptureCallback createNoOpCallback() {"
         errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/ImageCaptureTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/ImageCaptureTest.java
index 308491b..c88026a 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/ImageCaptureTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/ImageCaptureTest.java
@@ -44,6 +44,7 @@
 import android.util.Size;
 import android.view.Surface;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.camera.camera2.impl.util.FakeRepeatingUseCase;
 import androidx.camera.core.AppConfig;
@@ -58,10 +59,10 @@
 import androidx.camera.core.CaptureStage;
 import androidx.camera.core.Exif;
 import androidx.camera.core.ImageCapture;
+import androidx.camera.core.ImageCapture.ImageCaptureError;
 import androidx.camera.core.ImageCapture.Metadata;
 import androidx.camera.core.ImageCapture.OnImageCapturedListener;
 import androidx.camera.core.ImageCapture.OnImageSavedListener;
-import androidx.camera.core.ImageCapture.UseCaseError;
 import androidx.camera.core.ImageCaptureConfig;
 import androidx.camera.core.ImageProxy;
 import androidx.camera.testing.CameraUtil;
@@ -188,7 +189,7 @@
         mOnImageSavedListener =
                 new OnImageSavedListener() {
                     @Override
-                    public void onImageSaved(File file) {
+                    public void onImageSaved(@NonNull File file) {
                         mMockImageSavedListener.onImageSaved(file);
                         // Signal that an image was saved
                         mSemaphore.release();
@@ -196,7 +197,8 @@
 
                     @Override
                     public void onError(
-                            UseCaseError error, String message, @Nullable Throwable cause) {
+                            @NonNull ImageCaptureError error, @NonNull String message,
+                            @Nullable Throwable cause) {
                         mMockImageSavedListener.onError(error, message, cause);
                         // Signal that there was an error
                         mSemaphore.release();
@@ -465,7 +467,7 @@
         mSemaphore.acquire();
 
         verify(mMockImageSavedListener)
-                .onError(eq(UseCaseError.FILE_IO_ERROR), anyString(), any(Throwable.class));
+                .onError(eq(ImageCaptureError.FILE_IO_ERROR), anyString(), any(Throwable.class));
     }
 
     @Suppress // TODO(b/133171096): Remove once this no longer throws an IllegalStateException
@@ -601,7 +603,7 @@
         OnImageCapturedListener mockOnImageCaptureListener = mock(OnImageCapturedListener.class);
         imageCapture.takePicture(mockOnImageCaptureListener);
 
-        verify(mockOnImageCaptureListener, timeout(3000)).onError(any(UseCaseError.class),
+        verify(mockOnImageCaptureListener, timeout(3000)).onError(any(ImageCaptureError.class),
                 anyString(), any(IllegalArgumentException.class));
 
         CameraX.unbind(imageCapture);
@@ -643,8 +645,8 @@
         imageCapture.takePicture(mockOnImageCaptureListener);
 
         // It should get onError() callback twice.
-        verify(mockOnImageCaptureListener, timeout(3000).times(2)).onError(any(UseCaseError.class),
-                anyString(), any(IllegalArgumentException.class));
+        verify(mockOnImageCaptureListener, timeout(3000).times(2)).onError(
+                any(ImageCaptureError.class), anyString(), any(IllegalArgumentException.class));
 
         CameraX.unbind(imageCapture);
     }
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/PreviewTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/PreviewTest.java
index 002859c..3d2bf9c 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/PreviewTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/PreviewTest.java
@@ -20,7 +20,6 @@
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.junit.Assume.assumeTrue;
-import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
@@ -34,7 +33,6 @@
 import android.view.Surface;
 
 import androidx.annotation.NonNull;
-import androidx.camera.camera2.impl.Camera2CameraControl;
 import androidx.camera.core.AppConfig;
 import androidx.camera.core.CameraControlInternal;
 import androidx.camera.core.CameraFactory;
@@ -42,14 +40,13 @@
 import androidx.camera.core.CameraX.LensFacing;
 import androidx.camera.core.CaptureConfig;
 import androidx.camera.core.DeferrableSurfaces;
-import androidx.camera.core.OnFocusListener;
 import androidx.camera.core.Preview;
 import androidx.camera.core.Preview.OnPreviewOutputUpdateListener;
 import androidx.camera.core.Preview.PreviewOutput;
 import androidx.camera.core.PreviewConfig;
 import androidx.camera.core.SessionConfig;
-import androidx.camera.core.impl.utils.executor.CameraXExecutors;
 import androidx.camera.testing.CameraUtil;
+import androidx.camera.testing.fakes.FakeCameraControl;
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -67,7 +64,6 @@
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
 import java.util.concurrent.FutureTask;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
@@ -139,26 +135,6 @@
 
     @Test
     @UiThreadTest
-    public void focusRegionCanBeSet() {
-        Preview useCase = new Preview(mDefaultConfig);
-        useCase.updateSuggestedResolution(Collections.singletonMap(mCameraId, DEFAULT_RESOLUTION));
-
-        CameraControlInternal cameraControl = mock(CameraControlInternal.class);
-        useCase.attachCameraControl(mCameraId, cameraControl);
-
-        Rect rect = new Rect(/*left=*/ 200, /*top=*/ 200, /*right=*/ 800, /*bottom=*/ 800);
-        useCase.focus(rect, rect, mock(OnFocusListener.class));
-
-        ArgumentCaptor<Rect> rectArgumentCaptor1 = ArgumentCaptor.forClass(Rect.class);
-        ArgumentCaptor<Rect> rectArgumentCaptor2 = ArgumentCaptor.forClass(Rect.class);
-        verify(cameraControl).focus(rectArgumentCaptor1.capture(), rectArgumentCaptor2.capture(),
-                any(Executor.class), any(OnFocusListener.class));
-        assertThat(rectArgumentCaptor1.getValue()).isEqualTo(rect);
-        assertThat(rectArgumentCaptor2.getValue()).isEqualTo(rect);
-    }
-
-    @Test
-    @UiThreadTest
     public void zoomRegionCanBeSet() {
         Preview useCase = new Preview(mDefaultConfig);
         useCase.updateSuggestedResolution(Collections.singletonMap(mCameraId, DEFAULT_RESOLUTION));
@@ -490,21 +466,16 @@
     }
 
     private CameraControlInternal getFakeCameraControl() {
-        return new Camera2CameraControl(
-                new CameraControlInternal.ControlUpdateListener() {
-                    @Override
-                    public void onCameraControlUpdateSessionConfig(
-                            @NonNull SessionConfig sessionConfig) {
-                    }
+        return new FakeCameraControl(new CameraControlInternal.ControlUpdateListener() {
+            @Override
+            public void onCameraControlUpdateSessionConfig(@NonNull SessionConfig sessionConfig) {
+            }
 
-                    @Override
-                    public void onCameraControlCaptureRequests(
-                            @NonNull List<CaptureConfig> captureConfigs) {
-
-                    }
-                },
-                CameraXExecutors.mainThreadExecutor(),
-                CameraXExecutors.mainThreadExecutor());
+            @Override
+            public void onCameraControlCaptureRequests(
+                    @NonNull List<CaptureConfig> captureConfigs) {
+            }
+        });
     }
 
     private static final class SurfaceTextureCallable implements Callable<SurfaceTexture> {
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/SensorOrientedMeteringPointFactoryTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/SensorOrientedMeteringPointFactoryTest.java
new file mode 100644
index 0000000..0e5ee3e
--- /dev/null
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/SensorOrientedMeteringPointFactoryTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2019 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.camera.camera2;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Rational;
+
+import androidx.camera.core.AppConfig;
+import androidx.camera.core.CameraX;
+import androidx.camera.core.ImageAnalysis;
+import androidx.camera.core.ImageAnalysisConfig;
+import androidx.camera.core.MeteringPoint;
+import androidx.camera.core.MeteringPointFactory;
+import androidx.camera.core.SensorOrientedMeteringPointFactory;
+import androidx.camera.testing.fakes.FakeLifecycleOwner;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public final class SensorOrientedMeteringPointFactoryTest {
+    private static final float WIDTH = 480;
+    private static final float HEIGHT = 640;
+    private LifecycleOwner mLifecycle;
+    SensorOrientedMeteringPointFactory mPointFactory;
+    @Before
+    public void setUp() {
+        Context context = ApplicationProvider.getApplicationContext();
+        AppConfig config = Camera2AppConfig.create(context);
+
+        CameraX.init(context, config);
+        mLifecycle = new FakeLifecycleOwner();
+        mPointFactory = new SensorOrientedMeteringPointFactory(WIDTH, HEIGHT);
+    }
+
+    @Test
+    public void defaultWeightAndAreaSize() {
+        MeteringPoint point = mPointFactory.createPoint(0, 0);
+        assertThat(point.getSize()).isEqualTo(MeteringPointFactory.DEFAULT_AREASIZE);
+        assertThat(point.getWeight()).isEqualTo(MeteringPointFactory.DEFAULT_WEIGHT);
+        assertThat(point.getFOVAspectRatio()).isNull();
+    }
+
+    @Test
+    public void createPointWithValidWeightAndAreaSize() {
+        final float areaSize = 0.2f;
+        final float weight = 0.5f;
+        MeteringPoint point = mPointFactory.createPoint(0, 0, areaSize, weight);
+        assertThat(point.getSize()).isEqualTo(areaSize);
+        assertThat(point.getWeight()).isEqualTo(weight);
+        assertThat(point.getFOVAspectRatio()).isNull();
+    }
+
+    @Test
+    public void createPointLeftTop_correctValueSet() {
+        MeteringPoint meteringPoint = mPointFactory.createPoint(0f, 0f);
+        assertThat(meteringPoint.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint.getNormalizedCropRegionY()).isEqualTo(0f);
+    }
+
+    @Test
+    public void createPointLeftBottom_correctValueSet() {
+        MeteringPoint meteringPoint2 = mPointFactory.createPoint(0f, HEIGHT);
+        assertThat(meteringPoint2.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint2.getNormalizedCropRegionY()).isEqualTo(1f);
+    }
+
+    @Test
+    public void createPointRightTop_correctValueSet() {
+        MeteringPoint meteringPoint3 = mPointFactory.createPoint(WIDTH, 0f);
+        assertThat(meteringPoint3.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint3.getNormalizedCropRegionY()).isEqualTo(0f);
+    }
+
+    @Test
+    public void createPointRightBottom_correctValueSet() {
+        MeteringPoint meteringPoint4 = mPointFactory.createPoint(WIDTH, HEIGHT);
+        assertThat(meteringPoint4.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint4.getNormalizedCropRegionY()).isEqualTo(1f);
+    }
+
+    @Test
+    public void createPointWithFoVUseCase_success() {
+        ImageAnalysisConfig imageAnalysisConfig =
+                new ImageAnalysisConfig.Builder()
+                        .setLensFacing(CameraX.LensFacing.BACK)
+                        .setTargetAspectRatio(new Rational(3, 4))
+                        .setTargetName("ImageAnalysis")
+                        .setCallbackHandler(new Handler(Looper.getMainLooper()))
+                        .build();
+        ImageAnalysis imageAnalysis = new ImageAnalysis(imageAnalysisConfig);
+        CameraX.bindToLifecycle(mLifecycle, imageAnalysis);
+
+        SensorOrientedMeteringPointFactory factory = new SensorOrientedMeteringPointFactory(
+                WIDTH, HEIGHT, imageAnalysis);
+        MeteringPoint point = factory.createPoint(0f, 0f);
+        assertThat(point.getFOVAspectRatio()).isEqualTo(new Rational(4, 3));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void createPointWithFoVUseCase_FailedNotBound() {
+        ImageAnalysisConfig imageAnalysisConfig =
+                new ImageAnalysisConfig.Builder()
+                        .setLensFacing(CameraX.LensFacing.BACK)
+                        .setTargetAspectRatio(new Rational(3, 4))
+                        .setTargetName("ImageAnalysis")
+                        .setCallbackHandler(new Handler(Looper.getMainLooper()))
+                        .build();
+        ImageAnalysis imageAnalysis = new ImageAnalysis(imageAnalysisConfig);
+
+        // This will throw IllegalStateException.
+        SensorOrientedMeteringPointFactory factory = new SensorOrientedMeteringPointFactory(
+                WIDTH, HEIGHT, imageAnalysis);
+    }
+}
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2CameraControlTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2CameraControlTest.java
index 3cd0401..7ce5de0 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2CameraControlTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2CameraControlTest.java
@@ -20,31 +20,47 @@
 import static android.hardware.camera2.CameraMetadata.CONTROL_AE_MODE_ON;
 import static android.hardware.camera2.CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS_FLASH;
 import static android.hardware.camera2.CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH;
+import static android.hardware.camera2.CameraMetadata.CONTROL_AF_MODE_AUTO;
+import static android.hardware.camera2.CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE;
+import static android.hardware.camera2.CameraMetadata.CONTROL_AF_MODE_OFF;
+import static android.hardware.camera2.CameraMetadata.CONTROL_AWB_MODE_AUTO;
+import static android.hardware.camera2.CameraMetadata.CONTROL_AWB_MODE_OFF;
 import static android.hardware.camera2.CameraMetadata.FLASH_MODE_OFF;
 import static android.hardware.camera2.CameraMetadata.FLASH_MODE_TORCH;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import android.content.Context;
 import android.graphics.Rect;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
 import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.params.MeteringRectangle;
 import android.os.Build;
 import android.os.Handler;
 import android.os.HandlerThread;
 
 import androidx.camera.camera2.Camera2Config;
 import androidx.camera.core.CameraControlInternal;
+import androidx.camera.core.CameraInfoUnavailableException;
+import androidx.camera.core.CameraX;
 import androidx.camera.core.CaptureConfig;
 import androidx.camera.core.FlashMode;
+import androidx.camera.core.FocusMeteringAction;
+import androidx.camera.core.FocusMeteringAction.MeteringMode;
+import androidx.camera.core.SensorOrientedMeteringPointFactory;
 import androidx.camera.core.SessionConfig;
 import androidx.camera.core.impl.utils.executor.CameraXExecutors;
 import androidx.camera.testing.HandlerUtil;
 import androidx.core.os.HandlerCompat;
+import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
@@ -53,6 +69,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
 
 import java.util.Collections;
 import java.util.List;
@@ -61,8 +78,6 @@
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public final class Camera2CameraControlTest {
-
-    private static final long NO_TIMEOUT = 0;
     private Camera2CameraControl mCamera2CameraControl;
     private CameraControlInternal.ControlUpdateListener mControlUpdateListener;
     private ArgumentCaptor<SessionConfig> mSessionConfigArgumentCaptor =
@@ -72,17 +87,24 @@
             ArgumentCaptor.forClass(List.class);
     private HandlerThread mHandlerThread;
     private Handler mHandler;
+    private CameraCharacteristics mCameraCharacteristics;
 
     @Before
-    public void setUp() throws InterruptedException {
+    public void setUp() throws InterruptedException, CameraAccessException,
+            CameraInfoUnavailableException {
+        Context context = ApplicationProvider.getApplicationContext();
+        CameraManager cameraManager = (CameraManager) context.getSystemService(
+                Context.CAMERA_SERVICE);
+        mCameraCharacteristics = cameraManager.getCameraCharacteristics(
+                CameraX.getCameraWithLensFacing(CameraX.LensFacing.BACK));
         mControlUpdateListener = mock(CameraControlInternal.ControlUpdateListener.class);
         mHandlerThread = new HandlerThread("ControlThread");
         mHandlerThread.start();
         mHandler = HandlerCompat.createAsync(mHandlerThread.getLooper());
 
         ScheduledExecutorService executorService = CameraXExecutors.newHandlerExecutor(mHandler);
-        mCamera2CameraControl = new Camera2CameraControl(mControlUpdateListener, NO_TIMEOUT,
-                executorService, executorService);
+        mCamera2CameraControl = new Camera2CameraControl(mCameraCharacteristics,
+                mControlUpdateListener, executorService, executorService);
 
         HandlerUtil.waitForLooperToIdle(mHandler);
 
@@ -117,183 +139,15 @@
     }
 
     @Test
-    public void focus_focusRectSetAndRequestsExecuted() throws InterruptedException {
-        Rect focusRect = new Rect(0, 0, 10, 10);
-        Rect meteringRect = new Rect(20, 20, 30, 30);
-
-        mCamera2CameraControl.focus(focusRect, meteringRect);
-
-        HandlerUtil.waitForLooperToIdle(mHandler);
-
-        verify(mControlUpdateListener, times(1)).onCameraControlUpdateSessionConfig(
-                mSessionConfigArgumentCaptor.capture());
-        SessionConfig sessionConfig = mSessionConfigArgumentCaptor.getValue();
-        Camera2Config repeatingConfig = new Camera2Config(sessionConfig.getImplementationOptions());
-
-        assertThat(
-                repeatingConfig.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AF_REGIONS, null))
-                .isEqualTo(
-                        new MeteringRectangle[]{
-                                new MeteringRectangle(focusRect,
-                                        MeteringRectangle.METERING_WEIGHT_MAX)
-                        });
-
-        assertThat(
-                repeatingConfig.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AE_REGIONS, null))
-                .isEqualTo(
-                        new MeteringRectangle[]{
-                                new MeteringRectangle(
-                                        meteringRect, MeteringRectangle.METERING_WEIGHT_MAX)
-                        });
-
-        assertThat(
-                repeatingConfig.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AWB_REGIONS, null))
-                .isEqualTo(
-                        new MeteringRectangle[]{
-                                new MeteringRectangle(
-                                        meteringRect, MeteringRectangle.METERING_WEIGHT_MAX)
-                        });
-
-        Camera2Config singleConfig = new Camera2Config(mCamera2CameraControl.getSharedOptions());
-        assertThat(
-                singleConfig.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AF_REGIONS, null))
-                .isEqualTo(
-                        new MeteringRectangle[]{
-                                new MeteringRectangle(focusRect,
-                                        MeteringRectangle.METERING_WEIGHT_MAX)
-                        });
-
-        assertThat(
-                singleConfig.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AE_REGIONS, null))
-                .isEqualTo(
-                        new MeteringRectangle[]{
-                                new MeteringRectangle(
-                                        meteringRect, MeteringRectangle.METERING_WEIGHT_MAX)
-                        });
-
-        assertThat(
-                singleConfig.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AWB_REGIONS, null))
-                .isEqualTo(
-                        new MeteringRectangle[]{
-                                new MeteringRectangle(
-                                        meteringRect, MeteringRectangle.METERING_WEIGHT_MAX)
-                        });
-
-        assertThat(mCamera2CameraControl.isFocusLocked()).isTrue();
-
-        verify(mControlUpdateListener).onCameraControlCaptureRequests(
-                mCaptureConfigArgumentCaptor.capture());
-        CaptureConfig captureConfig = mCaptureConfigArgumentCaptor.getValue().get(0);
-        Camera2Config resultCaptureConfig =
-                new Camera2Config(captureConfig.getImplementationOptions());
-
-        assertThat(resultCaptureConfig.getCaptureRequestOption(CaptureRequest.CONTROL_AF_TRIGGER,
-                null)).isEqualTo(CaptureRequest.CONTROL_AF_TRIGGER_START);
-    }
-
-    @Test
-    public void cancelFocus_regionRestored() throws InterruptedException {
-        Rect focusRect = new Rect(0, 0, 10, 10);
-        Rect meteringRect = new Rect(20, 20, 30, 30);
-
-        mCamera2CameraControl.focus(focusRect, meteringRect);
-        mCamera2CameraControl.cancelFocus();
-
-        HandlerUtil.waitForLooperToIdle(mHandler);
-
-        verify(mControlUpdateListener, times(2)).onCameraControlUpdateSessionConfig(
-                mSessionConfigArgumentCaptor.capture());
-        SessionConfig sessionConfig = mSessionConfigArgumentCaptor.getAllValues().get(1);
-        Camera2Config repeatingConfig = new Camera2Config(sessionConfig.getImplementationOptions());
-        MeteringRectangle zeroRegion =
-                new MeteringRectangle(new Rect(), MeteringRectangle.METERING_WEIGHT_DONT_CARE);
-
-        assertThat(
-                repeatingConfig.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AF_REGIONS, null))
-                .isEqualTo(new MeteringRectangle[]{zeroRegion});
-        assertThat(
-                repeatingConfig.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AE_REGIONS, null))
-                .isEqualTo(new MeteringRectangle[]{zeroRegion});
-        assertThat(
-                repeatingConfig.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AWB_REGIONS, null))
-                .isEqualTo(new MeteringRectangle[]{zeroRegion});
-
-        Camera2Config singleConfig = new Camera2Config(mCamera2CameraControl.getSharedOptions());
-        assertThat(
-                singleConfig.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AF_REGIONS, null))
-                .isEqualTo(new MeteringRectangle[]{zeroRegion});
-        assertThat(
-                singleConfig.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AE_REGIONS, null))
-                .isEqualTo(new MeteringRectangle[]{zeroRegion});
-        assertThat(
-                singleConfig.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AWB_REGIONS, null))
-                .isEqualTo(new MeteringRectangle[]{zeroRegion});
-
-        assertThat(mCamera2CameraControl.isFocusLocked()).isFalse();
-
-        verify(mControlUpdateListener, times(2)).onCameraControlCaptureRequests(
-                mCaptureConfigArgumentCaptor.capture());
-        CaptureConfig captureConfig = mCaptureConfigArgumentCaptor.getAllValues().get(1).get(0);
-        Camera2Config resultCaptureConfig =
-                new Camera2Config(captureConfig.getImplementationOptions());
-
-        assertThat(resultCaptureConfig.getCaptureRequestOption(CaptureRequest.CONTROL_AF_TRIGGER,
-                null)).isEqualTo(CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
-    }
-
-    @Test
     public void defaultAFAWBMode_ShouldBeCAFWhenNotFocusLocked() {
         Camera2Config singleConfig = new Camera2Config(mCamera2CameraControl.getSharedOptions());
         assertThat(
                 singleConfig.getCaptureRequestOption(
                         CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF))
                 .isEqualTo(CaptureRequest.CONTROL_MODE_AUTO);
-        assertThat(
-                singleConfig.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF))
-                .isEqualTo(CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
-        assertThat(
-                singleConfig.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AWB_MODE,
-                        CaptureRequest.CONTROL_AWB_MODE_OFF))
-                .isEqualTo(CaptureRequest.CONTROL_AWB_MODE_AUTO);
-    }
 
-    @Test
-    public void focus_afModeSetToAuto() throws InterruptedException {
-        Rect focusRect = new Rect(0, 0, 10, 10);
-        mCamera2CameraControl.focus(focusRect, focusRect);
-
-        HandlerUtil.waitForLooperToIdle(mHandler);
-
-        Camera2Config singleConfig = new Camera2Config(mCamera2CameraControl.getSharedOptions());
-
-        mCamera2CameraControl.cancelFocus();
-
-        HandlerUtil.waitForLooperToIdle(mHandler);
-
-        Camera2Config singleConfig2 = new Camera2Config(mCamera2CameraControl.getSharedOptions());
-
-        assertThat(
-                singleConfig.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF))
-                .isEqualTo(CaptureRequest.CONTROL_AF_MODE_AUTO);
-        assertThat(
-                singleConfig2.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF))
-                .isEqualTo(CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+        assertAfMode(singleConfig, CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+        assertAwbMode(singleConfig, CONTROL_AWB_MODE_AUTO);
     }
 
     @Test
@@ -306,10 +160,8 @@
                 mSessionConfigArgumentCaptor.capture());
         SessionConfig sessionConfig = mSessionConfigArgumentCaptor.getValue();
         Camera2Config camera2Config = new Camera2Config(sessionConfig.getImplementationOptions());
-        assertThat(
-                camera2Config.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AE_MODE, CONTROL_AE_MODE_OFF))
-                .isEqualTo(CONTROL_AE_MODE_ON_AUTO_FLASH);
+
+        assertAeMode(camera2Config, CONTROL_AE_MODE_ON_AUTO_FLASH);
         assertThat(mCamera2CameraControl.getFlashMode()).isEqualTo(FlashMode.AUTO);
     }
 
@@ -323,10 +175,9 @@
                 mSessionConfigArgumentCaptor.capture());
         SessionConfig sessionConfig = mSessionConfigArgumentCaptor.getValue();
         Camera2Config camera2Config = new Camera2Config(sessionConfig.getImplementationOptions());
-        assertThat(
-                camera2Config.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AE_MODE, CONTROL_AE_MODE_OFF))
-                .isEqualTo(CaptureRequest.CONTROL_AE_MODE_ON);
+
+        assertAeMode(camera2Config, CONTROL_AE_MODE_ON);
+
         assertThat(mCamera2CameraControl.getFlashMode()).isEqualTo(FlashMode.OFF);
     }
 
@@ -340,10 +191,9 @@
                 mSessionConfigArgumentCaptor.capture());
         SessionConfig sessionConfig = mSessionConfigArgumentCaptor.getValue();
         Camera2Config camera2Config = new Camera2Config(sessionConfig.getImplementationOptions());
-        assertThat(
-                camera2Config.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AE_MODE, CONTROL_AE_MODE_OFF))
-                .isEqualTo(CONTROL_AE_MODE_ON_ALWAYS_FLASH);
+
+        assertAeMode(camera2Config, CONTROL_AE_MODE_ON_ALWAYS_FLASH);
+
         assertThat(mCamera2CameraControl.getFlashMode()).isEqualTo(FlashMode.ON);
     }
 
@@ -357,10 +207,9 @@
                 mSessionConfigArgumentCaptor.capture());
         SessionConfig sessionConfig = mSessionConfigArgumentCaptor.getValue();
         Camera2Config camera2Config = new Camera2Config(sessionConfig.getImplementationOptions());
-        assertThat(
-                camera2Config.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AE_MODE, CONTROL_AE_MODE_OFF))
-                .isEqualTo(CONTROL_AE_MODE_ON);
+
+        assertAeMode(camera2Config, CONTROL_AE_MODE_ON);
+
         assertThat(
                 camera2Config.getCaptureRequestOption(
                         CaptureRequest.FLASH_MODE, FLASH_MODE_OFF))
@@ -379,10 +228,9 @@
                 mSessionConfigArgumentCaptor.capture());
         SessionConfig sessionConfig = mSessionConfigArgumentCaptor.getAllValues().get(0);
         Camera2Config camera2Config = new Camera2Config(sessionConfig.getImplementationOptions());
-        assertThat(
-                camera2Config.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AE_MODE, CONTROL_AE_MODE_OFF))
-                .isEqualTo(CONTROL_AE_MODE_ON_AUTO_FLASH);
+
+        assertAeMode(camera2Config, CONTROL_AE_MODE_ON_AUTO_FLASH);
+
         assertThat(camera2Config.getCaptureRequestOption(CaptureRequest.FLASH_MODE, -1))
                 .isEqualTo(-1);
         assertThat(mCamera2CameraControl.isTorchOn()).isFalse();
@@ -392,10 +240,9 @@
         CaptureConfig captureConfig = mCaptureConfigArgumentCaptor.getValue().get(0);
         Camera2Config resultCaptureConfig =
                 new Camera2Config(captureConfig.getImplementationOptions());
-        assertThat(
-                resultCaptureConfig.getCaptureRequestOption(
-                        CaptureRequest.CONTROL_AE_MODE, null))
-                .isEqualTo(CaptureRequest.CONTROL_AE_MODE_ON);
+
+        assertAeMode(resultCaptureConfig, CONTROL_AE_MODE_ON);
+
     }
 
     @Test
@@ -522,8 +369,287 @@
         Camera2Config sharedOptions =
                 new Camera2Config(mCamera2CameraControl.getSharedOptions());
 
-        assertThat(resultCaptureConfig.getCaptureRequestOption(CaptureRequest.CONTROL_AF_MODE,
-                null)).isEqualTo(
+        assertAfMode(resultCaptureConfig,
                 sharedOptions.getCaptureRequestOption(CaptureRequest.CONTROL_AF_MODE, null));
     }
+
+    @Test
+    public void startFocusAndMetering_3ARegionsUpdatedInSessionAndSharedOptions()
+            throws InterruptedException {
+        SensorOrientedMeteringPointFactory factory = new SensorOrientedMeteringPointFactory(1.0f,
+                1.0f);
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(factory.createPoint(0, 0))
+                .build();
+        mCamera2CameraControl.startFocusAndMetering(action);
+
+        HandlerUtil.waitForLooperToIdle(mHandler);
+
+        verify(mControlUpdateListener, times(1)).onCameraControlUpdateSessionConfig(
+                mSessionConfigArgumentCaptor.capture());
+        SessionConfig sessionConfig = mSessionConfigArgumentCaptor.getValue();
+        Camera2Config repeatingConfig = new Camera2Config(sessionConfig.getImplementationOptions());
+
+        // Here we verify only 3A region count is correct.  Values correctness are left to
+        // FocusMeteringControlTest.
+        assertThat(
+                repeatingConfig.getCaptureRequestOption(
+                        CaptureRequest.CONTROL_AF_REGIONS, null)).hasLength(1);
+        assertThat(
+                repeatingConfig.getCaptureRequestOption(
+                        CaptureRequest.CONTROL_AE_REGIONS, null)).hasLength(1);
+        assertThat(
+                repeatingConfig.getCaptureRequestOption(
+                        CaptureRequest.CONTROL_AWB_REGIONS, null)).hasLength(1);
+
+
+        Camera2Config singleConfig = new Camera2Config(mCamera2CameraControl.getSharedOptions());
+        assertThat(
+                singleConfig.getCaptureRequestOption(
+                        CaptureRequest.CONTROL_AF_REGIONS, null)).hasLength(1);
+        assertThat(
+                singleConfig.getCaptureRequestOption(
+                        CaptureRequest.CONTROL_AE_REGIONS, null)).hasLength(1);
+        assertThat(
+                singleConfig.getCaptureRequestOption(
+                        CaptureRequest.CONTROL_AWB_REGIONS, null)).hasLength(1);
+    }
+
+    @Test
+    public void startFocusAndMetering_AfIsTriggeredProperly() throws InterruptedException {
+        SensorOrientedMeteringPointFactory factory = new SensorOrientedMeteringPointFactory(1.0f,
+                1.0f);
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(factory.createPoint(0, 0))
+                .build();
+        mCamera2CameraControl.startFocusAndMetering(action);
+        HandlerUtil.waitForLooperToIdle(mHandler);
+
+        verifyAfMode(CaptureRequest.CONTROL_AF_MODE_AUTO);
+
+        verify(mControlUpdateListener).onCameraControlCaptureRequests(
+                mCaptureConfigArgumentCaptor.capture());
+
+        CaptureConfig captureConfig = mCaptureConfigArgumentCaptor.getValue().get(0);
+        Camera2Config resultCaptureConfig =
+                new Camera2Config(captureConfig.getImplementationOptions());
+
+        // Trigger AF
+        assertThat(resultCaptureConfig.getCaptureRequestOption(CaptureRequest.CONTROL_AF_TRIGGER,
+                null)).isEqualTo(CaptureRequest.CONTROL_AF_TRIGGER_START);
+    }
+
+    @Test
+    public void startFocusAndMetering_AFNotInvolved_AfIsNotTriggered() throws InterruptedException {
+        SensorOrientedMeteringPointFactory factory = new SensorOrientedMeteringPointFactory(1.0f,
+                1.0f);
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(factory.createPoint(0, 0),
+                MeteringMode.AE_AWB)
+                .build();
+        mCamera2CameraControl.startFocusAndMetering(action);
+        HandlerUtil.waitForLooperToIdle(mHandler);
+
+        verifyAfMode(CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+
+        verify(mControlUpdateListener, never()).onCameraControlCaptureRequests(any());
+    }
+
+    @Test
+    public void cancelFocusAndMetering_3ARegionsReset() throws InterruptedException {
+        SensorOrientedMeteringPointFactory factory = new SensorOrientedMeteringPointFactory(1.0f,
+                1.0f);
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(factory.createPoint(0, 0))
+                .build();
+        mCamera2CameraControl.startFocusAndMetering(action);
+        HandlerUtil.waitForLooperToIdle(mHandler);
+        Mockito.reset(mControlUpdateListener);
+
+        mCamera2CameraControl.cancelFocusAndMetering();
+        HandlerUtil.waitForLooperToIdle(mHandler);
+
+        verify(mControlUpdateListener, times(1)).onCameraControlUpdateSessionConfig(
+                mSessionConfigArgumentCaptor.capture());
+        SessionConfig sessionConfig = mSessionConfigArgumentCaptor.getValue();
+        Camera2Config repeatingConfig = new Camera2Config(sessionConfig.getImplementationOptions());
+
+        assertThat(
+                repeatingConfig.getCaptureRequestOption(
+                        CaptureRequest.CONTROL_AF_REGIONS, null)).isNull();
+        assertThat(
+                repeatingConfig.getCaptureRequestOption(
+                        CaptureRequest.CONTROL_AE_REGIONS, null)).isNull();
+        assertThat(
+                repeatingConfig.getCaptureRequestOption(
+                        CaptureRequest.CONTROL_AWB_REGIONS, null)).isNull();
+
+
+        Camera2Config singleConfig = new Camera2Config(mCamera2CameraControl.getSharedOptions());
+        assertThat(
+                singleConfig.getCaptureRequestOption(
+                        CaptureRequest.CONTROL_AF_REGIONS, null)).isNull();
+        assertThat(
+                singleConfig.getCaptureRequestOption(
+                        CaptureRequest.CONTROL_AE_REGIONS, null)).isNull();
+        assertThat(
+                singleConfig.getCaptureRequestOption(
+                        CaptureRequest.CONTROL_AWB_REGIONS, null)).isNull();
+    }
+
+    @Test
+    public void cancelFocusAndMetering_cancelAfProperly() throws InterruptedException {
+        SensorOrientedMeteringPointFactory factory = new SensorOrientedMeteringPointFactory(1.0f,
+                1.0f);
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(factory.createPoint(0, 0))
+                .build();
+        mCamera2CameraControl.startFocusAndMetering(action);
+        HandlerUtil.waitForLooperToIdle(mHandler);
+        Mockito.reset(mControlUpdateListener);
+        mCamera2CameraControl.cancelFocusAndMetering();
+        HandlerUtil.waitForLooperToIdle(mHandler);
+
+        verifyAfMode(CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+
+        verify(mControlUpdateListener).onCameraControlCaptureRequests(
+                mCaptureConfigArgumentCaptor.capture());
+
+        CaptureConfig captureConfig = mCaptureConfigArgumentCaptor.getValue().get(0);
+        Camera2Config resultCaptureConfig =
+                new Camera2Config(captureConfig.getImplementationOptions());
+
+        // Trigger AF
+        assertThat(resultCaptureConfig.getCaptureRequestOption(CaptureRequest.CONTROL_AF_TRIGGER,
+                null)).isEqualTo(CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
+    }
+
+    private void verifyAfMode(int expectAfMode) {
+        verify(mControlUpdateListener, times(1)).onCameraControlUpdateSessionConfig(
+                mSessionConfigArgumentCaptor.capture());
+        SessionConfig sessionConfig = mSessionConfigArgumentCaptor.getValue();
+        Camera2Config repeatingConfig = new Camera2Config(sessionConfig.getImplementationOptions());
+        assertThat(repeatingConfig.getCaptureRequestOption(CaptureRequest.CONTROL_AF_MODE,
+                null)).isEqualTo(expectAfMode);
+    }
+
+    @Test
+    public void cancelFocusAndMetering_AFNotInvolved_notCancelAF() throws InterruptedException {
+        SensorOrientedMeteringPointFactory factory = new SensorOrientedMeteringPointFactory(1.0f,
+                1.0f);
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(factory.createPoint(0, 0),
+                MeteringMode.AE_ONLY)
+                .build();
+        mCamera2CameraControl.startFocusAndMetering(action);
+        HandlerUtil.waitForLooperToIdle(mHandler);
+        Mockito.reset(mControlUpdateListener);
+        mCamera2CameraControl.cancelFocusAndMetering();
+        HandlerUtil.waitForLooperToIdle(mHandler);
+
+        verify(mControlUpdateListener, never()).onCameraControlCaptureRequests(any());
+
+        verifyAfMode(CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+    }
+
+    @Test
+    public void startFocus_afModeIsSetToAuto() throws InterruptedException {
+        SensorOrientedMeteringPointFactory factory = new SensorOrientedMeteringPointFactory(1.0f,
+                1.0f);
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(factory.createPoint(0, 0))
+                .build();
+        mCamera2CameraControl.startFocusAndMetering(action);
+        HandlerUtil.waitForLooperToIdle(mHandler);
+
+        Camera2Config singleConfig = new Camera2Config(mCamera2CameraControl.getSharedOptions());
+
+        mCamera2CameraControl.cancelFocusAndMetering();
+        HandlerUtil.waitForLooperToIdle(mHandler);
+
+        Camera2Config singleConfig2 = new Camera2Config(mCamera2CameraControl.getSharedOptions());
+
+        assertThat(
+                singleConfig.getCaptureRequestOption(
+                        CaptureRequest.CONTROL_AF_MODE, null))
+                .isEqualTo(CaptureRequest.CONTROL_AF_MODE_AUTO);
+        assertThat(
+                singleConfig2.getCaptureRequestOption(
+                        CaptureRequest.CONTROL_AF_MODE, null))
+                       .isEqualTo(CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+    }
+
+    private boolean isAfModeSupported(int afMode) {
+        int[] modes = mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);
+        return isModeInList(afMode, modes);
+    }
+
+    private boolean isAeModeSupported(int aeMode) {
+        int[] modes = mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES);
+        return isModeInList(aeMode, modes);
+    }
+
+    private boolean isAwbModeSupported(int awbMode) {
+        int[] modes = mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES);
+        return isModeInList(awbMode, modes);
+    }
+
+
+    private boolean isModeInList(int mode, int[] modeList) {
+        if (modeList == null) {
+            return false;
+        }
+        for (int m : modeList) {
+            if (mode == m) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void assertAfMode(Camera2Config config, int afMode) {
+        if (isAfModeSupported(afMode)) {
+            assertThat(config.getCaptureRequestOption(
+                    CaptureRequest.CONTROL_AF_MODE, null)).isEqualTo(afMode);
+        } else {
+            int fallbackMode;
+            if (isAfModeSupported(CONTROL_AF_MODE_CONTINUOUS_PICTURE)) {
+                fallbackMode = CONTROL_AF_MODE_CONTINUOUS_PICTURE;
+            } else if (isAfModeSupported(CONTROL_AF_MODE_AUTO)) {
+                fallbackMode = CONTROL_AF_MODE_AUTO;
+            } else {
+                fallbackMode = CONTROL_AF_MODE_OFF;
+            }
+
+            assertThat(config.getCaptureRequestOption(
+                    CaptureRequest.CONTROL_AF_MODE, null)).isEqualTo(fallbackMode);
+        }
+    }
+
+    private void assertAeMode(Camera2Config config, int aeMode) {
+        if (isAeModeSupported(aeMode)) {
+            assertThat(config.getCaptureRequestOption(
+                    CaptureRequest.CONTROL_AE_MODE, null)).isEqualTo(aeMode);
+        } else {
+            int fallbackMode;
+            if (isAeModeSupported(CONTROL_AE_MODE_ON)) {
+                fallbackMode = CONTROL_AE_MODE_ON;
+            } else {
+                fallbackMode = CONTROL_AE_MODE_OFF;
+            }
+
+            assertThat(config.getCaptureRequestOption(
+                    CaptureRequest.CONTROL_AE_MODE, null)).isEqualTo(fallbackMode);
+        }
+    }
+
+    private void assertAwbMode(Camera2Config config, int awbMode) {
+        if (isAwbModeSupported(awbMode)) {
+            assertThat(config.getCaptureRequestOption(
+                    CaptureRequest.CONTROL_AWB_MODE, null)).isEqualTo(awbMode);
+        } else {
+            int fallbackMode;
+            if (isAwbModeSupported(CONTROL_AWB_MODE_AUTO)) {
+                fallbackMode = CONTROL_AWB_MODE_AUTO;
+            } else {
+                fallbackMode = CONTROL_AWB_MODE_OFF;
+            }
+
+            assertThat(config.getCaptureRequestOption(
+                    CaptureRequest.CONTROL_AWB_MODE, null)).isEqualTo(fallbackMode);
+        }
+    }
 }
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2ImplCameraXTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2ImplCameraXTest.java
index 17736c4..197592a 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2ImplCameraXTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2ImplCameraXTest.java
@@ -27,7 +27,9 @@
 
 import android.Manifest;
 import android.content.Context;
+import android.hardware.camera2.CameraAccessException;
 import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraDevice;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -38,6 +40,7 @@
 import androidx.camera.camera2.Camera2Config;
 import androidx.camera.camera2.impl.util.SemaphoreReleasingCamera2Callbacks.DeviceStateCallback;
 import androidx.camera.camera2.impl.util.SemaphoreReleasingCamera2Callbacks.SessionCaptureCallback;
+import androidx.camera.core.CameraInfoUnavailableException;
 import androidx.camera.core.CameraX;
 import androidx.camera.core.CameraX.LensFacing;
 import androidx.camera.core.ImageAnalysis;
@@ -157,7 +160,18 @@
     }
 
     @Test
-    public void removedUseCase_doesNotStreamWhenLifecycleResumes() throws InterruptedException {
+    public void removedUseCase_doesNotStreamWhenLifecycleResumes() throws NullPointerException,
+            CameraAccessException, CameraInfoUnavailableException {
+        // Legacy device would not support two ImageAnalysis use cases combination.
+        int hardwareLevelValue;
+        CameraCharacteristics cameraCharacteristics =
+                CameraUtil.getCameraManager().getCameraCharacteristics(
+                        CameraX.getCameraWithLensFacing(DEFAULT_LENS_FACING));
+        hardwareLevelValue = cameraCharacteristics.get(
+                CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
+        assumeTrue(
+                hardwareLevelValue != CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY);
+
         Observer<Long> mockObserver = Mockito.mock(Observer.class);
         Observer<Long> mockObserver2 = Mockito.mock(Observer.class);
 
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/CameraImplTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/CameraImplTest.java
index 0ede6cc..9e8d7c2 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/CameraImplTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/CameraImplTest.java
@@ -20,8 +20,10 @@
 
 import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
 
 import android.Manifest;
 import android.graphics.ImageFormat;
@@ -29,14 +31,13 @@
 import android.media.ImageReader;
 import android.os.Handler;
 import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.MessageQueue;
 import android.util.Size;
 
+import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
-import androidx.camera.camera2.Camera2Config;
+import androidx.annotation.Nullable;
+import androidx.camera.core.BaseCamera;
 import androidx.camera.core.CameraCaptureCallback;
-import androidx.camera.core.CameraCaptureCallbacks;
 import androidx.camera.core.CameraCaptureResult;
 import androidx.camera.core.CameraDeviceConfig;
 import androidx.camera.core.CameraFactory;
@@ -44,10 +45,14 @@
 import androidx.camera.core.CaptureConfig;
 import androidx.camera.core.DeferrableSurface;
 import androidx.camera.core.ImmediateSurface;
+import androidx.camera.core.Observable;
 import androidx.camera.core.SessionConfig;
 import androidx.camera.core.UseCase;
 import androidx.camera.core.UseCaseConfig;
+import androidx.camera.core.impl.utils.executor.CameraXExecutors;
+import androidx.camera.core.impl.utils.futures.Futures;
 import androidx.camera.testing.CameraUtil;
+import androidx.camera.testing.HandlerUtil;
 import androidx.camera.testing.fakes.FakeUseCase;
 import androidx.camera.testing.fakes.FakeUseCaseConfig;
 import androidx.test.core.app.ApplicationProvider;
@@ -55,20 +60,27 @@
 import androidx.test.filters.LargeTest;
 import androidx.test.rule.GrantPermissionRule;
 
+import com.google.common.util.concurrent.ListenableFuture;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mockito;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
-import java.util.concurrent.CountDownLatch;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
 import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Contains tests for {@link androidx.camera.camera2.impl.Camera} internal implementation.
@@ -77,24 +89,25 @@
 @RunWith(AndroidJUnit4.class)
 public class CameraImplTest {
     private static final CameraX.LensFacing DEFAULT_LENS_FACING = CameraX.LensFacing.BACK;
-    static CameraFactory sCameraFactory;
+    private static final Set<BaseCamera.State> STABLE_STATES = new HashSet<>(Arrays.asList(
+            BaseCamera.State.CLOSED,
+            BaseCamera.State.OPEN,
+            BaseCamera.State.RELEASED));
 
-    private Camera mCamera;
-    private String mCameraId;
+    private static CameraFactory sCameraFactory;
 
-    Semaphore mSemaphore;
-
-    CountDownLatch mLatchForDeviceClose;
-    private HandlerThread mCameraHandlerThread;
-    private Handler mCameraHandler;
-    MessageQueue mMessageQueue;
-    private boolean mWaitCameraCloseAtTearDown = true;
-
-    private CameraDevice.StateCallback mDeviceStateCallback;
+    // For the purpose of this test, always say we have 1 camera available.
+    private static final int DEFAULT_AVAILABLE_CAMERA_COUNT = 1;
 
     @Rule
     public GrantPermissionRule mRuntimePermissionRule = GrantPermissionRule.grant(
             Manifest.permission.CAMERA);
+    Semaphore mSemaphore;
+    private Camera mCamera;
+    private String mCameraId;
+    private HandlerThread mCameraHandlerThread;
+    private Handler mCameraHandler;
+    private SettableObservable<Integer> mAvailableCameras;
 
     private static String getCameraIdForLensFacingUnchecked(CameraX.LensFacing lensFacing) {
         try {
@@ -119,53 +132,20 @@
         mCameraHandlerThread.start();
         mCameraHandler = new Handler(mCameraHandlerThread.getLooper());
         mSemaphore = new Semaphore(0);
-        mCamera = new Camera(CameraUtil.getCameraManager(), mCameraId, mCameraHandler);
-        mLatchForDeviceClose = new CountDownLatch(1);
-
-        // To get MessageQueue from HandlerThread.
-        final CountDownLatch latchforMsgQueue = new CountDownLatch(1);
-        mCameraHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                mMessageQueue = Looper.myQueue();
-                latchforMsgQueue.countDown();
-            }
-        });
-
-        try {
-            latchforMsgQueue.await(1, TimeUnit.SECONDS);
-        } catch (InterruptedException e) {
-        }
-
-        mDeviceStateCallback = new CameraDevice.StateCallback() {
-            @Override
-            public void onOpened(@NonNull CameraDevice camera) {
-            }
-
-            @Override
-            public void onClosed(@NonNull CameraDevice camera) {
-                mLatchForDeviceClose.countDown();
-            }
-
-            @Override
-            public void onDisconnected(@NonNull CameraDevice camera) {
-            }
-
-            @Override
-            public void onError(@NonNull CameraDevice camera, int error) {
-            }
-        };
+        mAvailableCameras = new SettableObservable<>(DEFAULT_AVAILABLE_CAMERA_COUNT);
+        mCamera = new Camera(CameraUtil.getCameraManager(), mCameraId, mAvailableCameras,
+                mCameraHandler);
     }
 
     @After
-    public void teardown() throws InterruptedException {
+    public void teardown() throws InterruptedException, ExecutionException {
         if (mCamera != null) {
-            mCamera.release();
-            mCamera = null;
-        }
+            ListenableFuture<Void> cameraReleaseFuture = mCamera.release();
 
-        if (mWaitCameraCloseAtTearDown && mLatchForDeviceClose != null) {
-            mLatchForDeviceClose.await(2, TimeUnit.SECONDS);
+            // Wait for camera to be fully closed
+            cameraReleaseFuture.get();
+
+            mCamera = null;
         }
 
         if (mCameraHandlerThread != null) {
@@ -192,32 +172,11 @@
         mSemaphore.release();
     }
 
-    // wait until camera thread is idle
-    private void waitHandlerIdle() {
-        final CountDownLatch latchForWaitIdle = new CountDownLatch(1);
-
-        // If the posted runnable runs, it means the previous runnnables are already executed.
-        mMessageQueue.addIdleHandler(new MessageQueue.IdleHandler() {
-            @Override
-            public boolean queueIdle() {
-                latchForWaitIdle.countDown();
-                return false;
-
-            }
-        });
-
-        try {
-            latchForWaitIdle.await(3, TimeUnit.SECONDS);
-        } catch (InterruptedException e) {
-        }
-    }
-
     private UseCase createUseCase() {
         FakeUseCaseConfig.Builder configBuilder =
                 new FakeUseCaseConfig.Builder()
                         .setTargetName("UseCase")
                         .setLensFacing(DEFAULT_LENS_FACING);
-        new Camera2Config.Extender(configBuilder).setDeviceStateCallback(mDeviceStateCallback);
         TestUseCase testUseCase = new TestUseCase(configBuilder.build());
         Map<String, Size> suggestedResolutionMap = new HashMap<>();
         suggestedResolutionMap.put(mCameraId, new Size(640, 480));
@@ -233,7 +192,7 @@
     }
 
     @Test
-    public void addOnline_OneUseCase() {
+    public void addOnline_OneUseCase() throws InterruptedException {
         blockHandler();
 
         UseCase useCase1 = createUseCase();
@@ -243,7 +202,7 @@
         assertThat(mCamera.isUseCaseOnline(useCase1)).isFalse();
 
         unblockHandler();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         assertThat(mCamera.isUseCaseOnline(useCase1)).isTrue();
 
@@ -262,19 +221,20 @@
         assertThat(mCamera.isUseCaseOnline(useCase1)).isFalse();
 
         mCamera.removeOnlineUseCase(Arrays.asList(useCase1));
-        mWaitCameraCloseAtTearDown = false;
+
+        unblockHandler();
     }
 
 
     @Test
-    public void addOnline_alreadyOnline() {
+    public void addOnline_alreadyOnline() throws InterruptedException {
         blockHandler();
 
         UseCase useCase1 = createUseCase();
         mCamera.addOnlineUseCase(Arrays.asList(useCase1));
         assertThat(getUseCaseSurface(useCase1).getAttachedCount()).isEqualTo(1);
         unblockHandler();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         //Usecase1 is online now.
         assertThat(mCamera.isUseCaseOnline(useCase1)).isTrue();
@@ -286,7 +246,7 @@
         // Surface is attached when (1) UseCase added to online (2) Camera session opened
         // So here we need to wait until camera close before we start to verify the attach count
         mCamera.close();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         // Surface is only attached once.
         assertThat(getUseCaseSurface(useCase1).getAttachedCount()).isEqualTo(1);
@@ -296,7 +256,7 @@
     }
 
     @Test
-    public void addOnline_twoUseCases() {
+    public void addOnline_twoUseCases() throws InterruptedException {
         blockHandler();
 
         UseCase useCase1 = createUseCase();
@@ -310,7 +270,7 @@
         assertThat(mCamera.isUseCaseOnline(useCase2)).isFalse();
 
         unblockHandler();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         assertThat(mCamera.isUseCaseOnline(useCase1)).isTrue();
         assertThat(mCamera.isUseCaseOnline(useCase2)).isTrue();
@@ -319,14 +279,14 @@
     }
 
     @Test
-    public void addOnline_fromPendingOffline() {
+    public void addOnline_fromPendingOffline() throws InterruptedException {
         blockHandler();
 
         // First make UseCase online
         UseCase useCase = createUseCase();
         mCamera.addOnlineUseCase(Arrays.asList(useCase));
         unblockHandler();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         blockHandler();
         // Then make it offline but pending for Camera thread to run it.
@@ -336,35 +296,33 @@
         mCamera.addOnlineUseCase(Arrays.asList(useCase));
 
         unblockHandler();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         assertThat(mCamera.isUseCaseOnline(useCase)).isTrue();
 
         mCamera.close();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
         assertThat(getUseCaseSurface(useCase).getAttachedCount()).isEqualTo(1);
 
         mCamera.removeOnlineUseCase(Arrays.asList(useCase));
     }
 
     @Test
-    public void removeOnline_notOnline() {
+    public void removeOnline_notOnline() throws InterruptedException {
         blockHandler();
 
         UseCase useCase1 = createUseCase();
         mCamera.removeOnlineUseCase(Arrays.asList(useCase1));
 
         unblockHandler();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         // It should not be detached so the attached count should still be 0
         assertThat(getUseCaseSurface(useCase1).getAttachedCount()).isEqualTo(0);
-
-        mWaitCameraCloseAtTearDown = false;
     }
 
     @Test
-    public void removeOnline_fromPendingOnline() {
+    public void removeOnline_fromPendingOnline() throws InterruptedException {
         blockHandler();
 
         UseCase useCase1 = createUseCase();
@@ -374,14 +332,14 @@
         mCamera.removeOnlineUseCase(Arrays.asList(useCase1));
 
         unblockHandler();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         assertThat(mCamera.isUseCaseOnline(useCase1)).isFalse();
         assertThat(getUseCaseSurface(useCase1).getAttachedCount()).isEqualTo(0);
     }
 
     @Test
-    public void removeOnline_fromOnlineUseCases() {
+    public void removeOnline_fromOnlineUseCases() throws InterruptedException {
         blockHandler();
 
         UseCase useCase1 = createUseCase();
@@ -389,7 +347,7 @@
         mCamera.addOnlineUseCase(Arrays.asList(useCase1, useCase2));
 
         unblockHandler();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         assertThat(mCamera.isUseCaseOnline(useCase1)).isTrue();
         assertThat(mCamera.isUseCaseOnline(useCase2)).isTrue();
@@ -398,7 +356,7 @@
         mCamera.removeOnlineUseCase(Arrays.asList(useCase1));
 
         unblockHandler();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         assertThat(mCamera.isUseCaseOnline(useCase1)).isFalse();
         assertThat(mCamera.isUseCaseOnline(useCase2)).isTrue();
@@ -406,7 +364,7 @@
         // Surface is attached when (1) UseCase added to online (2) Camera session opened
         // So here we need to wait until camera close before we start to verify the attach count
         mCamera.close();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         assertThat(getUseCaseSurface(useCase1).getAttachedCount()).isEqualTo(0);
         assertThat(getUseCaseSurface(useCase2).getAttachedCount()).isEqualTo(1);
@@ -416,7 +374,7 @@
     }
 
     @Test
-    public void removeOnline_twoSameUseCase() {
+    public void removeOnline_twoSameUseCase() throws InterruptedException {
         blockHandler();
 
         UseCase useCase1 = createUseCase();
@@ -424,7 +382,7 @@
         mCamera.addOnlineUseCase(Arrays.asList(useCase1, useCase2));
 
         unblockHandler();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         // remove twice
         blockHandler();
@@ -435,7 +393,7 @@
         // Surface is attached when (1) UseCase added to online (2) Camera session opened
         // So here we need to wait until camera close before we start to verify the attach count
         mCamera.close();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         assertThat(getUseCaseSurface(useCase1).getAttachedCount()).isEqualTo(0);
 
@@ -443,7 +401,8 @@
     }
 
     @Test
-    public void onlineUseCase_changeSurface_onUseCaseUpdated_correctAttachCount() {
+    public void onlineUseCase_changeSurface_onUseCaseUpdated_correctAttachCount()
+            throws ExecutionException, InterruptedException {
         blockHandler();
 
         UseCase useCase1 = createUseCase();
@@ -451,14 +410,15 @@
         DeferrableSurface surface1 = useCase1.getSessionConfig(mCameraId).getSurfaces().get(0);
 
         unblockHandler();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         changeUseCaseSurface(useCase1);
         mCamera.onUseCaseUpdated(useCase1);
         DeferrableSurface surface2 = useCase1.getSessionConfig(mCameraId).getSurfaces().get(0);
 
-        mCamera.close();
-        waitHandlerIdle();
+        // Wait for camera to be released to ensure it has finished closing
+        ListenableFuture<Void> releaseFuture = mCamera.release();
+        releaseFuture.get();
 
         assertThat(surface1).isNotEqualTo(surface2);
 
@@ -471,7 +431,8 @@
     }
 
     @Test
-    public void onlineUseCase_changeSurface_onUseCaseReset_correctAttachCount() {
+    public void onlineUseCase_changeSurface_onUseCaseReset_correctAttachCount()
+            throws ExecutionException, InterruptedException {
         blockHandler();
 
         UseCase useCase1 = createUseCase();
@@ -479,14 +440,15 @@
         DeferrableSurface surface1 = useCase1.getSessionConfig(mCameraId).getSurfaces().get(0);
 
         unblockHandler();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         changeUseCaseSurface(useCase1);
         mCamera.onUseCaseReset(useCase1);
         DeferrableSurface surface2 = useCase1.getSessionConfig(mCameraId).getSurfaces().get(0);
 
-        mCamera.close();
-        waitHandlerIdle();
+        // Wait for camera to be released to ensure it has finished closing
+        ListenableFuture<Void> releaseFuture = mCamera.release();
+        releaseFuture.get();
 
         assertThat(surface1).isNotEqualTo(surface2);
 
@@ -498,7 +460,8 @@
     }
 
     @Test
-    public void onlineUseCase_changeSurface_onUseCaseActive_correctAttachCount() {
+    public void onlineUseCase_changeSurface_onUseCaseActive_correctAttachCount()
+            throws ExecutionException, InterruptedException {
         blockHandler();
 
         UseCase useCase1 = createUseCase();
@@ -506,14 +469,15 @@
         DeferrableSurface surface1 = useCase1.getSessionConfig(mCameraId).getSurfaces().get(0);
 
         unblockHandler();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         changeUseCaseSurface(useCase1);
         mCamera.onUseCaseActive(useCase1);
         DeferrableSurface surface2 = useCase1.getSessionConfig(mCameraId).getSurfaces().get(0);
 
-        mCamera.close();
-        waitHandlerIdle();
+        // Wait for camera to be released to ensure it has finished closing
+        ListenableFuture<Void> releaseFuture = mCamera.release();
+        releaseFuture.get();
 
         assertThat(surface1).isNotEqualTo(surface2);
 
@@ -527,7 +491,8 @@
 
 
     @Test
-    public void offlineUseCase_changeSurface_onUseCaseUpdated_correctAttachCount() {
+    public void offlineUseCase_changeSurface_onUseCaseUpdated_correctAttachCount()
+            throws ExecutionException, InterruptedException {
         blockHandler();
 
         UseCase useCase1 = createUseCase();
@@ -538,13 +503,13 @@
         DeferrableSurface surface1 = useCase1.getSessionConfig(mCameraId).getSurfaces().get(0);
 
         unblockHandler();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         changeUseCaseSurface(useCase1);
         mCamera.onUseCaseUpdated(useCase1);
         DeferrableSurface surface2 = useCase1.getSessionConfig(mCameraId).getSurfaces().get(0);
 
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         assertThat(surface1).isNotEqualTo(surface2);
 
@@ -554,8 +519,10 @@
 
         // make useCase1 online
         mCamera.addOnlineUseCase(Arrays.asList(useCase1));
-        mCamera.close();
-        waitHandlerIdle();
+
+        // Wait for camera to be released to ensure it has finished closing
+        ListenableFuture<Void> releaseFuture = mCamera.release();
+        releaseFuture.get();
 
         // only surface2 is attached.
         assertThat(surface1.getAttachedCount()).isEqualTo(0);
@@ -568,26 +535,17 @@
     public void pendingSingleRequestRunSucessfully_whenAnotherUseCaseOnline()
             throws InterruptedException {
 
-        final Semaphore semaphoreForCapture = new Semaphore(0);
         // Block camera thread to queue all the camera operations.
         blockHandler();
 
         UseCase useCase1 = createUseCase();
         mCamera.addOnlineUseCase(Arrays.asList(useCase1));
 
-        CameraCaptureCallback captureCallback = Mockito.mock(CameraCaptureCallback.class);
+        CameraCaptureCallback captureCallback = mock(CameraCaptureCallback.class);
         CaptureConfig.Builder captureConfigBuilder = new CaptureConfig.Builder();
         captureConfigBuilder.setTemplateType(CameraDevice.TEMPLATE_PREVIEW);
         captureConfigBuilder.addSurface(useCase1.getSessionConfig(mCameraId).getSurfaces().get(0));
-        captureConfigBuilder.addCameraCaptureCallback(CameraCaptureCallbacks.createComboCallback(
-                captureCallback,
-                new CameraCaptureCallback() {
-                    @Override
-                    public void onCaptureCompleted(
-                            @NonNull CameraCaptureResult cameraCaptureResult) {
-                        semaphoreForCapture.release();
-                    }
-                }));
+        captureConfigBuilder.addCameraCaptureCallback(captureCallback);
 
         mCamera.getCameraControlInternal().submitCaptureRequests(
                 Arrays.asList(captureConfigBuilder.build()));
@@ -599,8 +557,7 @@
         // To make the single request not able to run in 1st capture session.  and verify if it can
         // be carried over to the new capture session and run successfully.
         unblockHandler();
-
-        semaphoreForCapture.tryAcquire(3000, TimeUnit.MILLISECONDS);
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         // CameraCaptureCallback.onCaptureCompleted() should be called to signal a capture attempt.
         verify(captureCallback, timeout(3000).times(1))
@@ -611,7 +568,6 @@
     public void pendingSingleRequestSkipped_whenTheUseCaseIsRemoved()
             throws InterruptedException {
 
-        final Semaphore semaphoreForCapture = new Semaphore(0);
         // Block camera thread to queue all the camera operations.
         blockHandler();
 
@@ -620,20 +576,11 @@
 
         mCamera.addOnlineUseCase(Arrays.asList(useCase1, useCase2));
 
-        CameraCaptureCallback captureCallback = Mockito.mock(CameraCaptureCallback.class);
+        CameraCaptureCallback captureCallback = mock(CameraCaptureCallback.class);
         CaptureConfig.Builder captureConfigBuilder = new CaptureConfig.Builder();
         captureConfigBuilder.setTemplateType(CameraDevice.TEMPLATE_PREVIEW);
         captureConfigBuilder.addSurface(useCase1.getSessionConfig(mCameraId).getSurfaces().get(0));
-        captureConfigBuilder.addCameraCaptureCallback(CameraCaptureCallbacks.createComboCallback(
-                captureCallback,
-                new CameraCaptureCallback() {
-                    @Override
-                    public void onCaptureCompleted(
-                            @NonNull CameraCaptureResult cameraCaptureResult) {
-                        semaphoreForCapture.release();
-                    }
-
-                }));
+        captureConfigBuilder.addCameraCaptureCallback(captureCallback);
 
         mCamera.getCameraControlInternal().submitCaptureRequests(
                 Arrays.asList(captureConfigBuilder.build()));
@@ -643,16 +590,126 @@
         // To make the single request not able to run in 1st capture session.  and verify if it can
         // be carried to the new capture session and run successfully.
         unblockHandler();
-        waitHandlerIdle();
+        HandlerUtil.waitForLooperToIdle(mCameraHandler);
 
         // TODO: b/133710422 should provide a way to detect if request is cancelled.
         Thread.sleep(1000);
 
         // CameraCaptureCallback.onCaptureCompleted() is not called and there is no crash.
-        verify(captureCallback, timeout(3000).times(0))
+        verify(captureCallback, times(0))
                 .onCaptureCompleted(any(CameraCaptureResult.class));
     }
 
+    @Test
+    public void cameraStateIsClosed_afterInitialization()
+            throws ExecutionException, InterruptedException {
+        Observable<BaseCamera.State> state = mCamera.getCameraState();
+        BaseCamera.State currentState = state.fetchData().get();
+        assertThat(currentState).isEqualTo(BaseCamera.State.CLOSED);
+    }
+
+    @Test
+    public void cameraStateTransitionTest() throws InterruptedException {
+
+        final AtomicReference<BaseCamera.State> lastStableState = new AtomicReference<>(null);
+        Observable.Observer<BaseCamera.State> observer =
+                new Observable.Observer<BaseCamera.State>() {
+                    @Override
+                    public void onNewData(@Nullable BaseCamera.State value) {
+                        // Ignore any transient states.
+                        if (STABLE_STATES.contains(value)) {
+                            lastStableState.set(value);
+                            mSemaphore.release();
+                        }
+                    }
+
+                    @Override
+                    public void onError(@NonNull Throwable t) { /* Ignore any transient errors. */ }
+                };
+
+        List<BaseCamera.State> observedStates = new ArrayList<>();
+        mCamera.getCameraState().addObserver(CameraXExecutors.directExecutor(), observer);
+
+        // Wait for initial CLOSED state
+        mSemaphore.acquire();
+        observedStates.add(lastStableState.get());
+
+        // Wait for OPEN state
+        mCamera.open();
+        mSemaphore.acquire();
+        observedStates.add(lastStableState.get());
+
+        // Wait for CLOSED state again
+        mCamera.close();
+        mSemaphore.acquire();
+        observedStates.add(lastStableState.get());
+
+        // Wait for RELEASED state
+        mCamera.release();
+        mSemaphore.acquire();
+        observedStates.add(lastStableState.get());
+
+        mCamera.getCameraState().removeObserver(observer);
+
+        assertThat(observedStates).containsExactly(
+                BaseCamera.State.CLOSED,
+                BaseCamera.State.OPEN,
+                BaseCamera.State.CLOSED,
+                BaseCamera.State.RELEASED);
+    }
+
+    @Test
+    public void cameraTransitionsThroughPendingState_whenNoCamerasAvailable() {
+        @SuppressWarnings("unchecked") // Cannot mock generic type inline
+                Observable.Observer<BaseCamera.State> mockObserver =
+                mock(Observable.Observer.class);
+
+        // Set the available cameras to zero
+        mAvailableCameras.setValue(0);
+
+        mCamera.getCameraState().addObserver(CameraXExecutors.directExecutor(), mockObserver);
+
+        mCamera.open();
+
+        // Ensure that the camera gets to a PENDING_OPEN state
+        verify(mockObserver, timeout(3000)).onNewData(BaseCamera.State.PENDING_OPEN);
+
+        // Allow camera to be opened
+        mAvailableCameras.setValue(1);
+
+        verify(mockObserver, timeout(3000)).onNewData(BaseCamera.State.OPEN);
+
+        mCamera.getCameraState().removeObserver(mockObserver);
+    }
+
+    @Test
+    public void cameraStateIsReleased_afterRelease()
+            throws ExecutionException, InterruptedException {
+        Observable<BaseCamera.State> state = mCamera.getCameraState();
+
+        // Wait for camera to release
+        mCamera.release().get();
+        BaseCamera.State currentState = state.fetchData().get();
+
+        assertThat(currentState).isEqualTo(BaseCamera.State.RELEASED);
+    }
+
+    @Test
+    public void cameraStopsObservingAvailableCameras_afterRelease()
+            throws ExecutionException, InterruptedException {
+        // Camera should already be observing state after initialization
+        int observerCountBefore = mAvailableCameras.getObserverCount();
+
+        // Wait for camera to release
+        mCamera.release().get();
+
+        // Observer count should now be zero
+        int observerCountAfter = mAvailableCameras.getObserverCount();
+
+        assertThat(observerCountBefore).isEqualTo(1);
+        assertThat(observerCountAfter).isEqualTo(0);
+    }
+
     private DeferrableSurface getUseCaseSurface(UseCase useCase) {
         return useCase.getSessionConfig(mCameraId).getSurfaces().get(0);
     }
@@ -662,6 +719,7 @@
         Handler mHandler;
         ImageReader mImageReader;
         FakeUseCaseConfig mConfig;
+        List<ImageReader> mPreviousReaders = new ArrayList<>();
 
         TestUseCase(
                 FakeUseCaseConfig config) {
@@ -688,6 +746,12 @@
         void close() {
             mHandler.removeCallbacksAndMessages(null);
             mHandlerThread.quitSafely();
+            for (ImageReader reader : mPreviousReaders) {
+                reader.close();
+            }
+
+            mPreviousReaders.clear();
+
             if (mImageReader != null) {
                 mImageReader.close();
             }
@@ -703,6 +767,12 @@
             SessionConfig.Builder builder = SessionConfig.Builder.createFrom(mConfig);
 
             builder.setTemplateType(CameraDevice.TEMPLATE_PREVIEW);
+            if (mImageReader != null) {
+                // Hold on to the previous reader so its Surface stays alive and it can be closed
+                // later.
+                mPreviousReaders.add(mImageReader);
+            }
+
             mImageReader =
                     ImageReader.newInstance(
                             resolution.getWidth(),
@@ -715,4 +785,74 @@
             return suggestedResolutionMap;
         }
     }
+
+    private final class SettableObservable<T> implements Observable<T> {
+
+        private final Object mLock = new Object();
+        @GuardedBy("mLock")
+        private T mValue;
+
+        @GuardedBy("mLock")
+        private Map<Observer<T>, Executor> mObservers = new HashMap<>();
+
+        SettableObservable(@Nullable T initialValue) {
+            synchronized (mLock) {
+                mValue = initialValue;
+            }
+        }
+
+        void setValue(@Nullable final T value) {
+            Map<Observer<T>, Executor> notifyMap = null;
+            synchronized (mLock) {
+                if (!Objects.equals(mValue, value)) {
+                    mValue = value;
+
+                    if (!mObservers.isEmpty()) {
+                        notifyMap = new HashMap<>(mObservers);
+                    }
+                }
+            }
+
+            if (notifyMap != null) {
+                for (Map.Entry<Observer<T>, Executor> observer : notifyMap.entrySet()) {
+                    observer.getValue().execute(() -> observer.getKey().onNewData(value));
+                }
+            }
+        }
+
+        @NonNull
+        @Override
+        public ListenableFuture<T> fetchData() {
+            synchronized (mLock) {
+                return Futures.immediateFuture(mValue);
+            }
+        }
+
+        @Override
+        public void addObserver(@NonNull Executor executor, @NonNull Observer<T> observer) {
+            boolean needsUpdate = false;
+            T value;
+            synchronized (mLock) {
+                needsUpdate = !Objects.equals(mObservers.put(observer, executor), executor);
+                value = mValue;
+            }
+
+            if (needsUpdate) {
+                executor.execute(() -> observer.onNewData(value));
+            }
+        }
+
+        @Override
+        public void removeObserver(@NonNull Observer<T> observer) {
+            synchronized (mLock) {
+                mObservers.remove(observer);
+            }
+        }
+
+        int getObserverCount() {
+            synchronized (mLock) {
+                return mObservers.size();
+            }
+        }
+    }
 }
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/CameraTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/CameraTest.java
index d07c1d5..d8de294 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/CameraTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/CameraTest.java
@@ -30,8 +30,6 @@
 import android.os.HandlerThread;
 import android.util.Size;
 
-import androidx.annotation.NonNull;
-import androidx.camera.camera2.Camera2Config;
 import androidx.camera.core.BaseCamera;
 import androidx.camera.core.CameraDeviceConfig;
 import androidx.camera.core.CameraFactory;
@@ -58,8 +56,7 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ExecutionException;
 
 @LargeTest
 @RunWith(AndroidJUnit4.class)
@@ -73,9 +70,6 @@
     OnImageAvailableListener mMockOnImageAvailableListener;
     String mCameraId;
 
-    private CountDownLatch mLatchForDeviceClose;
-    private CameraDevice.StateCallback mDeviceStateCallback;
-
     private static String getCameraIdForLensFacingUnchecked(LensFacing lensFacing) {
         try {
             return sCameraFactory.cameraIdForLensFacing(lensFacing);
@@ -95,26 +89,6 @@
         assumeTrue(CameraUtil.deviceHasCamera());
         mMockOnImageAvailableListener = Mockito.mock(ImageReader.OnImageAvailableListener.class);
 
-        mLatchForDeviceClose = new CountDownLatch(1);
-        mDeviceStateCallback = new CameraDevice.StateCallback() {
-            @Override
-            public void onOpened(@NonNull CameraDevice camera) {
-            }
-
-            @Override
-            public void onClosed(@NonNull CameraDevice camera) {
-                mLatchForDeviceClose.countDown();
-            }
-
-            @Override
-            public void onDisconnected(@NonNull CameraDevice camera) {
-            }
-
-            @Override
-            public void onError(@NonNull CameraDevice camera, int error) {
-            }
-        };
-
         mCameraId = getCameraIdForLensFacingUnchecked(DEFAULT_LENS_FACING);
         mCamera = sCameraFactory.getCamera(mCameraId);
 
@@ -122,18 +96,18 @@
                 new FakeUseCaseConfig.Builder()
                         .setTargetName("UseCase")
                         .setLensFacing(DEFAULT_LENS_FACING);
-        new Camera2Config.Extender(configBuilder).setDeviceStateCallback(mDeviceStateCallback);
         mFakeUseCase = new TestUseCase(configBuilder.build(), mMockOnImageAvailableListener);
     }
 
     @After
-    public void teardown() throws InterruptedException {
+    public void teardown() throws InterruptedException, ExecutionException {
         // Need to release the camera no matter what is done, otherwise the CameraDevice is not
         // closed.
         // When the CameraDevice is not closed, then it can cause problems with interferes with
         // other test cases.
         if (mCamera != null) {
-            mCamera.release();
+            // Wait for camera release to complete
+            mCamera.release().get();
             mCamera = null;
         }
 
@@ -142,10 +116,6 @@
             mFakeUseCase.close();
             mFakeUseCase = null;
         }
-
-        if (mLatchForDeviceClose != null) {
-            mLatchForDeviceClose.await(2, TimeUnit.SECONDS);
-        }
     }
 
     @Test
@@ -206,8 +176,6 @@
 
     @Test
     public void releaseUnopenedCamera() {
-        // bypass camera close checking
-        mLatchForDeviceClose = null;
         // Checks that if a camera has been released then calling open() will no longer open it.
         mCamera.release();
         mCamera.open();
@@ -220,8 +188,6 @@
 
     @Test
     public void releasedOpenedCamera() {
-        // bypass camera close checking
-        mLatchForDeviceClose = null;
         mCamera.open();
         mCamera.release();
 
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/CaptureSessionTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/CaptureSessionTest.java
index 507177c..1c95496 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/CaptureSessionTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/CaptureSessionTest.java
@@ -52,6 +52,8 @@
 import androidx.camera.core.ImmediateSurface;
 import androidx.camera.core.MutableOptionsBundle;
 import androidx.camera.core.SessionConfig;
+import androidx.camera.core.impl.utils.executor.CameraXExecutors;
+import androidx.camera.core.impl.utils.futures.Futures;
 import androidx.camera.testing.CameraUtil;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
@@ -69,10 +71,13 @@
 import org.mockito.InOrder;
 import org.mockito.Mockito;
 
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
+import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -88,6 +93,8 @@
 
     private CameraDevice mCameraDevice;
 
+    private final List<CaptureSession> mCaptureSessions = new ArrayList<>();
+
     @Rule
     public GrantPermissionRule mRuntimePermissionRule = GrantPermissionRule.grant(
             Manifest.permission.CAMERA);
@@ -102,7 +109,16 @@
     }
 
     @After
-    public void tearDown() {
+    public void tearDown() throws ExecutionException, InterruptedException {
+        // Ensure all capture sessions are fully closed
+        List<ListenableFuture<Void>> releaseFutures = new ArrayList<>();
+        for (CaptureSession captureSession : mCaptureSessions) {
+            releaseFutures.add(captureSession.release(/*abortInFlightCaptures=*/false));
+        }
+        mCaptureSessions.clear();
+        Future<?> aggregateReleaseFuture = Futures.allAsList(releaseFutures);
+        aggregateReleaseFuture.get();
+
         if (mCameraDevice != null) {
             mTestParameters0.tearDown();
             mTestParameters1.tearDown();
@@ -112,7 +128,7 @@
 
     @Test
     public void setCaptureSessionSucceed() {
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
+        CaptureSession captureSession = createCaptureSession(mTestParameters0);
 
         captureSession.setSessionConfig(mTestParameters0.mSessionConfig);
 
@@ -121,7 +137,7 @@
 
     @Test(expected = IllegalStateException.class)
     public void setCaptureSessionOnClosedSession_throwsException() {
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
+        CaptureSession captureSession = createCaptureSession(mTestParameters0);
         SessionConfig newSessionConfig = mTestParameters0.mSessionConfig;
 
         captureSession.close();
@@ -132,7 +148,7 @@
 
     @Test
     public void openCaptureSessionSucceed() throws CameraAccessException, InterruptedException {
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
+        CaptureSession captureSession = createCaptureSession(mTestParameters0);
         captureSession.setSessionConfig(mTestParameters0.mSessionConfig);
 
         captureSession.open(mTestParameters0.mSessionConfig, mCameraDevice);
@@ -153,7 +169,7 @@
     @Test
     public void openCaptureSessionWithOptionOverride()
             throws CameraAccessException, InterruptedException {
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
+        CaptureSession captureSession = createCaptureSession(mTestParameters0);
         captureSession.setSessionConfig(mTestParameters0.mSessionConfig);
 
         captureSession.open(mTestParameters0.mSessionConfig, mCameraDevice);
@@ -192,7 +208,7 @@
 
     @Test
     public void closeUnopenedSession() {
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
+        CaptureSession captureSession = createCaptureSession(mTestParameters0);
         captureSession.setSessionConfig(mTestParameters0.mSessionConfig);
 
         captureSession.close();
@@ -201,23 +217,18 @@
     }
 
     @Test
-    public void releaseUnopenedSession() throws ExecutionException, InterruptedException {
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
+    public void releaseUnopenedSession() {
+        CaptureSession captureSession = createCaptureSession(mTestParameters0);
         captureSession.setSessionConfig(mTestParameters0.mSessionConfig);
 
-        ListenableFuture<Void> releaseFuture = captureSession.release(
-                /*abortInFlightCaptures=*/false);
-
-        // Wait for release
-        releaseFuture.get();
+        captureSession.release(/*abortInFlightCaptures=*/false);
 
         assertThat(captureSession.getState()).isEqualTo(State.RELEASED);
     }
 
     @Test
-    public void closeOpenedSession()
-            throws CameraAccessException, InterruptedException, ExecutionException {
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
+    public void closeOpenedSession() throws CameraAccessException {
+        CaptureSession captureSession = createCaptureSession(mTestParameters0);
         captureSession.setSessionConfig(mTestParameters0.mSessionConfig);
         captureSession.open(mTestParameters0.mSessionConfig, mCameraDevice);
 
@@ -226,19 +237,12 @@
         // Session should be in closed state immediately after calling close() on an
         // opening/opened session.
         assertThat(captureSession.getState()).isEqualTo(State.CLOSED);
-
-        // Release the session to clean up for next test
-        ListenableFuture<Void> releaseFuture = captureSession.release(
-                /*abortInFlightCaptures=*/false);
-
-        // Wait for release to finish
-        releaseFuture.get();
     }
 
     @Test
     public void releaseOpenedSession()
             throws CameraAccessException, InterruptedException, ExecutionException {
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
+        CaptureSession captureSession = createCaptureSession(mTestParameters0);
         captureSession.setSessionConfig(mTestParameters0.mSessionConfig);
         captureSession.open(mTestParameters0.mSessionConfig, mCameraDevice);
         ListenableFuture<Void> releaseFuture = captureSession.release(
@@ -255,22 +259,22 @@
 
     @Test
     public void openSecondSession() throws CameraAccessException, InterruptedException {
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
-        captureSession.setSessionConfig(mTestParameters0.mSessionConfig);
+        CaptureSession captureSession0 = createCaptureSession(mTestParameters0);
+        captureSession0.setSessionConfig(mTestParameters0.mSessionConfig);
 
         // First session is opened
-        captureSession.open(mTestParameters0.mSessionConfig, mCameraDevice);
-        captureSession.close();
+        captureSession0.open(mTestParameters0.mSessionConfig, mCameraDevice);
+        captureSession0.close();
 
         // Open second session, which should cause first one to be released
-        CaptureSession captureSession1 = new CaptureSession(mTestParameters1.mHandler);
+        CaptureSession captureSession1 = createCaptureSession(mTestParameters1);
         captureSession1.setSessionConfig(mTestParameters1.mSessionConfig);
         captureSession1.open(mTestParameters1.mSessionConfig, mCameraDevice);
 
         mTestParameters1.waitForData();
 
         assertThat(captureSession1.getState()).isEqualTo(State.OPENED);
-        assertThat(captureSession.getState()).isEqualTo(State.RELEASED);
+        assertThat(captureSession0.getState()).isEqualTo(State.RELEASED);
 
         // First session should have StateCallback.onConfigured(), onClosed() calls.
         verify(mTestParameters0.mSessionStateCallback, times(1))
@@ -289,7 +293,7 @@
 
     @Test
     public void issueCaptureRequest() throws CameraAccessException, InterruptedException {
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
+        CaptureSession captureSession = createCaptureSession(mTestParameters0);
         captureSession.setSessionConfig(mTestParameters0.mSessionConfig);
         captureSession.open(mTestParameters0.mSessionConfig, mCameraDevice);
 
@@ -310,7 +314,7 @@
     @Test
     public void issueCaptureRequestAppendAndOverrideRepeatingOptions()
             throws CameraAccessException, InterruptedException {
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
+        CaptureSession captureSession = createCaptureSession(mTestParameters0);
         captureSession.setSessionConfig(mTestParameters0.mSessionConfig);
         captureSession.open(mTestParameters0.mSessionConfig, mCameraDevice);
 
@@ -348,23 +352,24 @@
         assertThat(captureResult.getRequest().get(CaptureRequest.CONTROL_AE_MODE)).isEqualTo(
                 CaptureRequest.CONTROL_AE_MODE_ON);
     }
+
     @Test
     public void issueCaptureRequestAcrossCaptureSessions()
             throws CameraAccessException, InterruptedException {
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
-        captureSession.setSessionConfig(mTestParameters0.mSessionConfig);
+        CaptureSession captureSession0 = createCaptureSession(mTestParameters0);
+        captureSession0.setSessionConfig(mTestParameters0.mSessionConfig);
 
-        captureSession.issueCaptureRequests(
+        captureSession0.issueCaptureRequests(
                 Collections.singletonList(mTestParameters0.mCaptureConfig));
-        captureSession.open(mTestParameters0.mSessionConfig, mCameraDevice);
+        captureSession0.open(mTestParameters0.mSessionConfig, mCameraDevice);
 
-        captureSession.close();
-        CaptureSession captureSession2 = new CaptureSession(mTestParameters0.mHandler);
-        captureSession2.setSessionConfig(captureSession.getSessionConfig());
-        if (!captureSession.getCaptureConfigs().isEmpty()) {
-            captureSession2.issueCaptureRequests(captureSession.getCaptureConfigs());
+        captureSession0.close();
+        CaptureSession captureSession1 = createCaptureSession(mTestParameters0);
+        captureSession1.setSessionConfig(captureSession0.getSessionConfig());
+        if (!captureSession0.getCaptureConfigs().isEmpty()) {
+            captureSession1.issueCaptureRequests(captureSession0.getCaptureConfigs());
         }
-        captureSession2.open(mTestParameters0.mSessionConfig, mCameraDevice);
+        captureSession1.open(mTestParameters0.mSessionConfig, mCameraDevice);
 
         mTestParameters0.waitForCameraCaptureCallback();
 
@@ -376,7 +381,7 @@
     @Test
     public void issueCaptureRequestBeforeCaptureSessionOpened()
             throws CameraAccessException, InterruptedException {
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
+        CaptureSession captureSession = createCaptureSession(mTestParameters0);
         captureSession.setSessionConfig(mTestParameters0.mSessionConfig);
 
         captureSession.issueCaptureRequests(
@@ -392,7 +397,7 @@
 
     @Test(expected = IllegalStateException.class)
     public void issueCaptureRequestOnClosedSession_throwsException() {
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
+        CaptureSession captureSession = createCaptureSession(mTestParameters0);
 
         captureSession.close();
 
@@ -404,7 +409,7 @@
     @Test
     public void surfaceOnDetachedListenerIsCalledWhenSessionIsClose()
             throws CameraAccessException, InterruptedException, ExecutionException {
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
+        CaptureSession captureSession = createCaptureSession(mTestParameters0);
         captureSession.setSessionConfig(mTestParameters0.mSessionConfig);
 
         captureSession.open(mTestParameters0.mSessionConfig, mCameraDevice);
@@ -432,7 +437,7 @@
 
     @Test
     public void cameraEventCallbackInvokedInOrder() throws CameraAccessException {
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
+        CaptureSession captureSession = createCaptureSession(mTestParameters0);
         captureSession.setSessionConfig(mTestParameters0.mSessionConfig);
 
         captureSession.open(mTestParameters0.mSessionConfig, mCameraDevice);
@@ -457,7 +462,7 @@
         ArgumentCaptor<CameraCaptureResult> captureResultCaptor = ArgumentCaptor.forClass(
                 CameraCaptureResult.class);
 
-        CaptureSession captureSession = new CaptureSession(mTestParameters0.mHandler);
+        CaptureSession captureSession = createCaptureSession(mTestParameters0);
         captureSession.setSessionConfig(mTestParameters0.mSessionConfig);
 
         // Open the capture session and verify the onEnableSession callback would be invoked
@@ -496,6 +501,12 @@
                 never()).onCaptureCompleted(any(CameraCaptureResult.class));
     }
 
+    private CaptureSession createCaptureSession(CaptureSessionTestParameters testParams) {
+        CaptureSession captureSession = new CaptureSession(testParams.mExecutor);
+        mCaptureSessions.add(captureSession);
+        return captureSession;
+    }
+
     /**
      * A implementation to test {@link CameraEventCallback} on CaptureSession.
      */
@@ -531,7 +542,7 @@
         }
     }
 
-    private static CaptureConfig getCaptureConfig(CaptureRequest.Key key, int effectValue,
+    private static <T> CaptureConfig getCaptureConfig(CaptureRequest.Key<T> key, T effectValue,
             CameraCaptureCallback callback) {
         CaptureConfig.Builder captureConfigBuilder = new CaptureConfig.Builder();
         Camera2Config.Builder camera2ConfigurationBuilder =
@@ -552,6 +563,8 @@
         private final HandlerThread mHandlerThread;
         /** Handler for all asynchronous calls. */
         private final Handler mHandler;
+        /** Executor which delegates to Handler */
+        private final Executor mExecutor;
         /** Latch to wait for first image data to appear. */
         private final CountDownLatch mDataLatch = new CountDownLatch(1);
 
@@ -608,6 +621,8 @@
             mHandlerThread.start();
             mHandler = new Handler(mHandlerThread.getLooper());
 
+            mExecutor = CameraXExecutors.newHandlerExecutor(mHandler);
+
             mImageReader =
                     ImageReader.newInstance(640, 480, ImageFormat.YUV_420_888, /*maxImages*/ 2);
             mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mHandler);
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera.java
index 8896381..6189a209 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera.java
@@ -19,7 +19,6 @@
 import android.annotation.SuppressLint;
 import android.graphics.SurfaceTexture;
 import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.CameraCaptureSession;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CameraManager;
@@ -27,6 +26,8 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.util.Log;
+import android.util.Rational;
+import android.util.Size;
 import android.view.Surface;
 
 import androidx.annotation.GuardedBy;
@@ -34,6 +35,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
+import androidx.annotation.WorkerThread;
 import androidx.camera.core.BaseCamera;
 import androidx.camera.core.CameraControlInternal;
 import androidx.camera.core.CameraDeviceStateCallbacks;
@@ -43,17 +45,30 @@
 import androidx.camera.core.CaptureConfig;
 import androidx.camera.core.DeferrableSurface;
 import androidx.camera.core.ImmediateSurface;
+import androidx.camera.core.Observable;
+import androidx.camera.core.Preview;
 import androidx.camera.core.SessionConfig;
 import androidx.camera.core.SessionConfig.ValidatingBuilder;
 import androidx.camera.core.UseCase;
 import androidx.camera.core.UseCaseAttachState;
+import androidx.camera.core.impl.LiveDataObservable;
 import androidx.camera.core.impl.utils.executor.CameraXExecutors;
+import androidx.camera.core.impl.utils.futures.FutureCallback;
+import androidx.camera.core.impl.utils.futures.Futures;
+import androidx.concurrent.futures.CallbackToFutureAdapter;
+import androidx.core.util.Preconditions;
+
+import com.google.common.util.concurrent.ListenableFuture;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.Executor;
 import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * A camera which is controlled by the change of state in use cases.
@@ -68,6 +83,7 @@
  */
 final class Camera implements BaseCamera {
     private static final String TAG = "Camera";
+    private static final int ERROR_NONE = 0;
 
     private final Object mAttachedUseCaseLock = new Object();
 
@@ -83,17 +99,23 @@
 
     private final Object mCameraInfoLock = new Object();
     /** The handler for camera callbacks and use case state management calls. */
-    private final Handler mHandler;
+
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    final Handler mHandler;
+    private final Executor mExecutor;
+
     /**
      * State variable for tracking state of the camera.
      *
-     * <p>Is an atomic reference because it is initialized in the constructor which is not called on
-     * same thread as any of the other methods and callbacks.
+     * <p>Is volatile because it is initialized in the instance initializer which is not necessarily
+     * called on the same thread as any of the other methods and callbacks.
      */
     @SuppressWarnings("WeakerAccess") /* synthetic accessor */
-    final AtomicReference<State> mState = new AtomicReference<>(State.UNINITIALIZED);
+    volatile InternalState mState = InternalState.INITIALIZED;
+    private final LiveDataObservable<BaseCamera.State> mObservableState =
+            new LiveDataObservable<>();
     /** The camera control shared across all use cases bound to this Camera. */
-    private final CameraControlInternal mCameraControlInternal;
+    private final Camera2CameraControl mCameraControlInternal;
     private final StateCallback mStateCallback = new StateCallback();
     /** Information about the characteristics of this camera */
     // Nullable because this is lazily instantiated
@@ -104,35 +126,75 @@
     @Nullable
     @SuppressWarnings("WeakerAccess") /* synthetic accessor */
     CameraDevice mCameraDevice;
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    int mCameraDeviceError = ERROR_NONE;
     /** The configured session which handles issuing capture requests. */
-    private CaptureSession mCaptureSession = new CaptureSession(null);
+    private CaptureSession mCaptureSession;
     /** The session configuration of camera control. */
     private SessionConfig mCameraControlSessionConfig = SessionConfig.defaultEmptySessionConfig();
 
     private final Object mPendingLock = new Object();
     @GuardedBy("mPendingLock")
     private final List<UseCase> mPendingForAddOnline = new ArrayList<>();
-    @GuardedBy("mClosedCaptureSessions")
-    private List<CaptureSession> mClosedCaptureSessions = new ArrayList<>();
 
+    // Used to debug number of requests to release camera
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    final AtomicInteger mReleaseRequestCount = new AtomicInteger(0);
+    // Should only be accessed on handler thread
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    ListenableFuture<Void> mUserReleaseFuture;
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    CallbackToFutureAdapter.Completer<Void> mUserReleaseNotifier;
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    final Map<CaptureSession, ListenableFuture<Void>> mReleasedCaptureSessions = new HashMap<>();
+
+    private final Observable<Integer> mAvailableCamerasObservable;
+    private final Observable.Observer<Integer> mAvailableCamerasObserver;
+    /**
+     * Tracks the number of cameras available for opening.
+     *
+     * <p>If there are no cameras available to open, the camera will wait until there is at least
+     * 1 camera available before opening a CameraDevice.
+     *
+     * <p>This number should be updated by mAvailableCamerasObserver.
+     */
+    @SuppressWarnings("WeakerAccess")
+    int mNumAvailableCameras = 0;
 
     /**
      * Constructor for a camera.
      *
      * @param cameraManager the camera service used to retrieve a camera
      * @param cameraId      the name of the camera as defined by the camera service
+     * @param availableCamerasObservable An observable updated with the current number of cameras
+     *                                   that are available to be opened on the device.
      * @param handler       the handler for the thread on which all camera operations run
      */
-    Camera(CameraManager cameraManager, String cameraId, Handler handler) {
+    Camera(CameraManager cameraManager, String cameraId,
+            @NonNull Observable<Integer> availableCamerasObservable, Handler handler) {
         mCameraManager = cameraManager;
         mCameraId = cameraId;
+        mAvailableCamerasObserver = new AvailableCamerasObserver();
+        mAvailableCamerasObservable = availableCamerasObservable;
         mHandler = handler;
         ScheduledExecutorService executorScheduler = CameraXExecutors.newHandlerExecutor(mHandler);
+        mExecutor = executorScheduler;
         mUseCaseAttachState = new UseCaseAttachState(cameraId);
-        mState.set(State.INITIALIZED);
-        mCameraControlInternal = new Camera2CameraControl(this, executorScheduler,
-                executorScheduler);
-        mCaptureSession = new CaptureSession(mHandler);
+        mObservableState.postValue(State.CLOSED);
+
+        try {
+            CameraCharacteristics cameraCharacteristics =
+                    mCameraManager.getCameraCharacteristics(mCameraId);
+            mCameraControlInternal = new Camera2CameraControl(cameraCharacteristics,
+                    this, executorScheduler, executorScheduler);
+        } catch (CameraAccessException e) {
+            throw new IllegalStateException("Cannot access camera", e);
+        }
+
+        mCaptureSession = new CaptureSession(mExecutor);
+
+        // Register an observer to update the number of available cameras
+        mAvailableCamerasObservable.addObserver(mExecutor, mAvailableCamerasObserver);
     }
 
     /**
@@ -153,15 +215,27 @@
             return;
         }
 
-        switch (mState.get()) {
+        switch (mState) {
             case INITIALIZED:
                 openCameraDevice();
                 break;
             case CLOSING:
-                mState.set(State.REOPENING);
+                setState(InternalState.REOPENING);
+                // If session close has not yet completed, then the camera is still open. We
+                // can move directly back into an OPENED state.
+                // If session close is already complete, then the camera is closing. We'll reopen
+                // the camera in the camera state callback.
+                // If the camera device is currently in an error state, we need to close the
+                // camera before reopening, so we cannot directly reopen.
+                if (!isSessionCloseComplete() && mCameraDeviceError == ERROR_NONE) {
+                    Preconditions.checkState(mCameraDevice != null,
+                            "Camera Device should be open if session close is not complete");
+                    setState(InternalState.OPENED);
+                    openCaptureSession();
+                }
                 break;
             default:
-                Log.d(TAG, "open() ignored due to being in state: " + mState.get());
+                Log.d(TAG, "open() ignored due to being in state: " + mState);
         }
     }
 
@@ -184,107 +258,172 @@
         }
 
         Log.d(TAG, "Closing camera: " + mCameraId);
-        switch (mState.get()) {
+        switch (mState) {
             case OPENED:
-                mState.set(State.CLOSING);
-                closeCameraResource();
+                setState(InternalState.CLOSING);
+                closeCamera(/*abortInFlightCaptures=*/false);
                 break;
             case OPENING:
             case REOPENING:
-                // Though camera and capture session is not opened yet, still need to reset
-                // CaptureSession for clearing pending capture requests.
-                resetCaptureSession();
-                mState.set(State.CLOSING);
+                setState(InternalState.CLOSING);
                 break;
+            case PENDING_OPEN:
+                // We should be able to transition directly to an initialized state since the
+                // camera is not yet opening.
+                Preconditions.checkState(mCameraDevice == null);
+                setState(InternalState.INITIALIZED);
             default:
-                Log.d(TAG, "close() ignored due to being in state: " + mState.get());
+                Log.d(TAG, "close() ignored due to being in state: " + mState);
         }
     }
 
+    @WorkerThread
     private void configAndClose() {
-        switch (mState.get()) {
-            case OPENED:
-                mState.set(State.CLOSING);
+        // Configure the camera with a dummy capture session in order to clear the
+        // previous session. This should be released immediately after being configured.
+        final CaptureSession dummySession = new CaptureSession(mExecutor);
 
-                resetCaptureSession();
+        final SurfaceTexture surfaceTexture = new SurfaceTexture(0);
+        surfaceTexture.setDefaultBufferSize(640, 480);
+        final Surface surface = new Surface(surfaceTexture);
+        final Runnable closeAndCleanupRunner = new Runnable() {
+            @Override
+            public void run() {
+                surface.release();
+                surfaceTexture.release();
+            }
+        };
 
-                final SurfaceTexture surfaceTexture = new SurfaceTexture(0);
-                surfaceTexture.setDefaultBufferSize(640, 480);
-                final Surface surface = new Surface(surfaceTexture);
-                final Runnable surfaceReleaseRunner = new Runnable() {
-                    @Override
-                    public void run() {
-                        surface.release();
-                        surfaceTexture.release();
-                    }
-                };
+        SessionConfig.Builder builder = new SessionConfig.Builder();
+        builder.addNonRepeatingSurface(new ImmediateSurface(surface));
+        builder.setTemplateType(CameraDevice.TEMPLATE_PREVIEW);
+        try {
+            Log.d(TAG, "Start configAndClose.");
+            dummySession.open(builder.build(), mCameraDevice);
 
-                SessionConfig.Builder builder = new SessionConfig.Builder();
-                builder.addNonRepeatingSurface(new ImmediateSurface(surface));
-                builder.setTemplateType(CameraDevice.TEMPLATE_PREVIEW);
-                builder.addSessionStateCallback(new CameraCaptureSession.StateCallback() {
+            // Don't need to abort captures since there are none submitted for this session.
+            ListenableFuture<Void> releaseFuture = releaseSession(
+                    dummySession, /*abortInFlightCaptures=*/false);
 
-                    @Override
-                    public void onConfigured(@NonNull CameraCaptureSession session) {
-                        session.close();
-                    }
+            // Add a listener to clear the dummy surfaces
+            releaseFuture.addListener(closeAndCleanupRunner,
+                    CameraXExecutors.directExecutor());
 
-                    @Override
-                    public void onConfigureFailed(@NonNull CameraCaptureSession session) {
-                        closeCameraResource();
-                        surfaceReleaseRunner.run();
-                    }
+        } catch (CameraAccessException e) {
+            Log.d(TAG, "Unable to configure camera " + mCameraId + " due to "
+                    + e.getMessage());
+            closeAndCleanupRunner.run();
+        }
+    }
 
-                    @Override
-                    public void onClosed(@NonNull CameraCaptureSession session) {
-                        closeCameraResource();
-                        surfaceReleaseRunner.run();
-                    }
-                });
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    boolean isSessionCloseComplete() {
+        return mReleasedCaptureSessions.isEmpty();
+    }
 
-                try {
-                    Log.d(TAG, "Start configAndClose.");
-                    new CaptureSession(null).open(builder.build(), mCameraDevice);
-                } catch (CameraAccessException e) {
-                    Log.d(TAG, "Unable to configure camera " + mCameraId + " due to "
-                            + e.getMessage());
-                    surfaceReleaseRunner.run();
-                }
+    // This will notify futures of completion.
+    // Should only be called once the camera device is actually closed.
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    void finishClose() {
+        Preconditions.checkState(mState == InternalState.RELEASING
+                || mState == InternalState.CLOSING);
+        Preconditions.checkState(mReleasedCaptureSessions.isEmpty());
 
-                break;
-            case OPENING:
-            case REOPENING:
-                mState.set(State.CLOSING);
-                break;
-            default:
-                Log.d(TAG, "configAndClose() ignored due to being in state: " + mState.get());
+        mCameraDevice = null;
+        if (mState == InternalState.CLOSING) {
+            setState(InternalState.INITIALIZED);
+        } else {
+            setState(InternalState.RELEASED);
+
+            // After a camera is released, it cannot be reopened, so we don't need to listen for
+            // available camera changes.
+            mAvailableCamerasObservable.removeObserver(mAvailableCamerasObserver);
+
+            if (mUserReleaseNotifier != null) {
+                mUserReleaseNotifier.set(null);
+                mUserReleaseNotifier = null;
+            }
+        }
+    }
+
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    @WorkerThread
+    void closeCamera(boolean abortInFlightCaptures) {
+        Preconditions.checkState(mState == InternalState.CLOSING
+                        || mState == InternalState.RELEASING
+                        || (mState == InternalState.REOPENING && mCameraDeviceError != ERROR_NONE),
+                "closeCamera should only be called in a CLOSING, RELEASING or REOPENING (with "
+                        + "error) state. Current state: "
+                        + mState + " (error: " + getErrorMessage(mCameraDeviceError) + ")");
+
+        boolean isLegacyDevice = false;
+        try {
+            Camera2CameraInfo camera2CameraInfo = (Camera2CameraInfo) getCameraInfo();
+            isLegacyDevice = camera2CameraInfo.getSupportedHardwareLevel()
+                    == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
+        } catch (CameraInfoUnavailableException e) {
+            Log.w(TAG, "Check legacy device failed.", e);
         }
 
+        // TODO: Check if any sessions have been previously configured. We can probably skip
+        // configAndClose if there haven't been any sessions configured yet.
+        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M
+                && Build.VERSION.SDK_INT < 29
+                && isLegacyDevice
+                && mCameraDeviceError == ERROR_NONE) { // Cannot open session on device in error
+            // To configure surface again before close camera. This step would
+            // disconnect previous connected surface in some legacy device to prevent exception.
+            configAndClose();
+        }
+
+        // Release the current session and replace with a new uninitialized session in case the
+        // camera enters a REOPENING state during session closing.
+        resetCaptureSession(abortInFlightCaptures);
     }
 
-    void closeCameraResource() {
-        mCaptureSession.close();
-        mCaptureSession.release(/*abortInFlightCaptures=*/true);
-        mCameraDevice.close();
-        notifyCameraDeviceCloseToCaptureSessions();
-        mCameraDevice = null;
-        resetCaptureSession();
-    }
+    @WorkerThread
+    private ListenableFuture<Void> releaseSession(@NonNull final CaptureSession captureSession,
+            boolean abortInFlightCaptures) {
+        captureSession.close();
+        ListenableFuture<Void> releaseFuture = captureSession.release(abortInFlightCaptures);
 
-    // Notifies camera device closed event to all CaptureSessions. Not every closed
-    // CaptureSessions's
-    // onClosed will be called when device closed, so we have to notify closed CaptureSession as
-    // well for proper clean up.
-    private void notifyCameraDeviceCloseToCaptureSessions() {
-        synchronized (mClosedCaptureSessions) {
-            for (CaptureSession closedCaptureSession : mClosedCaptureSessions) {
-                closedCaptureSession.notifyCameraDeviceClose();
+        mReleasedCaptureSessions.put(captureSession, releaseFuture);
+
+        // Add a callback to clear the future and notify if the camera and all capture sessions
+        // are released
+        Futures.addCallback(releaseFuture, new FutureCallback<Void>() {
+            @WorkerThread
+            @Override
+            public void onSuccess(@Nullable Void result) {
+                mReleasedCaptureSessions.remove(captureSession);
+                switch (mState) {
+                    case REOPENING:
+                        if (mCameraDeviceError == ERROR_NONE) {
+                            // When reopening, don't close the camera if there is no error.
+                            break;
+                        }
+                        // Fall through if the camera device is in error. It needs to be closed.
+                    case CLOSING:
+                    case RELEASING:
+                        if (isSessionCloseComplete() && mCameraDevice != null) {
+                            mCameraDevice.close();
+                            mCameraDevice = null;
+                        }
+                        break;
+                    default:
+                        // Ignore all other states
+                }
             }
 
-            mClosedCaptureSessions.clear();
-        }
+            @Override
+            public void onFailure(Throwable t) {
+                // Don't reset the internal release future as we want to keep track of the error
+                // TODO: The camera should be put into an error state at this point
+            }
+            // Should always be called on the same handler thread, so directExecutor is OK here.
+        }, CameraXExecutors.directExecutor());
 
-        mCaptureSession.notifyCameraDeviceClose();
+        return releaseFuture;
     }
 
     /**
@@ -293,37 +432,98 @@
      * <p>Once the camera is released it is permanently closed. A new instance must be created to
      * access the camera.
      */
+    @NonNull
     @Override
-    public void release() {
+    public ListenableFuture<Void> release() {
+        ListenableFuture<Void> releaseFuture = CallbackToFutureAdapter.getFuture(
+                new CallbackToFutureAdapter.Resolver<Void>() {
+                    @Override
+                    public Object attachCompleter(
+                            @NonNull final CallbackToFutureAdapter.Completer<Void> completer) {
+
+                        mHandler.post(new Runnable() {
+                            @Override
+                            public void run() {
+                                Futures.propagate(getOrCreateUserReleaseFuture(), completer);
+                            }
+                        });
+                        return "Release[request=" + mReleaseRequestCount.getAndIncrement() + "]";
+                    }
+                });
+
         if (Looper.myLooper() != mHandler.getLooper()) {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    Camera.this.release();
+                    Camera.this.releaseInternal();
                 }
             });
-            return;
+        } else {
+            releaseInternal();
         }
 
-        switch (mState.get()) {
+        return releaseFuture;
+    }
+
+    @NonNull
+    @Override
+    public Observable<BaseCamera.State> getCameraState() {
+        return mObservableState;
+    }
+
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    @WorkerThread
+    void releaseInternal() {
+        switch (mState) {
             case INITIALIZED:
-                mState.set(State.RELEASED);
+            case PENDING_OPEN:
+                Preconditions.checkState(mCameraDevice == null);
+                setState(InternalState.RELEASING);
+                Preconditions.checkState(isSessionCloseComplete());
+                finishClose();
                 break;
             case OPENED:
-                mState.set(State.RELEASING);
-                mCameraDevice.close();
-                notifyCameraDeviceCloseToCaptureSessions();
+                setState(InternalState.RELEASING);
+                closeCamera(/*abortInFlightCaptures=*/true);
                 break;
             case OPENING:
             case CLOSING:
             case REOPENING:
-                mState.set(State.RELEASING);
+            case RELEASING:
+                // Wait for the camera async callback to finish releasing
+                setState(InternalState.RELEASING);
                 break;
             default:
-                Log.d(TAG, "release() ignored due to being in state: " + mState.get());
+                Log.d(TAG, "release() ignored due to being in state: " + mState);
         }
     }
 
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    @WorkerThread
+    ListenableFuture<Void> getOrCreateUserReleaseFuture() {
+        if (mUserReleaseFuture == null) {
+            if (mState != InternalState.RELEASED) {
+                mUserReleaseFuture = CallbackToFutureAdapter.getFuture(
+                        new CallbackToFutureAdapter.Resolver<Void>() {
+                            @Override
+                            public Object attachCompleter(
+                                    @NonNull CallbackToFutureAdapter.Completer<Void> completer) {
+                                Preconditions.checkState(mUserReleaseNotifier == null,
+                                        "Camera can only be released once, so release completer "
+                                                + "should be null on creation.");
+                                mUserReleaseNotifier = completer;
+                                return "Release[camera=" + Camera.this + "]";
+                            }
+                        });
+            } else {
+                // Set to an immediately successful future if already in the released state.
+                mUserReleaseFuture = Futures.immediateFuture(null);
+            }
+        }
+
+        return mUserReleaseFuture;
+    }
+
     /**
      * Sets the use case in a state to issue capture requests.
      *
@@ -411,6 +611,7 @@
             mUseCaseAttachState.updateUseCase(useCase);
         }
 
+        resetCaptureSession(/*abortInFlightCaptures=*/false);
         updateCaptureSessionConfig();
         openCaptureSession();
     }
@@ -418,7 +619,7 @@
     // Re-attaches use case's surfaces if surfaces are changed when use case is online.
     @GuardedBy("mAttachedUseCaseLock")
     private void reattachUseCaseSurfaces(UseCase useCase) {
-        // if use case is offline, then DeferrableSurface attaching will happens when the use
+        // if use case is offline, then DeferrableSurface attaching will happen when the use
         // case is addOnlineUsecase()'d.   So here we don't need to do the attaching.
         if (!isUseCaseOnline(useCase)) {
             return;
@@ -469,7 +670,7 @@
      * capture requests from the use case.
      */
     @Override
-    public void addOnlineUseCase(final Collection<UseCase> useCases) {
+    public void addOnlineUseCase(@NonNull final Collection<UseCase> useCases) {
         if (useCases.isEmpty()) {
             return;
         }
@@ -512,9 +713,37 @@
             mPendingForAddOnline.removeAll(useCases);
         }
 
-        open();
         updateCaptureSessionConfig();
-        openCaptureSession();
+        resetCaptureSession(/*abortInFlightCaptures=*/false);
+
+        if (mState == InternalState.OPENED) {
+            openCaptureSession();
+        } else {
+            open();
+        }
+
+        updateCameraControlPreviewAspectRatio(useCases);
+    }
+
+
+    private void updateCameraControlPreviewAspectRatio(Collection<UseCase> useCases) {
+        for (UseCase useCase : useCases) {
+            if (useCase instanceof Preview) {
+                Size resolutoin = useCase.getAttachedSurfaceResolution(mCameraId);
+                Rational aspectRatio = new Rational(resolutoin.getWidth(), resolutoin.getHeight());
+                mCameraControlInternal.setPreviewAspectRatio(aspectRatio);
+                return;
+            }
+        }
+    }
+
+    private void clearCameraControlPreviewAspectRatio(Collection<UseCase> useCases) {
+        for (UseCase useCase : useCases) {
+            if (useCase instanceof Preview) {
+                mCameraControlInternal.setPreviewAspectRatio(null);
+                return;
+            }
+        }
     }
 
     /**
@@ -522,7 +751,7 @@
      * handle capture requests from the use case.
      */
     @Override
-    public void removeOnlineUseCase(final Collection<UseCase> useCases) {
+    public void removeOnlineUseCase(@NonNull final Collection<UseCase> useCases) {
         if (useCases.isEmpty()) {
             return;
         }
@@ -552,35 +781,24 @@
             }
 
             if (mUseCaseAttachState.getOnlineUseCases().isEmpty()) {
-
-                boolean isLegacyDevice = false;
-                try {
-                    Camera2CameraInfo camera2CameraInfo = (Camera2CameraInfo) getCameraInfo();
-                    isLegacyDevice = camera2CameraInfo.getSupportedHardwareLevel()
-                            == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
-                } catch (CameraInfoUnavailableException e) {
-                    Log.w(TAG, "Check legacy device failed.", e);
-                }
-
-                if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M && Build.VERSION.SDK_INT < 29
-                        && isLegacyDevice) {
-                    // To configure surface again before close camera. This step would
-                    // disconnect
-                    // previous connected surface in some legacy device to prevent exception.
-                    configAndClose();
-                } else {
-                    close();
-                }
+                resetCaptureSession(/*abortInFlightCaptures=*/true);
+                close();
                 return;
             }
         }
 
-        openCaptureSession();
         updateCaptureSessionConfig();
+        resetCaptureSession(/*abortInFlightCaptures=*/false);
 
+        if (mState == InternalState.OPENED) {
+            openCaptureSession();
+        }
+
+        clearCameraControlPreviewAspectRatio(useCases);
     }
 
     /** Returns an interface to retrieve characteristics of the camera. */
+    @NonNull
     @Override
     public CameraInfo getCameraInfo() throws CameraInfoUnavailableException {
         synchronized (mCameraInfoLock) {
@@ -598,7 +816,16 @@
     @SuppressLint("MissingPermission")
     @SuppressWarnings("WeakerAccess") /* synthetic accessor */
     void openCameraDevice() {
-        mState.set(State.OPENING);
+        // Check that we have an available camera to open here before attempting
+        // to open the camera again.
+        if (mNumAvailableCameras <= 0) {
+            Log.d(TAG, "No cameras available. Waiting for available camera before opening camera: "
+                    + mCameraId);
+            setState(InternalState.PENDING_OPEN);
+            return;
+        } else {
+            setState(InternalState.OPENING);
+        }
 
         Log.d(TAG, "Opening camera: " + mCameraId);
 
@@ -606,7 +833,7 @@
             mCameraManager.openCamera(mCameraId, createDeviceStateCallback(), mHandler);
         } catch (CameraAccessException e) {
             Log.e(TAG, "Unable to open camera " + mCameraId + " due to " + e.getMessage());
-            mState.set(State.INITIALIZED);
+            setState(InternalState.INITIALIZED);
         }
     }
 
@@ -634,10 +861,7 @@
      */
     @SuppressWarnings("WeakerAccess") /* synthetic accessor */
     void openCaptureSession() {
-        if (mState.get() != State.OPENED) {
-            Log.d(TAG, "openCaptureSession() ignored due to being in state: " + mState.get());
-            return;
-        }
+        Preconditions.checkState(mState == InternalState.OPENED);
 
         ValidatingBuilder validatingBuilder;
         synchronized (mAttachedUseCaseLock) {
@@ -648,65 +872,33 @@
             return;
         }
 
-        if (mCameraDevice == null) {
-            Log.d(TAG, "CameraDevice is null");
-            return;
-        }
-
-        // When the previous capture session has not reached the open state, the issued single
-        // capture requests will still be in request queue and will need to be passed to the next
-        // capture session.
-        List<CaptureConfig> unissuedCaptureConfigs = mCaptureSession.getCaptureConfigs();
-        resetCaptureSession();
-
-        SessionConfig sessionConfig = validatingBuilder.build();
-
-        if (!unissuedCaptureConfigs.isEmpty()) {
-            List<CaptureConfig> reissuedCaptureConfigs = new ArrayList<>();
-            // Filters out requests that has unconfigured surface (probably caused by removeOnline)
-            for (CaptureConfig unissuedCaptureConfig : unissuedCaptureConfigs) {
-                if (sessionConfig.getSurfaces().containsAll(unissuedCaptureConfig.getSurfaces())) {
-                    reissuedCaptureConfigs.add(unissuedCaptureConfig);
-                }
-            }
-
-            if (!reissuedCaptureConfigs.isEmpty()) {
-                Log.d(TAG, "reissuedCaptureConfigs");
-                mCaptureSession.issueCaptureRequests(reissuedCaptureConfigs);
-            }
-        }
-
         try {
-            mCaptureSession.open(sessionConfig, mCameraDevice);
+            mCaptureSession.open(validatingBuilder.build(), mCameraDevice);
         } catch (CameraAccessException e) {
             Log.d(TAG, "Unable to configure camera " + mCameraId + " due to " + e.getMessage());
         }
     }
 
     /**
-     * Closes the currently opened capture session, so it can be safely disposed. Replaces the old
-     * session with a new session initialized with the old session's configuration.
+     * Replaces the old session with a new session initialized with the old session's configuration.
+     *
+     * <p>This does not close the previous session. The previous session should be
+     * explicitly released before calling this method so the camera can track the state of
+     * closing that session.
      */
-    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
-    void resetCaptureSession() {
-        Log.d(TAG, "Closing Capture Session: " + mCameraId);
-
+    @WorkerThread
+    private void resetCaptureSession(boolean abortInFlightCaptures) {
+        Preconditions.checkState(mCaptureSession != null);
+        Log.d(TAG, "Resetting Capture Session");
+        CaptureSession oldCaptureSession = mCaptureSession;
         // Recreate an initialized (but not opened) capture session from the previous configuration
-        SessionConfig previousSessionConfig = mCaptureSession.getSessionConfig();
-
-        mCaptureSession.close();
-        mCaptureSession.release(/*abortInFlightCaptures=*/false);
-
-        // Saves the closed CaptureSessions if device is not closed yet.
-        // We need to notify camera device closed event to these CaptureSessions.
-        if (mCameraDevice != null) {
-            synchronized (mClosedCaptureSessions) {
-                mClosedCaptureSessions.add(mCaptureSession);
-            }
-        }
-
-        mCaptureSession = new CaptureSession(mHandler);
+        SessionConfig previousSessionConfig = oldCaptureSession.getSessionConfig();
+        List<CaptureConfig> unissuedCaptureConfigs = oldCaptureSession.getCaptureConfigs();
+        mCaptureSession = new CaptureSession(mExecutor);
         mCaptureSession.setSessionConfig(previousSessionConfig);
+        mCaptureSession.issueCaptureRequests(unissuedCaptureConfigs);
+
+        releaseSession(oldCaptureSession, /*abortInFlightCaptures=*/abortInFlightCaptures);
     }
 
     private CameraDevice.StateCallback createDeviceStateCallback() {
@@ -761,6 +953,7 @@
     }
 
     /** Returns the Camera2CameraControl attached to Camera */
+    @NonNull
     @Override
     public CameraControlInternal getCameraControlInternal() {
         return mCameraControlInternal;
@@ -819,9 +1012,13 @@
         submitCaptureRequests(captureConfigs);
     }
 
-    enum State {
-        /** The default state of the camera before construction. */
-        UNINITIALIZED,
+    @NonNull
+    @Override
+    public String toString() {
+        return String.format(Locale.US, "Camera@%x[id=%s]", hashCode(), mCameraId);
+    }
+
+    enum InternalState {
         /**
          * Stable state once the camera has been constructed.
          *
@@ -834,6 +1031,15 @@
          */
         INITIALIZED,
         /**
+         * Camera is waiting for the camera to be available to open.
+         *
+         * <p>A camera may enter a pending state if the camera has been stolen by another process
+         * or if the maximum number of available cameras is already open.
+         *
+         * <p>At the end of this state, the camera should move into the OPENING state.
+         */
+        PENDING_OPEN,
+        /**
          * A transitional state where the camera device is currently opening.
          *
          * <p>At the end of this state, the camera should move into either the OPENED or CLOSING
@@ -878,132 +1084,219 @@
         RELEASED
     }
 
+    @WorkerThread
+    void setState(InternalState state) {
+        mState = state;
+        // Convert the internal state to the publicly visible state
+        switch (state) {
+            case INITIALIZED:
+                mObservableState.postValue(State.CLOSED);
+                break;
+            case PENDING_OPEN:
+                mObservableState.postValue(State.PENDING_OPEN);
+                break;
+            case OPENING:
+            case REOPENING:
+                mObservableState.postValue(State.OPENING);
+                break;
+            case OPENED:
+                mObservableState.postValue(State.OPEN);
+                break;
+            case CLOSING:
+                mObservableState.postValue(State.CLOSING);
+                break;
+            case RELEASING:
+                mObservableState.postValue(State.RELEASING);
+                break;
+            case RELEASED:
+                mObservableState.postValue(State.RELEASED);
+                break;
+        }
+    }
+
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    String getErrorMessage(int errorCode) {
+        switch (errorCode) {
+            case ERROR_NONE:
+                return "ERROR_NONE";
+            case CameraDevice.StateCallback.ERROR_CAMERA_DEVICE:
+                return "ERROR_CAMERA_DEVICE";
+            case CameraDevice.StateCallback.ERROR_CAMERA_DISABLED:
+                return "ERROR_CAMERA_DISABLED";
+            case CameraDevice.StateCallback.ERROR_CAMERA_IN_USE:
+                return "ERROR_CAMERA_IN_USE";
+            case CameraDevice.StateCallback.ERROR_CAMERA_SERVICE:
+                return "ERROR_CAMERA_SERVICE";
+            case CameraDevice.StateCallback.ERROR_MAX_CAMERAS_IN_USE:
+                return "ERROR_MAX_CAMERAS_IN_USE";
+            default: // fall out
+        }
+        return "UNKNOWN ERROR";
+    }
+
     final class StateCallback extends CameraDevice.StateCallback {
 
         @Override
         public void onOpened(CameraDevice cameraDevice) {
             Log.d(TAG, "CameraDevice.onOpened(): " + cameraDevice.getId());
-            switch (mState.get()) {
+            mCameraDevice = cameraDevice;
+            mCameraDeviceError = ERROR_NONE;
+            switch (mState) {
                 case CLOSING:
                 case RELEASING:
-                    cameraDevice.close();
-                    Camera.this.mCameraDevice = null;
+                    // No session should have yet been opened, so close camera directly here.
+                    Preconditions.checkState(isSessionCloseComplete());
+                    mCameraDevice.close();
+                    mCameraDevice = null;
                     break;
                 case OPENING:
                 case REOPENING:
-                    mState.set(State.OPENED);
-                    Camera.this.mCameraDevice = cameraDevice;
+                    setState(InternalState.OPENED);
                     openCaptureSession();
                     break;
                 default:
                     throw new IllegalStateException(
-                            "onOpened() should not be possible from state: " + mState.get());
+                            "onOpened() should not be possible from state: " + mState);
             }
         }
 
         @Override
         public void onClosed(CameraDevice cameraDevice) {
             Log.d(TAG, "CameraDevice.onClosed(): " + cameraDevice.getId());
-
-            resetCaptureSession();
-            switch (mState.get()) {
+            Preconditions.checkState(mCameraDevice == null,
+                    "Unexpected onClose callback on camera device: " + cameraDevice);
+            switch (mState) {
                 case CLOSING:
-                    mState.set(State.INITIALIZED);
-                    Camera.this.mCameraDevice = null;
+                case RELEASING:
+                    Preconditions.checkState(isSessionCloseComplete());
+                    finishClose();
                     break;
                 case REOPENING:
-                    mState.set(State.OPENING);
                     openCameraDevice();
                     break;
-                case RELEASING:
-                    mState.set(State.RELEASED);
-                    Camera.this.mCameraDevice = null;
-                    break;
                 default:
                     CameraX.postError(
                             CameraX.ErrorCode.CAMERA_STATE_INCONSISTENT,
-                            "Camera closed while in state: " + mState.get());
+                            "Camera closed while in state: " + mState);
             }
-
-
         }
 
         @Override
         public void onDisconnected(CameraDevice cameraDevice) {
             Log.d(TAG, "CameraDevice.onDisconnected(): " + cameraDevice.getId());
-            resetCaptureSession();
-            switch (mState.get()) {
+
+            // onDisconnected could be called before onOpened if the camera becomes disconnected
+            // during initialization, so keep track of it here.
+            mCameraDevice = cameraDevice;
+
+            switch (mState) {
                 case CLOSING:
-                    mState.set(State.INITIALIZED);
-                    Camera.this.mCameraDevice = null;
-                    break;
                 case REOPENING:
                 case OPENED:
                 case OPENING:
-                    mState.set(State.CLOSING);
-                    cameraDevice.close();
-                    Camera.this.mCameraDevice = null;
+                    // TODO: Create a "DISCONNECTED" state so camera can recover once available.
+                    setState(InternalState.RELEASING);
                     break;
                 case RELEASING:
-                    mState.set(State.RELEASED);
-                    cameraDevice.close();
-                    Camera.this.mCameraDevice = null;
+                    // State will be set to RELEASED once camera finishes closing.
                     break;
                 default:
                     throw new IllegalStateException(
-                            "onDisconnected() should not be possible from state: " + mState.get());
+                            "onDisconnected() should not be possible from state: " + mState);
             }
-        }
-
-        private String getErrorMessage(int errorCode) {
-            switch (errorCode) {
-                case CameraDevice.StateCallback.ERROR_CAMERA_DEVICE:
-                    return "ERROR_CAMERA_DEVICE";
-                case CameraDevice.StateCallback.ERROR_CAMERA_DISABLED:
-                    return "ERROR_CAMERA_DISABLED";
-                case CameraDevice.StateCallback.ERROR_CAMERA_IN_USE:
-                    return "ERROR_CAMERA_IN_USE";
-                case CameraDevice.StateCallback.ERROR_CAMERA_SERVICE:
-                    return "ERROR_CAMERA_SERVICE";
-                case CameraDevice.StateCallback.ERROR_MAX_CAMERAS_IN_USE:
-                    return "ERROR_MAX_CAMERAS_IN_USE";
-                default: // fall out
-            }
-            return "UNKNOWN ERROR";
+            // Not to close the in flight captures since the capture session has already been
+            // closed.
+            closeCamera(/*abortInFlightCaptures=*/false);
         }
 
         @Override
-        public void onError(CameraDevice cameraDevice, int error) {
-            Log.e(
-                    TAG,
-                    "CameraDevice.onError(): "
-                            + cameraDevice.getId()
-                            + " with error: "
-                            + getErrorMessage(error));
-            resetCaptureSession();
-            switch (mState.get()) {
-                case INITIALIZED:
-                    break;
-                case CLOSING:
-                    mState.set(State.INITIALIZED);
-                    Camera.this.mCameraDevice = null;
-                    break;
-                case REOPENING:
-                case OPENED:
-                case OPENING:
-                    mState.set(State.CLOSING);
-                    cameraDevice.close();
-                    Camera.this.mCameraDevice = null;
-                    break;
+        public void onError(@NonNull CameraDevice cameraDevice, int error) {
+            // onError could be called before onOpened if there is an error opening the camera
+            // during initialization, so keep track of it here.
+            mCameraDevice = cameraDevice;
+            mCameraDeviceError = error;
+
+            switch (mState) {
                 case RELEASING:
-                    mState.set(State.RELEASED);
-                    cameraDevice.close();
-                    Camera.this.mCameraDevice = null;
+                case CLOSING:
+                    Log.e(
+                            TAG,
+                            "CameraDevice.onError(): "
+                                    + cameraDevice.getId()
+                                    + " with error: "
+                                    + getErrorMessage(error));
+                    closeCamera(/*abortInFlightCaptures=*/false);
+                    break;
+                case OPENING:
+                case OPENED:
+                case REOPENING:
+                    handleErrorOnOpen(cameraDevice, error);
                     break;
                 default:
                     throw new IllegalStateException(
-                            "onError() should not be possible from state: " + mState.get());
+                            "onError() should not be possible from state: " + mState);
             }
         }
+
+        private void handleErrorOnOpen(@NonNull CameraDevice cameraDevice, int error) {
+            Preconditions.checkState(
+                    mState == InternalState.OPENING || mState == InternalState.OPENED
+                            || mState == InternalState.REOPENING,
+                    "Attempt to handle open error from non open state: " + mState);
+            switch (error) {
+                case CameraDevice.StateCallback.ERROR_CAMERA_DEVICE:
+                    // A fatal error occurred. The device should be reopened.
+                    // Fall through.
+                case CameraDevice.StateCallback.ERROR_MAX_CAMERAS_IN_USE:
+                    // Attempt to reopen the camera again. If there are no cameras available,
+                    // this will wait for the next available camera.
+                    reopenCameraAfterError();
+                    break;
+                default:
+                    // TODO: Properly handle other errors. For now, we will close the camera.
+                    Log.e(
+                            TAG,
+                            "Error observed on open (or opening) camera device "
+                                    + cameraDevice.getId()
+                                    + ": "
+                                    + getErrorMessage(error));
+                    setState(InternalState.CLOSING);
+                    closeCamera(/*abortInFlightCaptures=*/false);
+                    break;
+            }
+        }
+
+
+        private void reopenCameraAfterError() {
+            // After an error, we must close the current camera device before we can open a new
+            // one. To accomplish this, we will close the current camera and wait for the
+            // onClosed() callback to reopen the device. It is also possible that the device can
+            // be closed immediately, so in that case we will open the device manually.
+            Preconditions.checkState(mCameraDeviceError != ERROR_NONE,
+                    "Can only reopen camera device after error if the camera device is actually "
+                            + "in an error state.");
+            setState(InternalState.REOPENING);
+            closeCamera(/*abortInFlightCaptures=*/false);
+        }
+    }
+
+    final class AvailableCamerasObserver implements Observable.Observer<Integer> {
+
+        @Override
+        public void onNewData(@Nullable Integer value) {
+            Preconditions.checkNotNull(value);
+            if (value != mNumAvailableCameras) {
+                mNumAvailableCameras = value;
+
+                if (mState == InternalState.PENDING_OPEN) {
+                    openCameraDevice();
+                }
+            }
+        }
+
+        @Override
+        public void onError(@NonNull Throwable t) {
+            // No errors expected from available cameras yet. May need to be handled in the future.
+        }
     }
 }
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraControl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraControl.java
index da2118e..de8004e 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraControl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraControl.java
@@ -16,17 +16,14 @@
 
 package androidx.camera.camera2.impl;
 
-import android.annotation.SuppressLint;
 import android.graphics.Rect;
 import android.hardware.camera2.CameraCaptureSession;
 import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
+import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
 import android.hardware.camera2.TotalCaptureResult;
-import android.hardware.camera2.params.MeteringRectangle;
-import android.os.Build;
-import android.util.Log;
+import android.util.Rational;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -38,7 +35,7 @@
 import androidx.camera.core.CaptureConfig;
 import androidx.camera.core.Config;
 import androidx.camera.core.FlashMode;
-import androidx.camera.core.OnFocusListener;
+import androidx.camera.core.FocusMeteringAction;
 import androidx.camera.core.SessionConfig;
 import androidx.camera.core.impl.utils.executor.CameraXExecutors;
 
@@ -49,8 +46,6 @@
 import java.util.Set;
 import java.util.concurrent.Executor;
 import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
 
 /**
  * A Camera2 implementation for CameraControlInternal interface
@@ -59,50 +54,32 @@
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class Camera2CameraControl implements CameraControlInternal {
-    private static final long DEFAULT_FOCUS_TIMEOUT_MS = 5000;
     private static final String TAG = "Camera2CameraControl";
     @SuppressWarnings("WeakerAccess") /* synthetic accessor */
     final CameraControlSessionCallback mSessionCallback;
     @SuppressWarnings("WeakerAccess") /* synthetic accessor */
     final Executor mExecutor;
+    private final CameraCharacteristics mCameraCharacteristics;
     private final ControlUpdateListener mControlUpdateListener;
     private final ScheduledExecutorService mScheduler;
     private final SessionConfig.Builder mSessionConfigBuilder = new SessionConfig.Builder();
-
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    volatile Rational mPreviewAspectRatio = null;
+    @VisibleForTesting
+    final FocusMeteringControl mFocusMeteringControl;
     // use volatile modifier to make these variables in sync in all threads.
     private volatile boolean mIsTorchOn = false;
-    private volatile boolean mIsFocusLocked = false;
     private volatile FlashMode mFlashMode = FlashMode.OFF;
 
     //******************** Should only be accessed by executor *****************************//
-    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
-    CaptureResultListener mSessionListenerForFocus = null;
     private Rect mCropRect = null;
-    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
-    MeteringRectangle mAfRect;
-    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
-    MeteringRectangle mAeRect;
-    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
-    MeteringRectangle mAwbRect;
-    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
-    Integer mCurrentAfState = CaptureResult.CONTROL_AF_STATE_INACTIVE;
-    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
-    long mFocusTimeoutCounter = 0;
-    private long mFocusTimeoutMs;
-    private ScheduledFuture<?> mFocusTimeoutHandle;
     //**************************************************************************************//
 
 
-    public Camera2CameraControl(@NonNull ControlUpdateListener controlUpdateListener,
-            @NonNull ScheduledExecutorService scheduler, @NonNull Executor executor) {
-        this(controlUpdateListener, DEFAULT_FOCUS_TIMEOUT_MS, scheduler, executor);
-    }
-
-    public Camera2CameraControl(
+    public Camera2CameraControl(@NonNull CameraCharacteristics cameraCharacteristics,
             @NonNull ControlUpdateListener controlUpdateListener,
-            long focusTimeoutMs,
-            @NonNull ScheduledExecutorService scheduler,
-            @NonNull Executor executor) {
+            @NonNull ScheduledExecutorService scheduler, @NonNull Executor executor) {
+        mCameraCharacteristics = cameraCharacteristics;
         mControlUpdateListener = controlUpdateListener;
         if (CameraXExecutors.isSequentialExecutor(executor)) {
             mExecutor = executor;
@@ -110,14 +87,13 @@
             mExecutor = CameraXExecutors.newSequentialExecutor(executor);
         }
         mScheduler = scheduler;
-        mFocusTimeoutMs = focusTimeoutMs;
-
         mSessionCallback = new CameraControlSessionCallback(mExecutor);
-
         mSessionConfigBuilder.setTemplateType(getDefaultTemplate());
         mSessionConfigBuilder.addRepeatingCameraCaptureCallback(
                 CaptureCallbackContainer.create(mSessionCallback));
 
+        mFocusMeteringControl = new FocusMeteringControl(this, mExecutor, mScheduler);
+
         // Initialize the session config
         mExecutor.execute(new Runnable() {
             @Override
@@ -127,6 +103,30 @@
         });
     }
 
+    public void setPreviewAspectRatio(@Nullable Rational previewAspectRatio) {
+        mPreviewAspectRatio = previewAspectRatio;
+    }
+
+    @Override
+    public void startFocusAndMetering(@NonNull FocusMeteringAction action) {
+        mExecutor.execute(new Runnable() {
+            @Override
+            public void run() {
+                mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio);
+            }
+        });
+    }
+
+    @Override
+    public void cancelFocusAndMetering() {
+        mExecutor.execute(new Runnable() {
+            @Override
+            public void run() {
+                mFocusMeteringControl.cancelFocusAndMetering();
+            }
+        });
+    }
+
     /** {@inheritDoc} */
     @Override
     public void setCropRegion(@Nullable final Rect crop) {
@@ -138,44 +138,6 @@
         });
     }
 
-    /** {@inheritDoc} */
-    @SuppressLint("LambdaLast") // Remove after https://issuetracker.google.com/135275901
-    @Override
-    public void focus(
-            @NonNull final Rect focus,
-            @NonNull final Rect metering,
-            @NonNull final Executor userListenerExecutor,
-            @NonNull final OnFocusListener listener) {
-        mExecutor.execute(new Runnable() {
-            @Override
-            public void run() {
-                focusInternal(focus, metering, userListenerExecutor, listener);
-            }
-        });
-    }
-
-    @Override
-    public void focus(@NonNull Rect focus, @NonNull Rect metering) {
-        mExecutor.execute(new Runnable() {
-            @Override
-            public void run() {
-                // Listener executor won't be called, so its ok use pass direct executor here.
-                focusInternal(focus, metering, CameraXExecutors.directExecutor(), null);
-            }
-        });
-    }
-
-    /** Cancels the focus operation. */
-    @VisibleForTesting
-    void cancelFocus() {
-        mExecutor.execute(new Runnable() {
-            @Override
-            public void run() {
-                cancelFocusInternal();
-            }
-        });
-    }
-
     @NonNull
     @Override
     public FlashMode getFlashMode() {
@@ -217,11 +179,6 @@
         return mIsTorchOn;
     }
 
-    @Override
-    public boolean isFocusLocked() {
-        return mIsFocusLocked;
-    }
-
     /**
      * Issues a {@link CaptureRequest#CONTROL_AF_TRIGGER_START} request to start auto focus scan.
      */
@@ -230,7 +187,7 @@
         mExecutor.execute(new Runnable() {
             @Override
             public void run() {
-                triggerAfInternal();
+                mFocusMeteringControl.triggerAf();
             }
         });
     }
@@ -244,7 +201,7 @@
         mExecutor.execute(new Runnable() {
             @Override
             public void run() {
-                triggerAePrecaptureInternal();
+                mFocusMeteringControl.triggerAePrecapture();
             }
         });
     }
@@ -260,7 +217,8 @@
         mExecutor.execute(new Runnable() {
             @Override
             public void run() {
-                cancelAfAeTriggerInternal(cancelAfTrigger, cancelAePrecaptureTrigger);
+                mFocusMeteringControl.cancelAfAeTrigger(cancelAfTrigger,
+                        cancelAePrecaptureTrigger);
             }
         });
     }
@@ -311,143 +269,30 @@
         updateSessionConfig();
     }
 
-    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
     @WorkerThread
-    void focusInternal(
-            final Rect focus,
-            final Rect metering,
-            @NonNull final Executor listenerExecutor,
-            @Nullable final OnFocusListener listener) {
-        mSessionCallback.removeListener(mSessionListenerForFocus);
-
-        cancelFocusTimeout();
-
-        mAfRect = new MeteringRectangle(focus, MeteringRectangle.METERING_WEIGHT_MAX);
-        mAeRect = new MeteringRectangle(metering, MeteringRectangle.METERING_WEIGHT_MAX);
-        mAwbRect = new MeteringRectangle(metering, MeteringRectangle.METERING_WEIGHT_MAX);
-        Log.d(TAG, "Setting new AF rectangle: " + mAfRect);
-        Log.d(TAG, "Setting new AE rectangle: " + mAeRect);
-        Log.d(TAG, "Setting new AWB rectangle: " + mAwbRect);
-
-        mCurrentAfState = CaptureResult.CONTROL_AF_STATE_INACTIVE;
-        mIsFocusLocked = true;
-
-        if (listener != null) {
-
-            mSessionListenerForFocus =
-                    new CaptureResultListener() {
-                        // Will be called on mExecutor since mSessionCallback was created with
-                        // mExecutor
-                        @WorkerThread
-                        @Override
-                        public boolean onCaptureResult(TotalCaptureResult result) {
-                            Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
-                            if (afState == null) {
-                                return false;
-                            }
-
-                            if (mCurrentAfState == CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN) {
-                                if (afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED) {
-                                    listenerExecutor.execute(
-                                            new Runnable() {
-                                                @Override
-                                                public void run() {
-                                                    listener.onFocusLocked(mAfRect.getRect());
-                                                }
-                                            });
-                                    return true; // finished
-                                } else if (afState
-                                        == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
-                                    listenerExecutor.execute(
-                                            new Runnable() {
-                                                @Override
-                                                public void run() {
-                                                    listener.onFocusUnableToLock(
-                                                            mAfRect.getRect());
-                                                }
-                                            });
-                                    return true; // finished
-                                }
-                            }
-                            if (!mCurrentAfState.equals(afState)) {
-                                mCurrentAfState = afState;
-                            }
-                            return false; // continue checking
-                        }
-                    };
-
-            mSessionCallback.addListener(mSessionListenerForFocus);
+    @NonNull
+    Rect getCropSensorRegion() {
+        Rect cropRect = mCropRect;
+        if (cropRect == null) {
+            cropRect = getSensorRect();
         }
-        updateSessionConfig();
-
-        triggerAfInternal();
-        if (mFocusTimeoutMs > 0) {
-            final long timeoutId = ++mFocusTimeoutCounter;
-            final Runnable timeoutRunnable = new Runnable() {
-                @Override
-                public void run() {
-                    mExecutor.execute(new Runnable() {
-                        @WorkerThread
-                        @Override
-                        public void run() {
-                            if (timeoutId == mFocusTimeoutCounter) {
-                                cancelFocusInternal();
-
-                                mSessionCallback.removeListener(mSessionListenerForFocus);
-
-                                if (listener != null
-                                        && mCurrentAfState
-                                        == CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN) {
-                                    listenerExecutor.execute(
-                                            new Runnable() {
-                                                @Override
-                                                public void run() {
-                                                    listener.onFocusTimedOut(mAfRect.getRect());
-                                                }
-                                            });
-                                }
-                            }
-                        }
-                    });
-                }
-            };
-
-            mFocusTimeoutHandle = mScheduler.schedule(timeoutRunnable, mFocusTimeoutMs,
-                    TimeUnit.MILLISECONDS);
-        }
+        return cropRect;
     }
 
     @WorkerThread
-    private void cancelFocusTimeout() {
-        if (mFocusTimeoutHandle != null) {
-            mFocusTimeoutHandle.cancel(/*mayInterruptIfRunning=*/true);
-            mFocusTimeoutHandle = null;
-        }
+    @NonNull
+    Rect getSensorRect() {
+        return mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
     }
 
-    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
     @WorkerThread
-    void cancelFocusInternal() {
-        cancelFocusTimeout();
+    void removeCaptureResultListener(@NonNull CaptureResultListener listener) {
+        mSessionCallback.removeListener(listener);
+    }
 
-        MeteringRectangle zeroRegion =
-                new MeteringRectangle(new Rect(), MeteringRectangle.METERING_WEIGHT_DONT_CARE);
-        mAfRect = zeroRegion;
-        mAeRect = zeroRegion;
-        mAwbRect = zeroRegion;
-
-        // Send a single request to cancel af process
-        CaptureConfig.Builder singleRequestBuilder = createCaptureBuilderWithSharedOptions();
-        singleRequestBuilder.setTemplateType(getDefaultTemplate());
-        singleRequestBuilder.setUseRepeatingSurface(true);
-        Camera2Config.Builder configBuilder = new Camera2Config.Builder();
-        configBuilder.setCaptureRequestOption(CaptureRequest.CONTROL_AF_TRIGGER,
-                CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
-        singleRequestBuilder.addImplementationOptions(configBuilder.build());
-        notifyCaptureRequests(Collections.singletonList(singleRequestBuilder.build()));
-
-        mIsFocusLocked = false;
-        updateSessionConfig();
+    @WorkerThread
+    void addCaptureResultListener(@NonNull CaptureResultListener listener) {
+        mSessionCallback.addListener(listener);
     }
 
     @SuppressWarnings("WeakerAccess") /* synthetic accessor */
@@ -460,7 +305,7 @@
             singleRequestBuilder.setUseRepeatingSurface(true);
             Camera2Config.Builder configBuilder = new Camera2Config.Builder();
             configBuilder.setCaptureRequestOption(CaptureRequest.CONTROL_AE_MODE,
-                    CaptureRequest.CONTROL_AE_MODE_ON);
+                    getSupportedAeMode(CaptureRequest.CONTROL_AE_MODE_ON));
             configBuilder.setCaptureRequestOption(CaptureRequest.FLASH_MODE,
                     CaptureRequest.FLASH_MODE_OFF);
             singleRequestBuilder.addImplementationOptions(configBuilder.build());
@@ -469,52 +314,6 @@
         updateSessionConfig();
     }
 
-    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
-    @WorkerThread
-    void triggerAfInternal() {
-        CaptureConfig.Builder builder = createCaptureBuilderWithSharedOptions();
-        builder.setTemplateType(getDefaultTemplate());
-        builder.setUseRepeatingSurface(true);
-        Camera2Config.Builder configBuilder = new Camera2Config.Builder();
-        configBuilder.setCaptureRequestOption(CaptureRequest.CONTROL_AF_TRIGGER,
-                CaptureRequest.CONTROL_AF_TRIGGER_START);
-        builder.addImplementationOptions(configBuilder.build());
-        notifyCaptureRequests(Collections.singletonList(builder.build()));
-    }
-
-    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
-    @WorkerThread
-    void triggerAePrecaptureInternal() {
-        CaptureConfig.Builder builder = createCaptureBuilderWithSharedOptions();
-        builder.setTemplateType(getDefaultTemplate());
-        builder.setUseRepeatingSurface(true);
-        Camera2Config.Builder configBuilder = new Camera2Config.Builder();
-        configBuilder.setCaptureRequestOption(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
-                CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
-        builder.addImplementationOptions(configBuilder.build());
-        notifyCaptureRequests(Collections.singletonList(builder.build()));
-    }
-
-    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
-    @WorkerThread
-    void cancelAfAeTriggerInternal(final boolean cancelAfTrigger,
-            final boolean cancelAePrecaptureTrigger) {
-        CaptureConfig.Builder builder = createCaptureBuilderWithSharedOptions();
-        builder.setUseRepeatingSurface(true);
-        builder.setTemplateType(getDefaultTemplate());
-
-        Camera2Config.Builder configBuilder = new Camera2Config.Builder();
-        if (cancelAfTrigger) {
-            configBuilder.setCaptureRequestOption(CaptureRequest.CONTROL_AF_TRIGGER,
-                    CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
-        }
-        if (Build.VERSION.SDK_INT >= 23 && cancelAePrecaptureTrigger) {
-            configBuilder.setCaptureRequestOption(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
-                    CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL);
-        }
-        builder.addImplementationOptions(configBuilder.build());
-        notifyCaptureRequests(Collections.singletonList(builder.build()));
-    }
 
     @SuppressWarnings("WeakerAccess") /* synthetic accessor */
     @WorkerThread
@@ -542,11 +341,8 @@
         builder.setCaptureRequestOption(
                 CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
 
-        builder.setCaptureRequestOption(
-                CaptureRequest.CONTROL_AF_MODE,
-                isFocusLocked()
-                        ? CaptureRequest.CONTROL_AF_MODE_AUTO
-                        : CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+        // AF Mode is assigned in mFocusMeteringControl.
+        mFocusMeteringControl.addFocusMeteringOptions(builder);
 
         int aeMode = CaptureRequest.CONTROL_AE_MODE_ON;
         if (mIsTorchOn) {
@@ -565,23 +361,11 @@
                     break;
             }
         }
-        builder.setCaptureRequestOption(CaptureRequest.CONTROL_AE_MODE, aeMode);
+        builder.setCaptureRequestOption(CaptureRequest.CONTROL_AE_MODE, getSupportedAeMode(aeMode));
 
         builder.setCaptureRequestOption(
-                CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_AUTO);
-
-        if (mAfRect != null) {
-            builder.setCaptureRequestOption(
-                    CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{mAfRect});
-        }
-        if (mAeRect != null) {
-            builder.setCaptureRequestOption(
-                    CaptureRequest.CONTROL_AE_REGIONS, new MeteringRectangle[]{mAeRect});
-        }
-        if (mAwbRect != null) {
-            builder.setCaptureRequestOption(
-                    CaptureRequest.CONTROL_AWB_REGIONS, new MeteringRectangle[]{mAwbRect});
-        }
+                CaptureRequest.CONTROL_AWB_MODE,
+                getSupportedAwbMode(CaptureRequest.CONTROL_AWB_MODE_AUTO));
 
         if (mCropRect != null) {
             builder.setCaptureRequestOption(CaptureRequest.SCALER_CROP_REGION, mCropRect);
@@ -590,15 +374,117 @@
         return builder.build();
     }
 
+    /**
+     * Returns a supported AF mode which will be preferredMode if it is supported.
+     *
+     * <p><pre>If preferredMode is not supported, fallback with the following priority (highest to
+     * lowest).
+     * 1) {@link CaptureRequest#CONTROL_AF_MODE_CONTINUOUS_PICTURE}
+     * 2) {@link CaptureRequest#CONTROL_AF_MODE_AUTO)}
+     * 3) {@link CaptureRequest#CONTROL_AF_MODE_OFF}
+     * </pre>
+     */
+    @WorkerThread
+    int getSupportedAfMode(int preferredMode) {
+        int[] modes = mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);
+        if (modes == null) {
+            return CaptureRequest.CONTROL_AF_MODE_OFF;
+        }
+
+        // if preferredMode is supported, use it
+        if (isModeInList(preferredMode, modes)) {
+            return preferredMode;
+        }
+
+        // if not found, priority is CONTINUOUS_PICTURE > AUTO > OFF
+        if (isModeInList(CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE, modes)) {
+            return CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE;
+        } else if (isModeInList(CaptureRequest.CONTROL_AF_MODE_AUTO, modes)) {
+            return CaptureRequest.CONTROL_AF_MODE_AUTO;
+        }
+
+        return CaptureRequest.CONTROL_AF_MODE_OFF;
+    }
+
+    /**
+     * Returns a supported AE mode which will be preferredMode if it is supported.
+     *
+     * <p><pre>If preferredMode is not supported, fallback with the following priority (highest to
+     * lowest).
+     * 1) {@link CaptureRequest#CONTROL_AE_MODE_ON}
+     * 2) {@link CaptureRequest#CONTROL_AE_MODE_OFF)}
+     * </pre>
+     */
+    @WorkerThread
+    private int getSupportedAeMode(int preferredMode) {
+        int[] modes = mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES);
+
+        if (modes == null) {
+            return CaptureRequest.CONTROL_AE_MODE_OFF;
+        }
+
+        // if preferredMode is supported, use it
+        if (isModeInList(preferredMode, modes)) {
+            return preferredMode;
+        }
+
+        // if not found, priority is AE_ON > AE_OFF
+        if (isModeInList(CaptureRequest.CONTROL_AE_MODE_ON, modes)) {
+            return CaptureRequest.CONTROL_AE_MODE_ON;
+        }
+
+        return CaptureRequest.CONTROL_AE_MODE_OFF;
+    }
+
+    /**
+     * Returns a supported AWB mode which will be preferredMode if it is supported.
+     *
+     * <p><pre>If preferredMode is not supported, fallback with the following priority (highest to
+     * lowest).
+     * 1) {@link CaptureRequest#CONTROL_AWB_MODE_AUTO}
+     * 2) {@link CaptureRequest#CONTROL_AWB_MODE_OFF)}
+     * </pre>
+     */
+    @WorkerThread
+    private int getSupportedAwbMode(int preferredMode) {
+        int[] modes = mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES);
+
+        if (modes == null) {
+            return CaptureRequest.CONTROL_AWB_MODE_OFF;
+        }
+
+        // if preferredMode is supported, use it
+        if (isModeInList(preferredMode, modes)) {
+            return preferredMode;
+        }
+
+        // if not found, priority is AWB_AUTO > AWB_OFF
+        if (isModeInList(CaptureRequest.CONTROL_AWB_MODE_AUTO, modes)) {
+            return CaptureRequest.CONTROL_AWB_MODE_AUTO;
+        }
+
+        return CaptureRequest.CONTROL_AWB_MODE_OFF;
+    }
+
+    @WorkerThread
+    private boolean isModeInList(int mode, int[] modeList) {
+        for (int m : modeList) {
+            if (mode == m) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /** An interface to listen to camera capture results. */
-    private interface CaptureResultListener {
+    interface CaptureResultListener {
         /**
          * Callback to handle camera capture results.
          *
          * @param captureResult camera capture result.
          * @return true to finish listening, false to continue listening.
          */
-        boolean onCaptureResult(TotalCaptureResult captureResult);
+        boolean onCaptureResult(@NonNull TotalCaptureResult captureResult);
     }
 
     static final class CameraControlSessionCallback extends CaptureCallback {
@@ -611,12 +497,12 @@
         }
 
         @WorkerThread
-        void addListener(CaptureResultListener listener) {
+        void addListener(@NonNull CaptureResultListener listener) {
             mResultListeners.add(listener);
         }
 
         @WorkerThread
-        void removeListener(CaptureResultListener listener) {
+        void removeListener(@NonNull CaptureResultListener listener) {
             mResultListeners.remove(listener);
         }
 
@@ -642,8 +528,6 @@
                     }
                 }
             });
-
-
         }
     }
 }
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraFactory.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraFactory.java
index d61e61a..3aa3eb6 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraFactory.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraFactory.java
@@ -32,6 +32,7 @@
 import androidx.camera.core.CameraX.LensFacing;
 import androidx.camera.core.CameraXThreads;
 import androidx.camera.core.LensFacingCameraIdFilter;
+import androidx.camera.core.impl.utils.executor.CameraXExecutors;
 
 import java.util.Arrays;
 import java.util.LinkedHashSet;
@@ -47,8 +48,11 @@
 public final class Camera2CameraFactory implements CameraFactory {
     private static final String TAG = "Camera2CameraFactory";
 
+    private static final int DEFAULT_ALLOWED_CONCURRENT_OPEN_CAMERAS = 1;
+
     private static final HandlerThread sHandlerThread = new HandlerThread(CameraXThreads.TAG);
     private static final Handler sHandler;
+    private final CameraAvailabilityRegistry mAvailabilityRegistry;
 
     static {
         sHandlerThread.start();
@@ -57,16 +61,24 @@
 
     private final CameraManager mCameraManager;
 
-    public Camera2CameraFactory(Context context) {
+    public Camera2CameraFactory(@NonNull Context context) {
         mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
+        mAvailabilityRegistry = new CameraAvailabilityRegistry(
+                DEFAULT_ALLOWED_CONCURRENT_OPEN_CAMERAS,
+                CameraXExecutors.newHandlerExecutor(sHandler));
     }
 
     @Override
-    public BaseCamera getCamera(String cameraId) {
-        return new Camera(mCameraManager, cameraId, sHandler);
+    @NonNull
+    public BaseCamera getCamera(@NonNull String cameraId) {
+        Camera camera = new Camera(mCameraManager, cameraId,
+                mAvailabilityRegistry.getAvailableCameraCount(), sHandler);
+        mAvailabilityRegistry.registerCamera(camera);
+        return camera;
     }
 
     @Override
+    @NonNull
     public Set<String> getAvailableCameraIds() throws CameraInfoUnavailableException {
         List<String> camerasList = null;
         try {
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraInfo.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraInfo.java
index 6722377..d5251f2 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraInfo.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraInfo.java
@@ -70,9 +70,7 @@
 
     @Override
     public int getSensorRotationDegrees(@RotationValue int relativeRotation) {
-        Integer sensorOrientation =
-                mCameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
-        Preconditions.checkNotNull(sensorOrientation);
+        Integer sensorOrientation = getSensorOrientation();
         int relativeRotationDegrees =
                 CameraOrientationUtil.surfaceRotationToDegrees(relativeRotation);
         // Currently this assumes that a back-facing camera is always opposite to the screen.
@@ -85,6 +83,13 @@
                 isOppositeFacingScreen);
     }
 
+    int getSensorOrientation() {
+        Integer sensorOrientation =
+                mCameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
+        Preconditions.checkNotNull(sensorOrientation);
+        return sensorOrientation;
+    }
+
     int getSupportedHardwareLevel() {
         Integer deviceLevel =
                 mCameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/CameraAvailabilityRegistry.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/CameraAvailabilityRegistry.java
new file mode 100644
index 0000000..d7a0ba6
--- /dev/null
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/CameraAvailabilityRegistry.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2019 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.camera.camera2.impl;
+
+import android.util.Log;
+
+import androidx.annotation.GuardedBy;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.WorkerThread;
+import androidx.camera.core.BaseCamera;
+import androidx.camera.core.Observable;
+import androidx.camera.core.impl.LiveDataObservable;
+import androidx.core.util.Preconditions;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * A registry that tracks the state of cameras and publishes the number of cameras available to
+ * open.
+ */
+final class CameraAvailabilityRegistry {
+    private static final boolean DEBUG = false;
+    private StringBuilder mDebugString = DEBUG ? new StringBuilder() : null;
+    private static final String TAG = "AvailabilityRegistry";
+
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    final int mMaxAllowedOpenedCameras;
+    private final Executor mExecutor;
+    private final LiveDataObservable<Integer> mAvailableCameras;
+
+    private final Object mLock = new Object();
+    @GuardedBy("mLock")
+    private final Map<BaseCamera, BaseCamera.State> mCameraStates = new HashMap<>();
+
+
+    /**
+     * Creates a new registry with a limit of {@code maxAllowedOpenCameras} allowed to be opened.
+     *
+     * @param maxAllowedOpenedCameras The limit of number of simultaneous open cameras.
+     * @param executor                An executor used for state callbacks on
+     */
+    CameraAvailabilityRegistry(int maxAllowedOpenedCameras, @NonNull Executor executor) {
+        mMaxAllowedOpenedCameras = maxAllowedOpenedCameras;
+        mExecutor = Preconditions.checkNotNull(executor);
+        mAvailableCameras = new LiveDataObservable<>();
+        mAvailableCameras.postValue(maxAllowedOpenedCameras);
+    }
+
+    /**
+     * Registers a camera with the registry.
+     *
+     * <p>Once registered, the state will be tracked until the camera is released. Once released,
+     * the camera will be automatically unregistered.
+     *
+     * @param camera The camera to register.
+     */
+    void registerCamera(@NonNull final BaseCamera camera) {
+        synchronized (mLock) {
+            if (!mCameraStates.containsKey(camera)) {
+                mCameraStates.put(camera, null);
+
+                camera.getCameraState().addObserver(mExecutor,
+                        new Observable.Observer<BaseCamera.State>() {
+                            @Override
+                            public void onNewData(@Nullable BaseCamera.State state) {
+                                if (state == BaseCamera.State.RELEASED) {
+                                    unregisterCamera(camera, this);
+                                } else {
+                                    updateState(camera, state);
+                                }
+                            }
+
+                            @Override
+                            public void onError(@NonNull Throwable t) {
+                                // Ignore errors on state for now. Handle these in the future if
+                                // needed.
+                            }
+                        });
+            }
+        }
+    }
+
+    /**
+     * Returns an observable stream of the current available camera count.
+     *
+     * <p>This count is a best effort count of cameras available to be opened on this device.
+     * This should only be used as a hint for when cameras can be opened. Due to the asynchronous
+     * nature of notifications and when the camera device is opened, users should still expect
+     * that attempting to open cameras may fail and should handle errors appropriately.
+     */
+    Observable<Integer> getAvailableCameraCount() {
+        return mAvailableCameras;
+    }
+
+    @WorkerThread
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    void unregisterCamera(BaseCamera camera, Observable.Observer<BaseCamera.State> observer) {
+        int availableCameras;
+        synchronized (mLock) {
+            camera.getCameraState().removeObserver(observer);
+            if (mCameraStates.remove(camera) == null) {
+                return;
+            }
+
+            availableCameras = recalculateAvailableCameras();
+        }
+
+        mAvailableCameras.postValue(availableCameras);
+    }
+
+    @WorkerThread
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    void updateState(BaseCamera camera, BaseCamera.State state) {
+        int availableCameras;
+        synchronized (mLock) {
+            // If mCameraStates does not contain the camera, it may have been unregistered.
+            // Or, if the state has not been updated, ignore this update.
+            if (!mCameraStates.containsKey(camera) || mCameraStates.put(camera, state) == state) {
+                return;
+            }
+
+            availableCameras = recalculateAvailableCameras();
+        }
+
+        mAvailableCameras.postValue(availableCameras);
+    }
+
+    @WorkerThread
+    @GuardedBy("mLock")
+    private int recalculateAvailableCameras() {
+        if (DEBUG) {
+            mDebugString.setLength(0);
+            mDebugString.append("Recalculating open cameras:\n");
+            mDebugString.append(String.format(Locale.US, "%-45s%-22s\n", "Camera", "State"));
+            mDebugString.append(
+                    "-------------------------------------------------------------------\n");
+        }
+        // Count the number of cameras that are not in a closed state state. Closed states are
+        // considered to be CLOSED, PENDING_OPEN or OPENING, since we can't guarantee a camera
+        // has actually be open in these states. All cameras that are in a CLOSING or RELEASING
+        // state may have previously been open, so we will count them as open.
+        int openCount = 0;
+        for (Map.Entry<BaseCamera, BaseCamera.State> entry : mCameraStates.entrySet()) {
+            if (DEBUG) {
+                String stateString =
+                        entry.getValue() != null ? entry.getValue().toString() : "UNKNOWN";
+                mDebugString.append(String.format(Locale.US, "%-45s%-22s\n",
+                        entry.getKey().toString(),
+                        stateString));
+            }
+            if (entry.getValue() != BaseCamera.State.CLOSED
+                    && entry.getValue() != BaseCamera.State.OPENING
+                    && entry.getValue() != BaseCamera.State.PENDING_OPEN) {
+                openCount++;
+            }
+        }
+        if (DEBUG) {
+            mDebugString.append(
+                    "-------------------------------------------------------------------\n");
+            mDebugString.append(String.format(Locale.US, "Open count: %d (Max allowed: %d)",
+                    openCount,
+                    mMaxAllowedOpenedCameras));
+            Log.d(TAG, mDebugString.toString());
+        }
+
+        // Calculate available cameras value (clamped to 0 or more)
+        return Math.max(mMaxAllowedOpenedCameras - openCount, 0);
+    }
+}
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/CaptureSession.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/CaptureSession.java
index 2f69596..9e3403f 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/CaptureSession.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/CaptureSession.java
@@ -22,10 +22,6 @@
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.TotalCaptureResult;
-import android.hardware.camera2.params.OutputConfiguration;
-import android.hardware.camera2.params.SessionConfiguration;
-import android.os.Build;
-import android.os.Handler;
 import android.util.Log;
 import android.view.Surface;
 
@@ -33,6 +29,10 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.camera.camera2.Camera2Config;
+import androidx.camera.camera2.impl.compat.CameraCaptureSessionCompat;
+import androidx.camera.camera2.impl.compat.CameraDeviceCompat;
+import androidx.camera.camera2.impl.compat.params.OutputConfigurationCompat;
+import androidx.camera.camera2.impl.compat.params.SessionConfigurationCompat;
 import androidx.camera.core.CameraCaptureCallback;
 import androidx.camera.core.CameraCaptureSessionStateCallbacks;
 import androidx.camera.core.CaptureConfig;
@@ -66,25 +66,20 @@
  */
 final class CaptureSession {
     private static final String TAG = "CaptureSession";
-
-    /** Handler for all the callbacks from the {@link CameraCaptureSession}. */
-    @Nullable
-    private final Handler mHandler;
-    /** An adapter to pass the task to the handler. */
-    @Nullable
+    /** Lock on whether the camera is open or closed. */
+    final Object mStateLock = new Object();
+    /** Executor for all the callbacks from the {@link CameraCaptureSession}. */
     private final Executor mExecutor;
     /** The configuration for the currently issued single capture requests. */
     private final List<CaptureConfig> mCaptureConfigs = new ArrayList<>();
-    /** Lock on whether the camera is open or closed. */
-    final Object mStateLock = new Object();
     /** Callback for handling image captures. */
     private final CameraCaptureSession.CaptureCallback mCaptureCallback =
             new CaptureCallback() {
                 @Override
                 public void onCaptureCompleted(
-                        CameraCaptureSession session,
-                        CaptureRequest request,
-                        TotalCaptureResult result) {
+                        @NonNull CameraCaptureSession session,
+                        @NonNull CaptureRequest request,
+                        @NonNull TotalCaptureResult result) {
                 }
             };
     private final StateCallback mCaptureSessionStateCallback = new StateCallback();
@@ -121,15 +116,17 @@
     /**
      * Constructor for CaptureSession.
      *
-     * @param handler The handler is responsible for queuing up callbacks from capture requests. If
-     *                this is null then when asynchronous methods are called on this session they
-     *                will attempt
-     *                to use the current thread's looper.
+     * @param executor The executor is responsible for queuing up callbacks from capture requests.
      */
-    CaptureSession(@Nullable Handler handler) {
-        mHandler = handler;
+    CaptureSession(@NonNull Executor executor) {
         mState = State.INITIALIZED;
-        mExecutor = (handler != null) ? CameraXExecutors.newHandlerExecutor(handler) : null;
+
+        // Ensure tasks posted to the executor are executed sequentially.
+        if (CameraXExecutors.isSequentialExecutor(executor)) {
+            mExecutor = executor;
+        } else {
+            mExecutor = CameraXExecutors.newSequentialExecutor(executor);
+        }
     }
 
     /**
@@ -246,45 +243,39 @@
                     List<CaptureConfig> presetList =
                             eventCallbacks.createComboCallback().onPresetSession();
 
-                    if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P
-                            && !presetList.isEmpty()) {
+                    // Generate the CaptureRequest builder from repeating request since Android
+                    // recommend use the same template type as the initial capture request. The
+                    // tag and output targets would be ignored by default.
+                    CaptureConfig.Builder captureConfigBuilder = CaptureConfig.Builder.from(
+                            sessionConfig.getRepeatingCaptureConfig());
 
-                        // Generate the CaptureRequest builder from repeating request since Android
-                        // recommend use the same template type as the initial capture request. The
-                        // tag and output targets would be ignored by default.
-                        CaptureConfig.Builder captureConfigBuilder = CaptureConfig.Builder.from(
-                                sessionConfig.getRepeatingCaptureConfig());
-
-                        for (CaptureConfig config : presetList) {
-                            captureConfigBuilder.addImplementationOptions(
-                                    config.getImplementationOptions());
-                        }
-
-                        CaptureRequest captureRequest =
-                                Camera2CaptureRequestBuilder.buildWithoutTarget(
-                                        captureConfigBuilder.build(),
-                                        cameraDevice);
-
-                        if (captureRequest != null) {
-                            List<OutputConfiguration> outputConfigList = new LinkedList<>();
-                            for (Surface surface : uniqueConfiguredSurface) {
-                                outputConfigList.add(new OutputConfiguration(surface));
-                            }
-
-                            SessionConfiguration sessionParameterConfiguration =
-                                    new SessionConfiguration(SessionConfiguration.SESSION_REGULAR,
-                                            outputConfigList, getExecutor(), comboCallback);
-                            sessionParameterConfiguration.setSessionParameters(captureRequest);
-                            cameraDevice.createCaptureSession(sessionParameterConfiguration);
-                        } else {
-                            cameraDevice.createCaptureSession(uniqueConfiguredSurface,
-                                    comboCallback,
-                                    mHandler);
-                        }
-                    } else {
-                        cameraDevice.createCaptureSession(uniqueConfiguredSurface, comboCallback,
-                                mHandler);
+                    for (CaptureConfig config : presetList) {
+                        captureConfigBuilder.addImplementationOptions(
+                                config.getImplementationOptions());
                     }
+
+                    List<OutputConfigurationCompat> outputConfigList = new LinkedList<>();
+                    for (Surface surface : uniqueConfiguredSurface) {
+                        outputConfigList.add(new OutputConfigurationCompat(surface));
+                    }
+
+                    SessionConfigurationCompat sessionConfigCompat =
+                            new SessionConfigurationCompat(
+                                    SessionConfigurationCompat.SESSION_REGULAR,
+                                    outputConfigList,
+                                    getExecutor(),
+                                    comboCallback);
+
+                    CaptureRequest captureRequest =
+                            Camera2CaptureRequestBuilder.buildWithoutTarget(
+                                    captureConfigBuilder.build(),
+                                    cameraDevice);
+
+                    if (captureRequest != null) {
+                        sessionConfigCompat.setSessionParameters(captureRequest);
+                    }
+
+                    CameraDeviceCompat.createCaptureSession(cameraDevice, sessionConfigCompat);
                     break;
                 default:
                     Log.e(TAG, "Open not allowed in state: " + mState);
@@ -319,7 +310,14 @@
                         List<CaptureConfig> configList =
                                 eventCallbacks.createComboCallback().onDisableSession();
                         if (!configList.isEmpty()) {
-                            issueCaptureRequests(setupConfiguredSurface(configList));
+                            try {
+                                issueCaptureRequests(setupConfiguredSurface(configList));
+                            } catch (IllegalStateException e) {
+                                // We couldn't issue the request before close the capture session,
+                                // but we should continue the close flow.
+                                Log.e(TAG, "Unable to issue the request before close the capture "
+                                        + "session", e);
+                            }
                         }
                     }
                     // Not break close flow.
@@ -506,8 +504,8 @@
                             captureConfig.getCameraCaptureCallbacks(),
                             mCaptureCallback);
 
-            mCameraCaptureSession.setRepeatingRequest(
-                    captureRequest, comboCaptureCallback, mHandler);
+            CameraCaptureSessionCompat.setSingleRepeatingRequest(mCameraCaptureSession,
+                    captureRequest, mExecutor, comboCaptureCallback);
         } catch (CameraAccessException e) {
             Log.e(TAG, "Unable to access camera: " + e.getMessage());
             Thread.dumpStack();
@@ -529,6 +527,23 @@
                     continue;
                 }
 
+                // Validate all surfaces belong to configured surfaces map
+                boolean surfacesValid = true;
+                for (DeferrableSurface surface : captureConfig.getSurfaces()) {
+                    if (!mConfiguredSurfaceMap.containsKey(surface)) {
+                        Log.d(TAG, "Skipping capture request with invalid surface: " + surface);
+                        surfacesValid = false;
+                        break;
+                    }
+                }
+
+                if (!surfacesValid) {
+                    // An invalid surface was detected in this request.
+                    // Skip it and go on to the next request.
+                    // TODO (b/133710422): Report this request as an error.
+                    continue;
+                }
+
                 CaptureConfig.Builder captureConfigBuilder = CaptureConfig.Builder.from(
                         captureConfig);
 
@@ -563,11 +578,14 @@
                 }
                 callbackAggregator.addCamera2Callbacks(captureRequest, cameraCallbacks);
                 captureRequests.add(captureRequest);
-
             }
-            mCameraCaptureSession.captureBurst(captureRequests,
-                    callbackAggregator,
-                    mHandler);
+
+            if (!captureRequests.isEmpty()) {
+                CameraCaptureSessionCompat.captureBurstRequests(mCameraCaptureSession,
+                        captureRequests, mExecutor, callbackAggregator);
+            } else {
+                Log.d(TAG, "Skipping issuing burst request due to no valid request elements");
+            }
         } catch (CameraAccessException e) {
             Log.e(TAG, "Unable to access camera: " + e.getMessage());
             Thread.dumpStack();
@@ -588,6 +606,7 @@
         return Camera2CaptureCallbacks.createComboCallback(camera2Callbacks);
     }
 
+
     /**
      * Merges the implementation options from the input {@link CaptureConfig} list.
      *
@@ -671,7 +690,7 @@
          * will be immediately issued.
          */
         @Override
-        public void onConfigured(CameraCaptureSession session) {
+        public void onConfigured(@NonNull CameraCaptureSession session) {
             synchronized (mStateLock) {
                 switch (mState) {
                     case UNINITIALIZED:
@@ -713,7 +732,7 @@
         }
 
         @Override
-        public void onReady(CameraCaptureSession session) {
+        public void onReady(@NonNull CameraCaptureSession session) {
             synchronized (mStateLock) {
                 switch (mState) {
                     case UNINITIALIZED:
@@ -726,7 +745,7 @@
         }
 
         @Override
-        public void onClosed(CameraCaptureSession session) {
+        public void onClosed(@NonNull CameraCaptureSession session) {
             synchronized (mStateLock) {
                 if (mState == State.UNINITIALIZED) {
                     throw new IllegalStateException(
@@ -748,7 +767,7 @@
         }
 
         @Override
-        public void onConfigureFailed(CameraCaptureSession session) {
+        public void onConfigureFailed(@NonNull CameraCaptureSession session) {
             synchronized (mStateLock) {
                 switch (mState) {
                     case UNINITIALIZED:
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/FocusMeteringControl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/FocusMeteringControl.java
new file mode 100644
index 0000000..4df3d87
--- /dev/null
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/FocusMeteringControl.java
@@ -0,0 +1,415 @@
+/*
+ * Copyright 2019 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.camera.camera2.impl;
+
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.MeteringRectangle;
+import android.os.Build;
+import android.util.Rational;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.WorkerThread;
+import androidx.camera.camera2.Camera2Config;
+import androidx.camera.core.CaptureConfig;
+import androidx.camera.core.FocusMeteringAction;
+import androidx.camera.core.MeteringPoint;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Implementation of focus and metering.
+ *
+ * <p>It is intended to be used within {@link Camera2CameraControl} to implement the
+ * functionality of {@link Camera2CameraControl#startFocusAndMetering(FocusMeteringAction)} and
+ * {@link Camera2CameraControl#cancelFocusAndMetering()}. This class depends on
+ * {@link Camera2CameraControl} to provide some low-level methods such as updateSessionConfig,
+ * triggerAfInternal and cancelAfAeTriggerInternal to achieve the focus and metering functions.
+ *
+ * <p>To wait for the auto-focus lock, it calls
+ * {@link Camera2CameraControl#addCaptureResultListener(Camera2CameraControl.CaptureResultListener)}
+ * to monitor the capture result. It also requires {@link ScheduledExecutorService} to schedule the
+ * auto-cancel event and {@link Executor} to ensure all the methods within this class are called
+ * in the same thread as the Camera2CameraControl.
+ *
+ * <p>The {@link Camera2CameraControl} calls {@link FocusMeteringControl#addFocusMeteringOptions} to
+ * construct the 3A regions and append them to all repeating requests and single requests.
+ */
+class FocusMeteringControl {
+    private static final String TAG = "FocusMeteringControl";
+
+    private final Camera2CameraControl mCameraControl;
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    final Executor mExecutor;
+    private final ScheduledExecutorService mScheduler;
+
+    //******************** Should only be accessed by executor (WorkThread) ****************//
+    private FocusMeteringAction mCurrentFocusMeteringAction;
+    private boolean mIsInAfAutoMode = false;
+    Integer mCurrentAfState = CaptureResult.CONTROL_AF_STATE_INACTIVE;
+    private ScheduledFuture<?> mAutoCancelHandle;
+    long mFocusTimeoutCounter = 0;
+    Camera2CameraControl.CaptureResultListener mSessionListenerForFocus = null;
+    private MeteringRectangle[] mAfRects = new MeteringRectangle[]{};
+    private MeteringRectangle[] mAeRects = new MeteringRectangle[]{};
+    private MeteringRectangle[] mAwbRects = new MeteringRectangle[]{};
+    //**************************************************************************************//
+
+    FocusMeteringControl(@NonNull Camera2CameraControl cameraControl,
+            Executor executor, ScheduledExecutorService scheduler) {
+        mCameraControl = cameraControl;
+        mExecutor = executor;
+        mScheduler = scheduler;
+    }
+
+    /**
+     * Called by {@link Camera2CameraControl} to append the 3A regions to the shared options. It
+     * applies to all repeating requests and single requests.
+     */
+    @WorkerThread
+    void addFocusMeteringOptions(@NonNull Camera2Config.Builder configBuilder) {
+        int afMode = mIsInAfAutoMode
+                ? CaptureRequest.CONTROL_AF_MODE_AUTO
+                : CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE;
+
+        configBuilder.setCaptureRequestOption(
+                CaptureRequest.CONTROL_AF_MODE, mCameraControl.getSupportedAfMode(afMode));
+
+
+        if (mAfRects.length != 0) {
+            configBuilder.setCaptureRequestOption(
+                    CaptureRequest.CONTROL_AF_REGIONS, mAfRects);
+        }
+        if (mAeRects.length != 0) {
+            configBuilder.setCaptureRequestOption(
+                    CaptureRequest.CONTROL_AE_REGIONS, mAeRects);
+        }
+        if (mAwbRects.length != 0) {
+            configBuilder.setCaptureRequestOption(
+                    CaptureRequest.CONTROL_AWB_REGIONS, mAwbRects);
+        }
+    }
+
+    @WorkerThread
+    private PointF getFOVAdjustedPoint(@NonNull MeteringPoint meteringPoint,
+            @NonNull Rational cropRegionAspectRatio,
+            @NonNull Rational defaultAspectRatio) {
+        // Use default aspect ratio unless there is a custom aspect ratio in MeteringPoint.
+        Rational fovAspectRatio = defaultAspectRatio;
+        if (meteringPoint.getFOVAspectRatio() != null) {
+            fovAspectRatio = meteringPoint.getFOVAspectRatio();
+        }
+
+        PointF adjustedPoint = new PointF(meteringPoint.getNormalizedCropRegionX(),
+                meteringPoint.getNormalizedCropRegionY());
+        if (!fovAspectRatio.equals(cropRegionAspectRatio)) {
+
+            if (fovAspectRatio.compareTo(cropRegionAspectRatio) > 0) {
+                // FOV is more narrow than crop region, top and down side of FOV is cropped.
+                float heightOfCropRegion =
+                        (float) (fovAspectRatio.doubleValue()
+                                / cropRegionAspectRatio.doubleValue());
+                float top_padding = (float) ((heightOfCropRegion - 1.0) / 2);
+                adjustedPoint.y = (top_padding + adjustedPoint.y) * (1 / heightOfCropRegion);
+
+            } else {
+                // FOV is wider than crop region, left and right side of FOV is cropped.
+                float widthOfCropRegion =
+                        (float) (cropRegionAspectRatio.doubleValue()
+                                / fovAspectRatio.doubleValue());
+                float left_padding = (float) ((widthOfCropRegion - 1.0) / 2);
+                adjustedPoint.x = (left_padding + adjustedPoint.x) * (1f / widthOfCropRegion);
+            }
+        }
+
+        return adjustedPoint;
+    }
+
+    @WorkerThread
+    private MeteringRectangle getMeteringRect(MeteringPoint meteringPoint, PointF adjustedPoint,
+            Rect cropRegion) {
+        int centerX = (int) (cropRegion.left + adjustedPoint.x * cropRegion.width());
+        int centerY = (int) (cropRegion.top + adjustedPoint.y * cropRegion.height());
+
+        int width = (int) (meteringPoint.getSize() * cropRegion.width());
+        int height = (int) (meteringPoint.getSize() * cropRegion.height());
+
+        Rect focusRect = new Rect(centerX - width / 2, centerY - height / 2, centerX + width / 2,
+                centerY + height / 2);
+
+        focusRect.left = rangeLimit(focusRect.left, cropRegion.right, cropRegion.left);
+        focusRect.right = rangeLimit(focusRect.right, cropRegion.right, cropRegion.left);
+        focusRect.top = rangeLimit(focusRect.top, cropRegion.bottom, cropRegion.top);
+        focusRect.bottom = rangeLimit(focusRect.bottom, cropRegion.bottom, cropRegion.top);
+
+        int weight = (int) (meteringPoint.getWeight() * MeteringRectangle.METERING_WEIGHT_MAX);
+
+        weight = rangeLimit(weight, MeteringRectangle.METERING_WEIGHT_MAX,
+                MeteringRectangle.METERING_WEIGHT_MIN);
+        return new MeteringRectangle(focusRect, weight);
+    }
+
+    @WorkerThread
+    private int rangeLimit(int val, int max, int min) {
+        return Math.min(Math.max(val, min), max);
+    }
+
+    @WorkerThread
+    void startFocusAndMetering(@NonNull FocusMeteringAction action,
+            @Nullable Rational defaultAspectRatio) {
+        if (mCurrentFocusMeteringAction != null) {
+            cancelFocusAndMetering();
+        }
+        mCurrentFocusMeteringAction = action;
+
+        Rect cropSensorRegion = mCameraControl.getCropSensorRegion();
+        Rational cropRegionAspectRatio = new Rational(cropSensorRegion.width(),
+                cropSensorRegion.height());
+
+        if (defaultAspectRatio == null) {
+            defaultAspectRatio = cropRegionAspectRatio;
+        }
+
+        List<MeteringRectangle> meteringRectanglesListAF = new ArrayList<>();
+        List<MeteringRectangle> meteringRectanglesListAE = new ArrayList<>();
+        List<MeteringRectangle> meteringRectanglesListAWB = new ArrayList<>();
+
+        for (MeteringPoint meteringPoint : action.getMeteringPointsAF()) {
+            PointF adjustedPoint = getFOVAdjustedPoint(meteringPoint, cropRegionAspectRatio,
+                    defaultAspectRatio);
+            MeteringRectangle meteringRectangle = getMeteringRect(meteringPoint, adjustedPoint,
+                    cropSensorRegion);
+            meteringRectanglesListAF.add(meteringRectangle);
+        }
+
+        for (MeteringPoint meteringPoint : action.getMeteringPointsAE()) {
+            PointF adjustedPoint = getFOVAdjustedPoint(meteringPoint, cropRegionAspectRatio,
+                    defaultAspectRatio);
+            MeteringRectangle meteringRectangle = getMeteringRect(meteringPoint, adjustedPoint,
+                    cropSensorRegion);
+            meteringRectanglesListAE.add(meteringRectangle);
+        }
+
+        for (MeteringPoint meteringPoint : action.getMeteringPointsAWB()) {
+            PointF adjustedPoint = getFOVAdjustedPoint(meteringPoint, cropRegionAspectRatio,
+                    defaultAspectRatio);
+            MeteringRectangle meteringRectangle = getMeteringRect(meteringPoint, adjustedPoint,
+                    cropSensorRegion);
+            meteringRectanglesListAWB.add(meteringRectangle);
+        }
+
+        executeMeteringAction(meteringRectanglesListAF.toArray(
+                new MeteringRectangle[meteringRectanglesListAF.size()]),
+                meteringRectanglesListAE.toArray(
+                        new MeteringRectangle[meteringRectanglesListAE.size()]),
+                meteringRectanglesListAWB.toArray(
+                        new MeteringRectangle[meteringRectanglesListAWB.size()]),
+                action
+        );
+    }
+
+    @WorkerThread
+    private int getDefaultTemplate() {
+        return CameraDevice.TEMPLATE_PREVIEW;
+    }
+
+    @WorkerThread
+    void triggerAf() {
+        CaptureConfig.Builder builder = new CaptureConfig.Builder();
+        builder.setTemplateType(getDefaultTemplate());
+        builder.setUseRepeatingSurface(true);
+        Camera2Config.Builder configBuilder = new Camera2Config.Builder();
+        configBuilder.setCaptureRequestOption(CaptureRequest.CONTROL_AF_TRIGGER,
+                CaptureRequest.CONTROL_AF_TRIGGER_START);
+        builder.addImplementationOptions(configBuilder.build());
+        mCameraControl.submitCaptureRequestsInternal(Collections.singletonList(builder.build()));
+    }
+
+    @WorkerThread
+    void triggerAePrecapture() {
+        CaptureConfig.Builder builder = new CaptureConfig.Builder();
+        builder.setTemplateType(getDefaultTemplate());
+        builder.setUseRepeatingSurface(true);
+        Camera2Config.Builder configBuilder = new Camera2Config.Builder();
+        configBuilder.setCaptureRequestOption(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
+        builder.addImplementationOptions(configBuilder.build());
+        mCameraControl.submitCaptureRequestsInternal(Collections.singletonList(builder.build()));
+    }
+
+    @WorkerThread
+    void cancelAfAeTrigger(final boolean cancelAfTrigger,
+            final boolean cancelAePrecaptureTrigger) {
+        CaptureConfig.Builder builder = new CaptureConfig.Builder();
+        builder.setUseRepeatingSurface(true);
+        builder.setTemplateType(getDefaultTemplate());
+
+        Camera2Config.Builder configBuilder = new Camera2Config.Builder();
+        if (cancelAfTrigger) {
+            configBuilder.setCaptureRequestOption(CaptureRequest.CONTROL_AF_TRIGGER,
+                    CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
+        }
+        if (Build.VERSION.SDK_INT >= 23 && cancelAePrecaptureTrigger) {
+            configBuilder.setCaptureRequestOption(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                    CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL);
+        }
+        builder.addImplementationOptions(configBuilder.build());
+        mCameraControl.submitCaptureRequestsInternal(Collections.singletonList(builder.build()));
+    }
+
+
+    @WorkerThread
+    private void disableAutoCancel() {
+        if (mAutoCancelHandle != null) {
+            mAutoCancelHandle.cancel(/*mayInterruptIfRunning=*/true);
+            mAutoCancelHandle = null;
+        }
+    }
+
+    @WorkerThread
+    void executeMeteringAction(
+            @Nullable MeteringRectangle[] afRects,
+            @Nullable MeteringRectangle[] aeRects,
+            @Nullable MeteringRectangle[] awbRects,
+            FocusMeteringAction focusMeteringAction) {
+        mCameraControl.removeCaptureResultListener(mSessionListenerForFocus);
+
+        disableAutoCancel();
+
+        if (afRects == null) {
+            mAfRects = new MeteringRectangle[]{};
+        } else {
+            mAfRects = afRects;
+        }
+
+        if (aeRects == null) {
+            mAeRects = new MeteringRectangle[]{};
+        } else {
+            mAeRects = aeRects;
+        }
+
+        if (awbRects == null) {
+            mAwbRects = new MeteringRectangle[]{};
+        } else {
+            mAwbRects = awbRects;
+        }
+
+        // Trigger AF scan if any AF points are added.
+        if (shouldTriggerAF()) {
+            mCurrentAfState = CaptureResult.CONTROL_AF_STATE_INACTIVE;
+            if (focusMeteringAction.getOnAutoFocusListener() != null) {
+                mSessionListenerForFocus =
+                        new Camera2CameraControl.CaptureResultListener() {
+                            // Will be called on mExecutor since mSessionCallback was created with
+                            // mExecutor
+                            @WorkerThread
+                            @Override
+                            public boolean onCaptureResult(@NonNull TotalCaptureResult result) {
+                                Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
+                                if (afState == null) {
+                                    return false;
+                                }
+
+                                if (mCurrentAfState == CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN) {
+                                    if (afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED) {
+                                        focusMeteringAction.notifyAutoFocusCompleted(true);
+                                        return true; // finished
+                                    } else if (afState
+                                            == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
+                                        focusMeteringAction.notifyAutoFocusCompleted(false);
+                                        return true; // finished
+                                    }
+                                }
+                                if (!mCurrentAfState.equals(afState)) {
+                                    mCurrentAfState = afState;
+                                }
+                                return false; // continue checking
+                            }
+                        };
+
+                mCameraControl.addCaptureResultListener(mSessionListenerForFocus);
+            }
+
+            mIsInAfAutoMode = true;
+            mCameraControl.updateSessionConfig();
+            triggerAf();
+        } else {
+            // Still calls OnAutoFocusActionListener when AF is not enabled.
+            focusMeteringAction.notifyAutoFocusCompleted(false);
+            mCameraControl.updateSessionConfig();
+        }
+
+        if (focusMeteringAction.isAutoCancelEnabled()) {
+            final long timeoutId = ++mFocusTimeoutCounter;
+            final Runnable autoCancelRunnable = new Runnable() {
+                @Override
+                public void run() {
+                    mExecutor.execute(new Runnable() {
+                        @WorkerThread
+                        @Override
+                        public void run() {
+                            if (timeoutId == mFocusTimeoutCounter) {
+                                cancelFocusAndMetering();
+                            }
+                        }
+                    });
+                }
+            };
+
+            mAutoCancelHandle = mScheduler.schedule(autoCancelRunnable,
+                    focusMeteringAction.getAutoCancelDurationInMs(),
+                    TimeUnit.MILLISECONDS);
+        }
+    }
+
+    @WorkerThread
+    private boolean shouldTriggerAF() {
+        return mAfRects.length > 0;
+    }
+
+    @WorkerThread
+    void cancelFocusAndMetering() {
+        mCameraControl.removeCaptureResultListener(mSessionListenerForFocus);
+
+        if (mCurrentFocusMeteringAction != null) {
+            mCurrentFocusMeteringAction.notifyAutoFocusCompleted(false);
+        }
+        disableAutoCancel();
+
+        if (shouldTriggerAF()) {
+            cancelAfAeTrigger(true, false);
+        }
+        mAfRects = new MeteringRectangle[]{};
+        mAeRects = new MeteringRectangle[]{};
+        mAwbRects = new MeteringRectangle[]{};
+
+        mIsInAfAutoMode = false;
+        mCameraControl.updateSessionConfig();
+        mCurrentFocusMeteringAction = null;
+    }
+}
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/compat/params/OutputConfigurationCompatBaseImpl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/compat/params/OutputConfigurationCompatBaseImpl.java
index 7015f02..f1c4fbe 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/compat/params/OutputConfigurationCompatBaseImpl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/compat/params/OutputConfigurationCompatBaseImpl.java
@@ -18,6 +18,7 @@
 
 import android.annotation.SuppressLint;
 import android.graphics.ImageFormat;
+import android.os.Build;
 import android.util.Log;
 import android.util.Size;
 import android.view.Surface;
@@ -248,6 +249,10 @@
                 Class<?> legacyCameraDeviceClass = Class.forName(LEGACY_CAMERA_DEVICE_CLASS);
                 Method detectSurfaceType = legacyCameraDeviceClass.getDeclaredMethod(
                         DETECT_SURFACE_TYPE_METHOD, Surface.class);
+                if (Build.VERSION.SDK_INT < 22) {
+                    // On API 21, 'detectSurfaceType()' is package private.
+                    detectSurfaceType.setAccessible(true);
+                }
                 return (int) detectSurfaceType.invoke(null, surface);
             } catch (ClassNotFoundException
                     | NoSuchMethodException
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/Camera2DeviceSurfaceManagerTest.java b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/Camera2DeviceSurfaceManagerTest.java
index 63bd355..e6d2710 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/Camera2DeviceSurfaceManagerTest.java
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/Camera2DeviceSurfaceManagerTest.java
@@ -56,6 +56,7 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.filters.SmallTest;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -132,6 +133,11 @@
         setupCamera();
     }
 
+    @After
+    public void tearDown() {
+        CameraX.deinit();
+    }
+
     @Test
     public void checkLegacySurfaceCombinationSupportedInLegacyDevice() {
         SupportedSurfaceCombination supportedSurfaceCombination =
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/CameraAvailabilityRegistryTest.java b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/CameraAvailabilityRegistryTest.java
new file mode 100644
index 0000000..3ab4d6d
--- /dev/null
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/CameraAvailabilityRegistryTest.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2019 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.camera.camera2.impl;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.camera.core.BaseCamera;
+import androidx.camera.core.Observable;
+import androidx.camera.core.impl.utils.executor.CameraXExecutors;
+import androidx.camera.testing.fakes.FakeCamera;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.internal.DoNotInstrument;
+import org.robolectric.shadows.ShadowLooper;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+@SmallTest
+@RunWith(RobolectricTestRunner.class)
+@DoNotInstrument
+@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
+public final class CameraAvailabilityRegistryTest {
+    private int mAvailableCameraCount;
+    private Observable.Observer<Integer> mCountObserver = new Observable.Observer<Integer>() {
+
+        @Override
+        public void onNewData(@Nullable Integer value) {
+            mAvailableCameraCount = value;
+        }
+
+        @Override
+        public void onError(@NonNull Throwable t) {
+
+        }
+    };
+
+    @Before
+    public void setUp() {
+        mAvailableCameraCount = 0;
+    }
+
+    @Test
+    public void singleOpenCamera_reducesAvailableCameras() {
+        CameraAvailabilityRegistry registry = new CameraAvailabilityRegistry(1,
+                CameraXExecutors.directExecutor());
+
+        Observable<Integer> cameraCountObservable = registry.getAvailableCameraCount();
+
+        cameraCountObservable.addObserver(CameraXExecutors.directExecutor(), mCountObserver);
+
+        ShadowLooper.runUiThreadTasks();
+
+        int initialAvailableCount = mAvailableCameraCount;
+
+        FakeCamera camera = new FakeCamera();
+        camera.open();
+
+        registry.registerCamera(camera);
+
+        ShadowLooper.runUiThreadTasks();
+
+        int finalAvailableCount = mAvailableCameraCount;
+
+        cameraCountObservable.removeObserver(mCountObserver);
+
+        assertThat(initialAvailableCount).isEqualTo(1);
+        assertThat(finalAvailableCount).isEqualTo(0);
+    }
+
+    @Test
+    public void singleClosedCamera_doesNotReduceAvailableCameras() {
+        CameraAvailabilityRegistry registry = new CameraAvailabilityRegistry(1,
+                CameraXExecutors.directExecutor());
+
+        Observable<Integer> cameraCountObservable = registry.getAvailableCameraCount();
+
+        cameraCountObservable.addObserver(CameraXExecutors.directExecutor(), mCountObserver);
+
+        ShadowLooper.runUiThreadTasks();
+
+        int initialAvailableCount = mAvailableCameraCount;
+
+        FakeCamera camera = new FakeCamera();
+        // Do not open the camera. Leave in this state.
+
+        registry.registerCamera(camera);
+
+        ShadowLooper.runUiThreadTasks();
+
+        int finalAvailableCount = mAvailableCameraCount;
+
+        cameraCountObservable.removeObserver(mCountObserver);
+
+        assertThat(initialAvailableCount).isEqualTo(1);
+        assertThat(finalAvailableCount).isEqualTo(1);
+    }
+
+    @Test
+    public void closingCameras_increasesAvailableCount() {
+        CameraAvailabilityRegistry registry = new CameraAvailabilityRegistry(1,
+                CameraXExecutors.directExecutor());
+
+        Observable<Integer> cameraCountObservable = registry.getAvailableCameraCount();
+
+        cameraCountObservable.addObserver(CameraXExecutors.directExecutor(), mCountObserver);
+
+        FakeCamera camera = new FakeCamera();
+        camera.open();
+
+        registry.registerCamera(camera);
+
+        ShadowLooper.runUiThreadTasks();
+
+        int initialAvailableCount = mAvailableCameraCount;
+
+        camera.close();
+
+        ShadowLooper.runUiThreadTasks();
+
+        int finalAvailableCount = mAvailableCameraCount;
+
+        cameraCountObservable.removeObserver(mCountObserver);
+
+        assertThat(initialAvailableCount).isEqualTo(0);
+        assertThat(finalAvailableCount).isEqualTo(1);
+    }
+
+    @Test
+    public void releasingCameras_increasesAvailableCount() {
+        CameraAvailabilityRegistry registry = new CameraAvailabilityRegistry(1,
+                CameraXExecutors.directExecutor());
+
+        Observable<Integer> cameraCountObservable = registry.getAvailableCameraCount();
+
+        cameraCountObservable.addObserver(CameraXExecutors.directExecutor(), mCountObserver);
+
+        FakeCamera camera = new FakeCamera();
+        camera.open();
+
+        registry.registerCamera(camera);
+
+        ShadowLooper.runUiThreadTasks();
+
+        int initialAvailableCount = mAvailableCameraCount;
+
+        camera.release();
+
+        ShadowLooper.runUiThreadTasks();
+
+        int finalAvailableCount = mAvailableCameraCount;
+
+        cameraCountObservable.removeObserver(mCountObserver);
+
+        assertThat(initialAvailableCount).isEqualTo(0);
+        assertThat(finalAvailableCount).isEqualTo(1);
+    }
+
+    @Test
+    public void availableCount_neverGoesNegative() {
+        CameraAvailabilityRegistry registry = new CameraAvailabilityRegistry(1,
+                CameraXExecutors.directExecutor());
+
+        Observable<Integer> cameraCountObservable = registry.getAvailableCameraCount();
+
+        cameraCountObservable.addObserver(CameraXExecutors.directExecutor(), mCountObserver);
+
+        FakeCamera camera1 = new FakeCamera();
+        camera1.open();
+        FakeCamera camera2 = new FakeCamera();
+        camera2.open();
+
+        registry.registerCamera(camera1);
+        registry.registerCamera(camera2);
+
+        ShadowLooper.runUiThreadTasks();
+
+        int finalAvailableCount = mAvailableCameraCount;
+
+        cameraCountObservable.removeObserver(mCountObserver);
+
+        assertThat(finalAvailableCount).isEqualTo(0);
+    }
+
+    @Test
+    public void pendingOpen_isNotCountedAsOpen() {
+        CameraAvailabilityRegistry registry = new CameraAvailabilityRegistry(1,
+                CameraXExecutors.directExecutor());
+
+        Observable<Integer> cameraCountObservable = registry.getAvailableCameraCount();
+
+        cameraCountObservable.addObserver(CameraXExecutors.directExecutor(), mCountObserver);
+
+        FakeCamera camera = new FakeCamera();
+
+        AtomicReference<BaseCamera.State> cameraState = new AtomicReference<>(null);
+        Observable.Observer<BaseCamera.State> stateObserver =
+                new Observable.Observer<BaseCamera.State>() {
+
+                    @Override
+                    public void onNewData(@Nullable BaseCamera.State value) {
+                        cameraState.set(value);
+                    }
+
+                    @Override
+                    public void onError(@NonNull Throwable t) {
+
+                    }
+                };
+
+        camera.getCameraState().addObserver(CameraXExecutors.directExecutor(), stateObserver);
+        camera.setAvailableCameraCount(0);
+        camera.open();
+
+        ShadowLooper.runUiThreadTasks();
+
+        camera.getCameraState().removeObserver(stateObserver);
+        cameraCountObservable.removeObserver(mCountObserver);
+
+        // Ensure that even though the camera is the PENDING_OPEN state, there is still 1 camera
+        // available to be opened.
+        assertThat(cameraState.get()).isEqualTo(BaseCamera.State.PENDING_OPEN);
+        assertThat(mAvailableCameraCount).isEqualTo(1);
+    }
+}
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/DisplayOrientedMeteringPointFactoryTest.java b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/DisplayOrientedMeteringPointFactoryTest.java
new file mode 100644
index 0000000..066d37b
--- /dev/null
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/DisplayOrientedMeteringPointFactoryTest.java
@@ -0,0 +1,364 @@
+/*
+ * Copyright 2019 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.camera.camera2.impl;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Build;
+import android.view.Display;
+import android.view.Surface;
+import android.view.WindowManager;
+
+import androidx.camera.core.AppConfig;
+import androidx.camera.core.CameraDeviceSurfaceManager;
+import androidx.camera.core.CameraX;
+import androidx.camera.core.ConfigProvider;
+import androidx.camera.core.DisplayOrientedMeteringPointFactory;
+import androidx.camera.core.ExtendableUseCaseConfigFactory;
+import androidx.camera.core.MeteringPoint;
+import androidx.camera.core.MeteringPointFactory;
+import androidx.camera.testing.fakes.FakeCamera;
+import androidx.camera.testing.fakes.FakeCameraDeviceSurfaceManager;
+import androidx.camera.testing.fakes.FakeCameraFactory;
+import androidx.camera.testing.fakes.FakeCameraInfo;
+import androidx.camera.testing.fakes.FakeUseCaseConfig;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.internal.DoNotInstrument;
+
+@SmallTest
+@RunWith(RobolectricTestRunner.class)
+@DoNotInstrument
+@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
+public class DisplayOrientedMeteringPointFactoryTest {
+    private static final float WIDTH = 480;
+    private static final float HEIGHT = 640;
+    private Context mMockContext;
+    private Display mMockDisplay;
+
+    @Before
+    public void setUp() {
+        Context context = ApplicationProvider.getApplicationContext();
+
+        // Init CameraX to inject our FakeCamera with FakeCameraInfo.
+        FakeCameraFactory fakeCameraFactory = new FakeCameraFactory();
+        fakeCameraFactory.insertBackCamera(
+                new FakeCamera(new FakeCameraInfo(90, CameraX.LensFacing.BACK), null));
+        fakeCameraFactory.insertFrontCamera(
+                new FakeCamera(new FakeCameraInfo(270, CameraX.LensFacing.FRONT), null));
+
+        CameraDeviceSurfaceManager surfaceManager = new FakeCameraDeviceSurfaceManager();
+        ExtendableUseCaseConfigFactory defaultConfigFactory = new ExtendableUseCaseConfigFactory();
+        defaultConfigFactory.installDefaultProvider(FakeUseCaseConfig.class,
+                new ConfigProvider<FakeUseCaseConfig>() {
+                    @Override
+                    public FakeUseCaseConfig getConfig(CameraX.LensFacing lensFacing) {
+                        return new FakeUseCaseConfig.Builder().build();
+                    }
+                });
+
+        AppConfig appConfig =
+                new AppConfig.Builder()
+                        .setCameraFactory(fakeCameraFactory)
+                        .setDeviceSurfaceManager(surfaceManager)
+                        .setUseCaseConfigFactory(defaultConfigFactory)
+                        .build();
+        CameraX.init(context, appConfig);
+
+        mMockDisplay = Mockito.mock(Display.class);
+        when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_0);
+        WindowManager mockWindowManager = Mockito.mock(WindowManager.class);
+        when(mockWindowManager.getDefaultDisplay()).thenReturn(mMockDisplay);
+        mMockContext = Mockito.mock(Context.class);
+        when(mMockContext.getSystemService(Context.WINDOW_SERVICE)).thenReturn(mockWindowManager);
+    }
+
+    @After
+    public void tearDown() {
+        CameraX.deinit();
+    }
+
+    @Test
+    public void defaultWeightAndAreaSize() {
+        DisplayOrientedMeteringPointFactory factory = new DisplayOrientedMeteringPointFactory(
+                mMockContext, CameraX.LensFacing.BACK, WIDTH, HEIGHT);
+
+        MeteringPoint point = factory.createPoint(0, 0);
+        assertThat(point.getSize()).isEqualTo(MeteringPointFactory.DEFAULT_AREASIZE);
+        assertThat(point.getWeight()).isEqualTo(MeteringPointFactory.DEFAULT_WEIGHT);
+        assertThat(point.getFOVAspectRatio()).isNull();
+    }
+
+    @Test
+    public void createPointWithValidWeightAndAreaSize() {
+        DisplayOrientedMeteringPointFactory factory = new DisplayOrientedMeteringPointFactory(
+                mMockContext, CameraX.LensFacing.BACK, WIDTH, HEIGHT);
+
+        final float areaSize = 0.2f;
+        final float weight = 0.5f;
+        MeteringPoint point = factory.createPoint(0, 0, areaSize, weight);
+        assertThat(point.getSize()).isEqualTo(areaSize);
+        assertThat(point.getWeight()).isEqualTo(weight);
+        assertThat(point.getFOVAspectRatio()).isNull();
+    }
+
+    @Test
+    public void display0_back() {
+        when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_0);
+
+        DisplayOrientedMeteringPointFactory factory = new DisplayOrientedMeteringPointFactory(
+                mMockContext, CameraX.LensFacing.BACK, WIDTH, HEIGHT);
+
+        MeteringPoint meteringPoint = factory.createPoint(0f, 0f);
+        assertThat(meteringPoint.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint.getNormalizedCropRegionY()).isEqualTo(1f);
+
+        MeteringPoint meteringPoint2 = factory.createPoint(0f, HEIGHT);
+        assertThat(meteringPoint2.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint2.getNormalizedCropRegionY()).isEqualTo(1f);
+
+        MeteringPoint meteringPoint3 = factory.createPoint(WIDTH, 0f);
+
+        assertThat(meteringPoint3.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint3.getNormalizedCropRegionY()).isEqualTo(0f);
+
+        MeteringPoint meteringPoint4 = factory.createPoint(WIDTH, HEIGHT);
+
+        assertThat(meteringPoint4.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint4.getNormalizedCropRegionY()).isEqualTo(0f);
+    }
+
+    @Test
+    public void display0_front() {
+        when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_0);
+
+        DisplayOrientedMeteringPointFactory factory = new DisplayOrientedMeteringPointFactory(
+                mMockContext, CameraX.LensFacing.FRONT, WIDTH, HEIGHT);
+
+        MeteringPoint meteringPoint = factory.createPoint(0f, 0f);
+        assertThat(meteringPoint.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint.getNormalizedCropRegionY()).isEqualTo(1f);
+
+        MeteringPoint meteringPoint2 = factory.createPoint(0f, HEIGHT);
+        assertThat(meteringPoint2.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint2.getNormalizedCropRegionY()).isEqualTo(1f);
+
+        MeteringPoint meteringPoint3 = factory.createPoint(WIDTH, 0f);
+
+        assertThat(meteringPoint3.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint3.getNormalizedCropRegionY()).isEqualTo(0f);
+
+        MeteringPoint meteringPoint4 = factory.createPoint(WIDTH, HEIGHT);
+
+        assertThat(meteringPoint4.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint4.getNormalizedCropRegionY()).isEqualTo(0f);
+    }
+
+    @Test
+    public void display90_back() {
+        when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_90);
+
+        DisplayOrientedMeteringPointFactory factory = new DisplayOrientedMeteringPointFactory(
+                mMockContext, CameraX.LensFacing.BACK, WIDTH, HEIGHT);
+
+        MeteringPoint meteringPoint = factory.createPoint(0f, 0f);
+        assertThat(meteringPoint.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint.getNormalizedCropRegionY()).isEqualTo(0f);
+
+        MeteringPoint meteringPoint2 = factory.createPoint(0f, HEIGHT);
+        assertThat(meteringPoint2.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint2.getNormalizedCropRegionY()).isEqualTo(1f);
+
+        MeteringPoint meteringPoint3 = factory.createPoint(WIDTH, 0f);
+
+        assertThat(meteringPoint3.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint3.getNormalizedCropRegionY()).isEqualTo(0f);
+
+        MeteringPoint meteringPoint4 = factory.createPoint(WIDTH, HEIGHT);
+
+        assertThat(meteringPoint4.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint4.getNormalizedCropRegionY()).isEqualTo(1f);
+    }
+
+    @Test
+    public void display90_front() {
+        when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_90);
+
+        DisplayOrientedMeteringPointFactory factory = new DisplayOrientedMeteringPointFactory(
+                mMockContext, CameraX.LensFacing.FRONT, WIDTH, HEIGHT);
+
+        MeteringPoint meteringPoint = factory.createPoint(0f, 0f);
+        assertThat(meteringPoint.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint.getNormalizedCropRegionY()).isEqualTo(0f);
+
+        MeteringPoint meteringPoint2 = factory.createPoint(0f, HEIGHT);
+        assertThat(meteringPoint2.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint2.getNormalizedCropRegionY()).isEqualTo(1f);
+
+        MeteringPoint meteringPoint3 = factory.createPoint(WIDTH, 0f);
+
+        assertThat(meteringPoint3.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint3.getNormalizedCropRegionY()).isEqualTo(0f);
+
+        MeteringPoint meteringPoint4 = factory.createPoint(WIDTH, HEIGHT);
+
+        assertThat(meteringPoint4.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint4.getNormalizedCropRegionY()).isEqualTo(1f);
+    }
+
+    @Test
+    public void display180_back() {
+        when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_180);
+
+        DisplayOrientedMeteringPointFactory factory = new DisplayOrientedMeteringPointFactory(
+                mMockContext, CameraX.LensFacing.BACK, WIDTH, HEIGHT);
+
+        MeteringPoint meteringPoint = factory.createPoint(0f, 0f);
+        assertThat(meteringPoint.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint.getNormalizedCropRegionY()).isEqualTo(0f);
+
+        MeteringPoint meteringPoint2 = factory.createPoint(0f, HEIGHT);
+        assertThat(meteringPoint2.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint2.getNormalizedCropRegionY()).isEqualTo(0f);
+
+        MeteringPoint meteringPoint3 = factory.createPoint(WIDTH, 0f);
+
+        assertThat(meteringPoint3.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint3.getNormalizedCropRegionY()).isEqualTo(1f);
+
+        MeteringPoint meteringPoint4 = factory.createPoint(WIDTH, HEIGHT);
+
+        assertThat(meteringPoint4.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint4.getNormalizedCropRegionY()).isEqualTo(1f);
+    }
+
+    @Test
+    public void display180_front() {
+        when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_180);
+
+        DisplayOrientedMeteringPointFactory factory = new DisplayOrientedMeteringPointFactory(
+                mMockContext, CameraX.LensFacing.FRONT, WIDTH, HEIGHT);
+
+        MeteringPoint meteringPoint = factory.createPoint(0f, 0f);
+        assertThat(meteringPoint.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint.getNormalizedCropRegionY()).isEqualTo(0f);
+
+        MeteringPoint meteringPoint2 = factory.createPoint(0f, HEIGHT);
+        assertThat(meteringPoint2.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint2.getNormalizedCropRegionY()).isEqualTo(0f);
+
+        MeteringPoint meteringPoint3 = factory.createPoint(WIDTH, 0f);
+
+        assertThat(meteringPoint3.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint3.getNormalizedCropRegionY()).isEqualTo(1f);
+
+        MeteringPoint meteringPoint4 = factory.createPoint(WIDTH, HEIGHT);
+
+        assertThat(meteringPoint4.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint4.getNormalizedCropRegionY()).isEqualTo(1f);
+    }
+
+    @Test
+    public void display270_back() {
+        when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_270);
+
+        DisplayOrientedMeteringPointFactory factory = new DisplayOrientedMeteringPointFactory(
+                mMockContext, CameraX.LensFacing.BACK, WIDTH, HEIGHT);
+
+        MeteringPoint meteringPoint = factory.createPoint(0f, 0f);
+        assertThat(meteringPoint.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint.getNormalizedCropRegionY()).isEqualTo(1f);
+
+        MeteringPoint meteringPoint2 = factory.createPoint(0f, HEIGHT);
+        assertThat(meteringPoint2.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint2.getNormalizedCropRegionY()).isEqualTo(0f);
+
+        MeteringPoint meteringPoint3 = factory.createPoint(WIDTH, 0f);
+
+        assertThat(meteringPoint3.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint3.getNormalizedCropRegionY()).isEqualTo(1f);
+
+        MeteringPoint meteringPoint4 = factory.createPoint(WIDTH, HEIGHT);
+
+        assertThat(meteringPoint4.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint4.getNormalizedCropRegionY()).isEqualTo(0f);
+    }
+
+    @Test
+    public void display270_front() {
+        when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_270);
+
+        DisplayOrientedMeteringPointFactory factory = new DisplayOrientedMeteringPointFactory(
+                mMockContext, CameraX.LensFacing.FRONT, WIDTH, HEIGHT);
+
+        MeteringPoint meteringPoint = factory.createPoint(0f, 0f);
+        assertThat(meteringPoint.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint.getNormalizedCropRegionY()).isEqualTo(1f);
+
+        MeteringPoint meteringPoint2 = factory.createPoint(0f, HEIGHT);
+        assertThat(meteringPoint2.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint2.getNormalizedCropRegionY()).isEqualTo(0f);
+
+        MeteringPoint meteringPoint3 = factory.createPoint(WIDTH, 0f);
+
+        assertThat(meteringPoint3.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint3.getNormalizedCropRegionY()).isEqualTo(1f);
+
+        MeteringPoint meteringPoint4 = factory.createPoint(WIDTH, HEIGHT);
+
+        assertThat(meteringPoint4.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint4.getNormalizedCropRegionY()).isEqualTo(0f);
+    }
+
+    @Test
+    public void display0_back_useCustomDisplay() {
+        when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_270);
+
+        DisplayOrientedMeteringPointFactory factory = new DisplayOrientedMeteringPointFactory(
+                mMockDisplay, CameraX.LensFacing.FRONT, WIDTH, HEIGHT);
+
+        MeteringPoint meteringPoint = factory.createPoint(0f, 0f);
+        assertThat(meteringPoint.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint.getNormalizedCropRegionY()).isEqualTo(1f);
+
+        MeteringPoint meteringPoint2 = factory.createPoint(0f, HEIGHT);
+        assertThat(meteringPoint2.getNormalizedCropRegionX()).isEqualTo(0f);
+        assertThat(meteringPoint2.getNormalizedCropRegionY()).isEqualTo(0f);
+
+        MeteringPoint meteringPoint3 = factory.createPoint(WIDTH, 0f);
+
+        assertThat(meteringPoint3.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint3.getNormalizedCropRegionY()).isEqualTo(1f);
+
+        MeteringPoint meteringPoint4 = factory.createPoint(WIDTH, HEIGHT);
+
+        assertThat(meteringPoint4.getNormalizedCropRegionX()).isEqualTo(1f);
+        assertThat(meteringPoint4.getNormalizedCropRegionY()).isEqualTo(0f);
+    }
+
+}
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/FocusMeteringControlTest.java b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/FocusMeteringControlTest.java
new file mode 100644
index 0000000..cf2bb81
--- /dev/null
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/FocusMeteringControlTest.java
@@ -0,0 +1,903 @@
+/*
+ * Copyright 2019 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.camera.camera2.impl;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.MeteringRectangle;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Rational;
+import android.util.Size;
+
+import androidx.annotation.NonNull;
+import androidx.camera.camera2.Camera2AppConfig;
+import androidx.camera.camera2.Camera2Config;
+import androidx.camera.camera2.impl.Camera2CameraControl.CaptureResultListener;
+import androidx.camera.core.AppConfig;
+import androidx.camera.core.CameraX;
+import androidx.camera.core.FocusMeteringAction;
+import androidx.camera.core.ImageAnalysis;
+import androidx.camera.core.MeteringPoint;
+import androidx.camera.core.MeteringPointFactory;
+import androidx.camera.core.Observable;
+import androidx.camera.core.SensorOrientedMeteringPointFactory;
+import androidx.camera.core.impl.utils.executor.CameraXExecutors;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.filters.SmallTest;
+
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.internal.DoNotInstrument;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowCameraCharacteristics;
+import org.robolectric.shadows.ShadowCameraManager;
+import org.robolectric.shadows.ShadowLooper;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+@SmallTest
+@RunWith(RobolectricTestRunner.class)
+@DoNotInstrument
+public class FocusMeteringControlTest {
+    private static final String CAMERA0_ID = "0";
+    private static final String CAMERA1_ID = "1";
+    private static final int SENSOR_WIDTH = 640;
+    private static final int SENSOR_HEIGHT = 480;
+    private static final int SENSOR_WIDTH2 = 1920;
+    private static final int SENSOR_HEIGHT2 = 1080;
+
+    private static final int AREA_WIDTH =
+            (int) (MeteringPointFactory.DEFAULT_AREASIZE * SENSOR_WIDTH);
+    private static final int AREA_HEIGHT =
+            (int) (MeteringPointFactory.DEFAULT_AREASIZE * SENSOR_HEIGHT);
+    private static final int AREA_WIDTH2 =
+            (int) (MeteringPointFactory.DEFAULT_AREASIZE * SENSOR_WIDTH2);
+    private static final int AREA_HEIGHT2 =
+            (int) (MeteringPointFactory.DEFAULT_AREASIZE * SENSOR_HEIGHT2);
+
+    SensorOrientedMeteringPointFactory mPointFactory = new SensorOrientedMeteringPointFactory(1, 1);
+    FocusMeteringControl mFocusMeteringControl;
+
+    MeteringPoint mPoint1 = mPointFactory.createPoint(0, 0);
+    MeteringPoint mPoint2 = mPointFactory.createPoint(0.0f, 1.0f);
+    MeteringPoint mPoint3 = mPointFactory.createPoint(1.0f, 1.0f);
+
+    Rect mMRect1 = new Rect(0, 0, AREA_WIDTH / 2, AREA_HEIGHT / 2);
+    Rect mMRect2 = new Rect(0, SENSOR_HEIGHT - AREA_HEIGHT / 2, AREA_WIDTH / 2, SENSOR_HEIGHT);
+    Rect mMRect3 = new Rect(SENSOR_WIDTH - AREA_WIDTH / 2, SENSOR_HEIGHT - AREA_HEIGHT / 2,
+            SENSOR_WIDTH, SENSOR_HEIGHT);
+
+    Rational mPreviewAspectRatio4X3 = new Rational(4, 3);
+    Camera2CameraControl mCamera2CameraControl;
+
+    @Before
+    public void setUp() throws CameraAccessException {
+        Context context = ApplicationProvider.getApplicationContext();
+        AppConfig config = Camera2AppConfig.create(context);
+        CameraX.init(context, config);
+        initCameraManager();
+        mFocusMeteringControl = spy(initFocusMeteringControl(CAMERA0_ID));
+    }
+
+    private FocusMeteringControl initFocusMeteringControl(String cameraID) throws
+            CameraAccessException {
+        CameraManager cameraManager =
+                (CameraManager) ApplicationProvider.getApplicationContext().getSystemService(
+                        Context.CAMERA_SERVICE);
+        Camera camera = spy(
+                new Camera(cameraManager, cameraID, getObserable(),
+                        new Handler(Looper.getMainLooper())));
+
+        CameraCharacteristics cameraCharacteristics =
+                cameraManager.getCameraCharacteristics(
+                        cameraID);
+
+        mCamera2CameraControl = spy(new Camera2CameraControl(cameraCharacteristics, camera,
+                CameraXExecutors.mainThreadExecutor(), CameraXExecutors.mainThreadExecutor()));
+
+
+        return new FocusMeteringControl(mCamera2CameraControl,
+                CameraXExecutors.mainThreadExecutor(), CameraXExecutors.mainThreadExecutor());
+    }
+
+    private Observable<Integer> getObserable() {
+        return new Observable<Integer>() {
+            @NonNull
+            @Override
+            public ListenableFuture<Integer> fetchData() {
+                return null;
+            }
+
+            @Override
+            public void addObserver(@NonNull Executor executor,
+                    @NonNull Observer<Integer> observer) {
+
+            }
+
+            @Override
+            public void removeObserver(@NonNull Observer<Integer> observer) {
+
+            }
+        };
+    }
+
+    private void initCameraManager() {
+        // **** Camera 0 characteristics ****//
+        CameraCharacteristics characteristics0 =
+                ShadowCameraCharacteristics.newCameraCharacteristics();
+
+        ShadowCameraCharacteristics shadowCharacteristics0 = Shadow.extract(characteristics0);
+
+        shadowCharacteristics0.set(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE,
+                new Rect(0, 0, SENSOR_WIDTH, SENSOR_HEIGHT));
+        shadowCharacteristics0.set(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES, new int[] {
+                CaptureResult.CONTROL_AF_MODE_CONTINUOUS_PICTURE,
+                CaptureResult.CONTROL_AF_MODE_AUTO,
+                CaptureResult.CONTROL_AF_MODE_OFF
+        });
+        shadowCharacteristics0.set(CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES, new int[] {
+                CaptureResult.CONTROL_AE_MODE_ON,
+                CaptureResult.CONTROL_AE_MODE_ON_ALWAYS_FLASH,
+                CaptureResult.CONTROL_AE_MODE_ON_AUTO_FLASH,
+                CaptureResult.CONTROL_AE_MODE_OFF
+        });
+        shadowCharacteristics0.set(CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES, new int[] {
+                CaptureResult.CONTROL_AWB_MODE_AUTO,
+                CaptureResult.CONTROL_AWB_MODE_OFF,
+        });
+
+        // Add the camera to the camera service
+        ((ShadowCameraManager)
+                Shadow.extract(
+                        ApplicationProvider.getApplicationContext()
+                                .getSystemService(Context.CAMERA_SERVICE)))
+                .addCamera(CAMERA0_ID, characteristics0);
+
+        // **** Camera 0 characteristics ****//
+        CameraCharacteristics characteristics1 =
+                ShadowCameraCharacteristics.newCameraCharacteristics();
+
+        ShadowCameraCharacteristics shadowCharacteristics1 = Shadow.extract(characteristics1);
+
+        shadowCharacteristics1.set(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE,
+                new Rect(0, 0, SENSOR_WIDTH2, SENSOR_HEIGHT2));
+        // Add the camera to the camera service
+        ((ShadowCameraManager)
+                Shadow.extract(
+                        ApplicationProvider.getApplicationContext()
+                                .getSystemService(Context.CAMERA_SERVICE)))
+                .addCamera(CAMERA1_ID, characteristics1);
+
+    }
+
+    private MeteringRectangle[] getAfRects(FocusMeteringControl control) {
+        Camera2Config.Builder configBuilder = new Camera2Config.Builder();
+        control.addFocusMeteringOptions(configBuilder);
+        Camera2Config config = configBuilder.build();
+
+        return config.getCaptureRequestOption(CaptureRequest.CONTROL_AF_REGIONS,
+                new MeteringRectangle[]{});
+    }
+
+    private MeteringRectangle[] getAeRects(FocusMeteringControl control) {
+        Camera2Config.Builder configBuilder = new Camera2Config.Builder();
+        control.addFocusMeteringOptions(configBuilder);
+        Camera2Config config = configBuilder.build();
+
+        return config.getCaptureRequestOption(CaptureRequest.CONTROL_AE_REGIONS,
+                new MeteringRectangle[]{});
+    }
+
+    private MeteringRectangle[] getAwbRects(FocusMeteringControl control) {
+        Camera2Config.Builder configBuilder = new Camera2Config.Builder();
+        control.addFocusMeteringOptions(configBuilder);
+        Camera2Config config = configBuilder.build();
+
+        return config.getCaptureRequestOption(CaptureRequest.CONTROL_AWB_REGIONS,
+                new MeteringRectangle[]{});
+    }
+
+    @Test
+    public void startFocusAndMetering_defaultPoint_3ARectssAreCorrect() {
+        mFocusMeteringControl.startFocusAndMetering(
+                FocusMeteringAction.Builder.from(mPoint1).build(),
+                mPreviewAspectRatio4X3);
+
+        MeteringRectangle[] afRects = getAfRects(mFocusMeteringControl);
+        MeteringRectangle[] aeRects = getAeRects(mFocusMeteringControl);
+        MeteringRectangle[] awbRects = getAwbRects(mFocusMeteringControl);
+
+        assertThat(afRects.length).isEqualTo(1);
+        assertThat(afRects[0].getRect()).isEqualTo(mMRect1);
+        assertThat(aeRects.length).isEqualTo(1);
+        assertThat(aeRects[0].getRect()).isEqualTo(mMRect1);
+        assertThat(awbRects.length).isEqualTo(1);
+        assertThat(awbRects[0].getRect()).isEqualTo(mMRect1);
+    }
+
+    @Test
+    public void startFocusAndMetering_multiplePoint_3ARectsAreCorrect() {
+        mFocusMeteringControl.startFocusAndMetering(
+                FocusMeteringAction.Builder.from(mPoint1)
+                        .addPoint(mPoint2)
+                        .addPoint(mPoint3)
+                        .build(), mPreviewAspectRatio4X3);
+
+        MeteringRectangle[] afRects = getAfRects(mFocusMeteringControl);
+        MeteringRectangle[] aeRects = getAeRects(mFocusMeteringControl);
+        MeteringRectangle[] awbRects = getAwbRects(mFocusMeteringControl);
+
+        assertThat(afRects.length).isEqualTo(3);
+        assertThat(afRects[0].getRect()).isEqualTo(mMRect1);
+        assertThat(afRects[1].getRect()).isEqualTo(mMRect2);
+        assertThat(afRects[2].getRect()).isEqualTo(mMRect3);
+
+        assertThat(aeRects.length).isEqualTo(3);
+        assertThat(aeRects[0].getRect()).isEqualTo(mMRect1);
+        assertThat(aeRects[1].getRect()).isEqualTo(mMRect2);
+        assertThat(aeRects[2].getRect()).isEqualTo(mMRect3);
+
+        assertThat(awbRects.length).isEqualTo(3);
+        assertThat(awbRects[0].getRect()).isEqualTo(mMRect1);
+        assertThat(awbRects[1].getRect()).isEqualTo(mMRect2);
+        assertThat(awbRects[2].getRect()).isEqualTo(mMRect3);
+    }
+
+    @Test
+    public void startFocusAndMetering_multiplePointVariousModes() {
+        mFocusMeteringControl.startFocusAndMetering(
+                FocusMeteringAction.Builder.from(mPoint1, FocusMeteringAction.MeteringMode.AWB_ONLY)
+                        .addPoint(mPoint2, FocusMeteringAction.MeteringMode.AF_AE)
+                        .addPoint(mPoint3, FocusMeteringAction.MeteringMode.AF_AE_AWB)
+                        .build(), mPreviewAspectRatio4X3);
+
+        MeteringRectangle[] afRects = getAfRects(mFocusMeteringControl);
+        MeteringRectangle[] aeRects = getAeRects(mFocusMeteringControl);
+        MeteringRectangle[] awbRects = getAwbRects(mFocusMeteringControl);
+
+        assertThat(afRects.length).isEqualTo(2);
+        assertThat(afRects[0].getRect()).isEqualTo(mMRect2);
+        assertThat(afRects[1].getRect()).isEqualTo(mMRect3);
+
+        assertThat(aeRects.length).isEqualTo(2);
+        assertThat(aeRects[0].getRect()).isEqualTo(mMRect2);
+        assertThat(aeRects[1].getRect()).isEqualTo(mMRect3);
+
+        assertThat(awbRects.length).isEqualTo(2);
+        assertThat(awbRects[0].getRect()).isEqualTo(mMRect1);
+        assertThat(awbRects[1].getRect()).isEqualTo(mMRect3);
+    }
+
+    @Test
+    public void startFocusAndMetering_multiplePointVariousModes2() {
+        mFocusMeteringControl.startFocusAndMetering(
+                FocusMeteringAction.Builder.from(mPoint1, FocusMeteringAction.MeteringMode.AF_ONLY)
+                        .addPoint(mPoint2, FocusMeteringAction.MeteringMode.AWB_ONLY)
+                        .addPoint(mPoint3, FocusMeteringAction.MeteringMode.AE_ONLY)
+                        .build(), mPreviewAspectRatio4X3);
+        MeteringRectangle[] afRects = getAfRects(mFocusMeteringControl);
+        MeteringRectangle[] aeRects = getAeRects(mFocusMeteringControl);
+        MeteringRectangle[] awbRects = getAwbRects(mFocusMeteringControl);
+
+        assertThat(afRects.length).isEqualTo(1);
+        assertThat(afRects[0].getRect()).isEqualTo(mMRect1);
+
+        assertThat(aeRects.length).isEqualTo(1);
+        assertThat(aeRects[0].getRect()).isEqualTo(mMRect3);
+
+        assertThat(awbRects.length).isEqualTo(1);
+        assertThat(awbRects[0].getRect()).isEqualTo(mMRect2);
+    }
+
+    @Test
+    public void cropRegionIsSet_resultBasedOnCropRegion() {
+        final int cropWidth = 480;
+        final int cropHeight = 360;
+        Rect cropRect = new Rect(SENSOR_WIDTH / 2 - cropWidth / 2,
+                SENSOR_HEIGHT / 2 - cropHeight / 2,
+                SENSOR_WIDTH / 2 + cropWidth / 2, SENSOR_HEIGHT / 2 + cropHeight / 2);
+        when(mCamera2CameraControl.getCropSensorRegion()).thenReturn(cropRect);
+
+        MeteringPoint centorPt = mPointFactory.createPoint(0.5f, 0.5f);
+        mFocusMeteringControl.startFocusAndMetering(
+                FocusMeteringAction.Builder.from(centorPt).build(),
+                mPreviewAspectRatio4X3);
+        MeteringRectangle[] afRects = getAfRects(mFocusMeteringControl);
+
+        final int areaWidth = (int) (MeteringPointFactory.DEFAULT_AREASIZE * cropRect.width());
+        final int areaHeight = (int) (MeteringPointFactory.DEFAULT_AREASIZE * cropRect.height());
+        Rect adjustedRect = new Rect(cropRect.centerX() - areaWidth / 2,
+                cropRect.centerY() - areaHeight / 2,
+                cropRect.centerX() + areaWidth / 2,
+                cropRect.centerY() + areaHeight / 2);
+
+        assertThat(afRects[0].getRect()).isEqualTo(adjustedRect);
+    }
+
+    @Test
+    public void previewFovAdjusted_16by9_to_4by3() {
+        // use 16:9 preview aspect ratio
+        Rational previewAspectRatio = new Rational(16, 9);
+        mFocusMeteringControl.startFocusAndMetering(
+                FocusMeteringAction.Builder.from(mPoint1).build(),
+                previewAspectRatio);
+        MeteringRectangle[] afRects = getAfRects(mFocusMeteringControl);
+
+
+        Rect adjustedRect = new Rect(0, 60 - AREA_HEIGHT / 2, AREA_WIDTH / 2, 60 + AREA_HEIGHT / 2);
+        assertThat(afRects[0].getRect()).isEqualTo(adjustedRect);
+    }
+
+    @Test
+    public void previewFovAdjusted_4by3_to_16by9()
+            throws CameraAccessException {
+        //Camera1 sensor region is 16:9
+        mFocusMeteringControl = initFocusMeteringControl(CAMERA1_ID);
+
+        mFocusMeteringControl.startFocusAndMetering(
+                FocusMeteringAction.Builder.from(mPoint1).build(),
+                mPreviewAspectRatio4X3);
+        MeteringRectangle[] afRects = getAfRects(mFocusMeteringControl);
+
+        Rect adjustedRect = new Rect(240 - AREA_WIDTH2 / 2, 0, 240 + AREA_WIDTH2 / 2,
+                AREA_HEIGHT2 / 2);
+        assertThat(afRects[0].getRect()).isEqualTo(adjustedRect);
+    }
+
+    @Test
+    public void customFovAdjusted() {
+        // 16:9 to 4:3
+        ImageAnalysis imageAnalysis = Mockito.mock(ImageAnalysis.class);
+        when(imageAnalysis.getAttachedSurfaceResolution(any())).thenReturn(
+                new Size(1920, 1080));
+        when(imageAnalysis.getAttachedCameraIds()).thenReturn(Sets.newHashSet(CAMERA0_ID));
+
+        SensorOrientedMeteringPointFactory factory =
+                new SensorOrientedMeteringPointFactory(1.0f, 1.0f, imageAnalysis);
+
+        MeteringPoint point = factory.createPoint(0, 0);
+        mFocusMeteringControl.startFocusAndMetering(FocusMeteringAction.Builder.from(point).build(),
+                mPreviewAspectRatio4X3);
+        MeteringRectangle[] afRects = getAfRects(mFocusMeteringControl);
+
+
+        Rect adjustedRect = new Rect(0, 60 - AREA_HEIGHT / 2, AREA_WIDTH / 2, 60 + AREA_HEIGHT / 2);
+        assertThat(afRects[0].getRect()).isEqualTo(adjustedRect);
+    }
+
+    @Test
+    public void weight_ConvertedCorrect() {
+        MeteringPoint point1 = mPointFactory.createPoint(0, 0, 0.2f, 1.0f);
+        MeteringPoint point2 = mPointFactory.createPoint(0, 0, 0.2f, 0.5f);
+        MeteringPoint point3 = mPointFactory.createPoint(0, 0, 0.2f, 0.1f);
+
+        mFocusMeteringControl.startFocusAndMetering(FocusMeteringAction.Builder.from(point1)
+                .addPoint(point2)
+                .addPoint(point3).build(), mPreviewAspectRatio4X3);
+        MeteringRectangle[] afRects = getAfRects(mFocusMeteringControl);
+
+        assertThat(afRects.length).isEqualTo(3);
+        assertThat(afRects[0].getMeteringWeight()).isEqualTo(
+                (int) (MeteringRectangle.METERING_WEIGHT_MAX * 1.0f));
+        assertThat(afRects[1].getMeteringWeight()).isEqualTo(
+                (int) (MeteringRectangle.METERING_WEIGHT_MAX * 0.5f));
+        assertThat(afRects[2].getMeteringWeight()).isEqualTo(
+                (int) (MeteringRectangle.METERING_WEIGHT_MAX * 0.1f));
+    }
+
+    @Test
+    public void invalidWeight_ConvertedCorrect() {
+        MeteringPoint point1 = mPointFactory.createPoint(0, 0, 0.2f, 1.1f);
+        MeteringPoint point2 = mPointFactory.createPoint(0, 0, 0.2f, -0.3f);
+        MeteringPoint point3 = mPointFactory.createPoint(0, 0, 0.2f, 90000f);
+
+        mFocusMeteringControl.startFocusAndMetering(FocusMeteringAction.Builder.from(point1)
+                .addPoint(point2)
+                .addPoint(point3).build(), mPreviewAspectRatio4X3);
+        MeteringRectangle[] afRects = getAfRects(mFocusMeteringControl);
+
+        assertThat(afRects.length).isEqualTo(3);
+        assertThat(afRects[0].getMeteringWeight()).isEqualTo(
+                MeteringRectangle.METERING_WEIGHT_MAX);
+        assertThat(afRects[1].getMeteringWeight()).isEqualTo(
+                MeteringRectangle.METERING_WEIGHT_MIN);
+        assertThat(afRects[2].getMeteringWeight()).isEqualTo(
+                MeteringRectangle.METERING_WEIGHT_MAX);
+    }
+
+    @Test
+    public void pointSize_ConvertedCorrect() {
+        MeteringPoint point1 = mPointFactory.createPoint(0.5f, 0.5f, 1.0f, 1.0f);
+        MeteringPoint point2 = mPointFactory.createPoint(0.5f, 0.5f, 0.5f, 1.0f);
+        MeteringPoint point3 = mPointFactory.createPoint(0.5f, 0.5f, 0.1f, 1.0f);
+
+        mFocusMeteringControl.startFocusAndMetering(FocusMeteringAction.Builder.from(point1)
+                .addPoint(point2)
+                .addPoint(point3).build(), mPreviewAspectRatio4X3);
+        MeteringRectangle[] afRects = getAfRects(mFocusMeteringControl);
+
+        assertThat(afRects.length).isEqualTo(3);
+        assertThat(afRects[0].getWidth()).isEqualTo(
+                (int) (SENSOR_WIDTH * 1.0f));
+        assertThat(afRects[0].getHeight()).isEqualTo(
+                (int) (SENSOR_HEIGHT * 1.0f));
+
+        assertThat(afRects[1].getWidth()).isEqualTo(
+                (int) (SENSOR_WIDTH * 0.5f));
+        assertThat(afRects[1].getHeight()).isEqualTo(
+                (int) (SENSOR_HEIGHT * 0.5f));
+
+        assertThat(afRects[2].getWidth()).isEqualTo(
+                (int) (SENSOR_WIDTH * 0.1f));
+        assertThat(afRects[2].getHeight()).isEqualTo(
+                (int) (SENSOR_HEIGHT * 0.1f));
+    }
+
+    @Test
+    public void withAFPoints_AFIsTriggered() {
+        mFocusMeteringControl.startFocusAndMetering(FocusMeteringAction.Builder.from(mPoint1,
+                FocusMeteringAction.MeteringMode.AF_AE_AWB).build(), mPreviewAspectRatio4X3);
+
+        verify(mFocusMeteringControl).triggerAf();
+        Mockito.reset(mFocusMeteringControl);
+
+        mFocusMeteringControl.startFocusAndMetering(
+                FocusMeteringAction.Builder.from(mPoint1,
+                        FocusMeteringAction.MeteringMode.AF_ONLY).build(),
+                mPreviewAspectRatio4X3);
+        verify(mFocusMeteringControl).triggerAf();
+        Mockito.reset(mFocusMeteringControl);
+
+        mFocusMeteringControl.startFocusAndMetering(
+                FocusMeteringAction.Builder.from(mPoint1,
+                        FocusMeteringAction.MeteringMode.AF_AE).build(),
+                mPreviewAspectRatio4X3);
+        verify(mFocusMeteringControl).triggerAf();
+        Mockito.reset(mFocusMeteringControl);
+
+        mFocusMeteringControl.startFocusAndMetering(
+                FocusMeteringAction.Builder.from(mPoint1,
+                        FocusMeteringAction.MeteringMode.AF_AWB).build(),
+                mPreviewAspectRatio4X3);
+        verify(mFocusMeteringControl).triggerAf();
+        Mockito.reset(mFocusMeteringControl);
+    }
+
+    @Test
+    public void withoutAFPoints_AFIsNotTriggered() {
+        mFocusMeteringControl.startFocusAndMetering(FocusMeteringAction.Builder.from(mPoint1,
+                FocusMeteringAction.MeteringMode.AE_ONLY).build(), mPreviewAspectRatio4X3);
+        verify(mFocusMeteringControl, never()).triggerAf();
+        Mockito.reset(mFocusMeteringControl);
+
+        mFocusMeteringControl.startFocusAndMetering(
+                FocusMeteringAction.Builder.from(mPoint1,
+                        FocusMeteringAction.MeteringMode.AWB_ONLY).build(),
+                mPreviewAspectRatio4X3);
+        verify(mFocusMeteringControl, never()).triggerAf();
+        Mockito.reset(mFocusMeteringControl);
+
+        mFocusMeteringControl.startFocusAndMetering(
+                FocusMeteringAction.Builder.from(mPoint1,
+                        FocusMeteringAction.MeteringMode.AE_ONLY).build(),
+                mPreviewAspectRatio4X3);
+        verify(mFocusMeteringControl, never()).triggerAf();
+        Mockito.reset(mFocusMeteringControl);
+
+        mFocusMeteringControl.startFocusAndMetering(
+                FocusMeteringAction.Builder.from(mPoint1,
+                        FocusMeteringAction.MeteringMode.AE_AWB).build(),
+                mPreviewAspectRatio4X3);
+        verify(mFocusMeteringControl, never()).triggerAf();
+        Mockito.reset(mFocusMeteringControl);
+    }
+
+    @Test
+    public void updateSessionConfigIsCalled() {
+        mFocusMeteringControl.startFocusAndMetering(
+                FocusMeteringAction.Builder.from(mPoint1).build(),
+                mPreviewAspectRatio4X3);
+
+        verify(mCamera2CameraControl, times(1)).updateSessionConfig();
+    }
+
+    @Test
+    public void autoCancelDuration_cancelIsCalled() throws InterruptedException {
+        mFocusMeteringControl = spy(mFocusMeteringControl);
+        final long autocancelDuration = 500;
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1)
+                .setAutoCancelDuration(autocancelDuration, TimeUnit.MILLISECONDS)
+                .build();
+
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+
+        // This is necessary for running delayed task in robolectric.
+        ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
+        verify(mFocusMeteringControl, timeout(action.getAutoCancelDurationInMs()))
+                .cancelFocusAndMetering();
+    }
+
+    @Test
+    public void autoCancelDurationDisabled_cancelIsNotCalled() throws InterruptedException {
+        mFocusMeteringControl = spy(mFocusMeteringControl);
+        final long autocancelDuration = 500;
+
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1)
+                .setAutoCancelDuration(autocancelDuration, TimeUnit.MILLISECONDS)
+                .disableAutoCancel()
+                .build();
+
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+
+        // This is necessary for running delayed task in robolectric.
+        ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
+        Thread.sleep(autocancelDuration);
+        verify(mFocusMeteringControl, never()).cancelFocusAndMetering();
+    }
+
+    @Test
+    public void onAutoFocusListener_cancelImmediately_calledWithFalse() {
+        FocusMeteringAction.OnAutoFocusListener onAutoFocusListener = mock(
+                FocusMeteringAction.OnAutoFocusListener.class);
+
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1)
+                .setAutoFocusCallback(onAutoFocusListener)
+                .build();
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+        mFocusMeteringControl.cancelFocusAndMetering();
+
+        verify(onAutoFocusListener).onFocusCompleted(false);
+    }
+
+    @Test
+    public void onAutoFocusListener_AFNotTriggered_calledWithFalse() {
+        FocusMeteringAction.OnAutoFocusListener onAutoFocusListener = mock(
+                FocusMeteringAction.OnAutoFocusListener.class);
+
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
+                FocusMeteringAction.MeteringMode.AE_AWB)
+                .setAutoFocusCallback(onAutoFocusListener)
+                .build();
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+
+        verify(onAutoFocusListener).onFocusCompleted(false);
+        Mockito.reset(onAutoFocusListener);
+
+        action = FocusMeteringAction.Builder.from(mPoint1,
+                FocusMeteringAction.MeteringMode.AE_ONLY)
+                .setAutoFocusCallback(onAutoFocusListener)
+                .build();
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+        verify(onAutoFocusListener).onFocusCompleted(false);
+        Mockito.reset(onAutoFocusListener);
+
+        action = FocusMeteringAction.Builder.from(mPoint1,
+                FocusMeteringAction.MeteringMode.AWB_ONLY)
+                .setAutoFocusCallback(onAutoFocusListener)
+                .build();
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+        verify(onAutoFocusListener).onFocusCompleted(false);
+        Mockito.reset(onAutoFocusListener);
+    }
+
+    @Test
+    public void onAutoFocusListener_AFLocked_calledWithTrue() {
+        FocusMeteringAction.OnAutoFocusListener onAutoFocusListener = mock(
+                FocusMeteringAction.OnAutoFocusListener.class);
+
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1)
+                .setAutoFocusCallback(onAutoFocusListener)
+                .build();
+
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+
+        for (CaptureResultListener listener :
+                mCamera2CameraControl.mSessionCallback.mResultListeners) {
+            TotalCaptureResult result1 = mock(TotalCaptureResult.class);
+            when(result1.get(CaptureResult.CONTROL_AF_STATE)).thenReturn(
+                    CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN);
+            listener.onCaptureResult(result1);
+
+            TotalCaptureResult result2 = mock(TotalCaptureResult.class);
+            when(result2.get(CaptureResult.CONTROL_AF_STATE)).thenReturn(
+                    CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED);
+            listener.onCaptureResult(result2);
+
+        }
+        verify(onAutoFocusListener).onFocusCompleted(true);
+    }
+
+    @Test
+    public void onAutoFocusListener_executorSpecified_calledWithTheExecutor() {
+        FocusMeteringAction.OnAutoFocusListener onAutoFocusListener = mock(
+                FocusMeteringAction.OnAutoFocusListener.class);
+
+        Executor executor = spy(new Executor() {
+            @Override
+            public void execute(@NonNull Runnable runnable) {
+                runnable.run();
+            }
+        });
+
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1)
+                .setAutoFocusCallback(executor, onAutoFocusListener)
+                .build();
+
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+        for (CaptureResultListener listener :
+                mCamera2CameraControl.mSessionCallback.mResultListeners) {
+            TotalCaptureResult result1 = mock(TotalCaptureResult.class);
+            when(result1.get(CaptureResult.CONTROL_AF_STATE)).thenReturn(
+                    CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN);
+            listener.onCaptureResult(result1);
+
+            TotalCaptureResult result2 = mock(TotalCaptureResult.class);
+            when(result2.get(CaptureResult.CONTROL_AF_STATE)).thenReturn(
+                    CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED);
+            listener.onCaptureResult(result2);
+
+        }
+
+        verify(onAutoFocusListener).onFocusCompleted(true);
+        verify(executor).execute(any());
+    }
+
+    @Test
+    public void onAutoFocusListener_NotAFLocked_calledWithFalse() {
+        FocusMeteringAction.OnAutoFocusListener onAutoFocusListener = mock(
+                FocusMeteringAction.OnAutoFocusListener.class);
+
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1)
+                .setAutoFocusCallback(onAutoFocusListener)
+                .build();
+
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+
+        for (CaptureResultListener listener :
+                mCamera2CameraControl.mSessionCallback.mResultListeners) {
+            TotalCaptureResult result1 = mock(TotalCaptureResult.class);
+            when(result1.get(CaptureResult.CONTROL_AF_STATE)).thenReturn(
+                    CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN);
+            listener.onCaptureResult(result1);
+
+            TotalCaptureResult result2 = mock(TotalCaptureResult.class);
+            when(result2.get(CaptureResult.CONTROL_AF_STATE)).thenReturn(
+                    CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+            listener.onCaptureResult(result2);
+
+        }
+        verify(onAutoFocusListener).onFocusCompleted(false);
+    }
+
+    @Test
+    public void onAutoFocusListener_isCalledOnce() {
+        FocusMeteringAction.OnAutoFocusListener onAutoFocusListener = mock(
+                FocusMeteringAction.OnAutoFocusListener.class);
+
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1)
+                .setAutoFocusCallback(onAutoFocusListener)
+                .build();
+
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+
+        for (CaptureResultListener listener :
+                mCamera2CameraControl.mSessionCallback.mResultListeners) {
+            TotalCaptureResult result1 = mock(TotalCaptureResult.class);
+            when(result1.get(CaptureResult.CONTROL_AF_STATE)).thenReturn(
+                    CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN);
+            listener.onCaptureResult(result1);
+
+            TotalCaptureResult result2 = mock(TotalCaptureResult.class);
+            when(result2.get(CaptureResult.CONTROL_AF_STATE)).thenReturn(
+                    CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED);
+            listener.onCaptureResult(result2);
+
+        }
+
+        // cancel it and then ensure the OnAutoFocusListener is still called once.
+        mFocusMeteringControl.cancelFocusAndMetering();
+
+        verify(onAutoFocusListener, times(1)).onFocusCompleted(anyBoolean());
+    }
+
+
+    @Test
+    public void cancelFocusAndMetering_regionIsReset() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
+                FocusMeteringAction.MeteringMode.AF_AE_AWB)
+                .addPoint(mPoint2, FocusMeteringAction.MeteringMode.AF_AE_AWB)
+                .build();
+
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+        MeteringRectangle[] afRects = getAfRects(mFocusMeteringControl);
+        MeteringRectangle[] aeRects = getAeRects(mFocusMeteringControl);
+        MeteringRectangle[] awbRects = getAwbRects(mFocusMeteringControl);
+
+        assertThat(afRects).hasLength(2);
+        assertThat(aeRects).hasLength(2);
+        assertThat(awbRects).hasLength(2);
+
+        mFocusMeteringControl.cancelFocusAndMetering();
+        afRects = getAfRects(mFocusMeteringControl);
+        aeRects = getAeRects(mFocusMeteringControl);
+        awbRects = getAwbRects(mFocusMeteringControl);
+
+        assertThat(afRects).hasLength(0);
+        assertThat(aeRects).hasLength(0);
+        assertThat(awbRects).hasLength(0);
+    }
+
+
+    @Test
+    public void cancelFocusAndMetering_updateSessionIsCalled() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
+                FocusMeteringAction.MeteringMode.AF_AE_AWB)
+                .addPoint(mPoint2, FocusMeteringAction.MeteringMode.AF_AE_AWB)
+                .build();
+
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+        Mockito.reset(mCamera2CameraControl);
+
+        mFocusMeteringControl.cancelFocusAndMetering();
+        verify(mCamera2CameraControl, times(1)).updateSessionConfig();
+    }
+
+
+    @Test
+    public void cancelFocusAndMetering_triggerCancelAfProperly() {
+        // If AF is enabled, cancel operation needs to call cancelAfAeTriggerInternal(true, false)
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
+                FocusMeteringAction.MeteringMode.AF_AE_AWB)
+                .build();
+
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+        Mockito.reset(mFocusMeteringControl);
+        mFocusMeteringControl.cancelFocusAndMetering();
+        verify(mFocusMeteringControl, times(1)).cancelAfAeTrigger(true, false);
+
+        action = FocusMeteringAction.Builder.from(mPoint1, FocusMeteringAction.MeteringMode.AF_AE)
+                .build();
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+        Mockito.reset(mFocusMeteringControl);
+        mFocusMeteringControl.cancelFocusAndMetering();
+        verify(mFocusMeteringControl, times(1)).cancelAfAeTrigger(true, false);
+
+        action = FocusMeteringAction.Builder.from(mPoint1, FocusMeteringAction.MeteringMode.AF_AWB)
+                .build();
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+        Mockito.reset(mFocusMeteringControl);
+        mFocusMeteringControl.cancelFocusAndMetering();
+        verify(mFocusMeteringControl, times(1)).cancelAfAeTrigger(true, false);
+
+        action = FocusMeteringAction.Builder.from(mPoint1, FocusMeteringAction.MeteringMode.AF_ONLY)
+                .build();
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+        Mockito.reset(mFocusMeteringControl);
+        mFocusMeteringControl.cancelFocusAndMetering();
+        verify(mFocusMeteringControl, times(1)).cancelAfAeTrigger(true, false);
+    }
+
+    @Test
+    public void cancelFocusAndMetering_AFNotInvolved_cancelAfNotTriggered() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
+                FocusMeteringAction.MeteringMode.AE_ONLY)
+                .build();
+
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+        Mockito.reset(mFocusMeteringControl);
+        mFocusMeteringControl.cancelFocusAndMetering();
+        verify(mFocusMeteringControl, never()).cancelAfAeTrigger(true, false);
+
+        action = FocusMeteringAction.Builder.from(mPoint1,
+                FocusMeteringAction.MeteringMode.AWB_ONLY)
+                .build();
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+        Mockito.reset(mFocusMeteringControl);
+        mFocusMeteringControl.cancelFocusAndMetering();
+        verify(mFocusMeteringControl, never()).cancelAfAeTrigger(true, false);
+
+        action = FocusMeteringAction.Builder.from(mPoint1, FocusMeteringAction.MeteringMode.AE_AWB)
+                .build();
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+        Mockito.reset(mFocusMeteringControl);
+        mFocusMeteringControl.cancelFocusAndMetering();
+        verify(mFocusMeteringControl, never()).cancelAfAeTrigger(true, false);
+    }
+
+    @Test
+    public void cancelFocusAndMetering_autoCancelIsDisabled() throws InterruptedException {
+        mFocusMeteringControl = spy(mFocusMeteringControl);
+        final long autocancelDuration = 500;
+
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1)
+                .setAutoCancelDuration(autocancelDuration, TimeUnit.MILLISECONDS)
+                .build();
+
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+        mFocusMeteringControl.cancelFocusAndMetering();
+        Mockito.reset(mFocusMeteringControl);
+
+        // This is necessary for running delayed task in robolectric.
+        ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
+        Thread.sleep(autocancelDuration);
+
+        verify(mFocusMeteringControl, never()).cancelFocusAndMetering();
+    }
+
+    @Test
+    public void startFocusMetering_isAfAutoModeIsTrue() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1).build();
+
+        verifyAfMode(CaptureResult.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+
+        verifyAfMode(CaptureResult.CONTROL_AF_MODE_AUTO);
+    }
+
+    private void verifyAfMode(int expectAfMode) {
+        Camera2Config.Builder builder1 = new Camera2Config.Builder();
+        mFocusMeteringControl.addFocusMeteringOptions(builder1);
+        assertThat(builder1.build().getCaptureRequestOption(CaptureRequest.CONTROL_AF_MODE, null))
+                .isEqualTo(expectAfMode);
+    }
+
+    @Test
+    public void startFocusMetering_AfNotInvolved_isAfAutoModeIsSet() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
+                FocusMeteringAction.MeteringMode.AE_AWB).build();
+
+        verifyAfMode(CaptureResult.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+        verifyAfMode(CaptureResult.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+    }
+
+    @Test
+    public void startAndThenCancel_isAfAutoModeIsFalse() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1).build();
+        mFocusMeteringControl.startFocusAndMetering(action, mPreviewAspectRatio4X3);
+        mFocusMeteringControl.cancelFocusAndMetering();
+        verifyAfMode(CaptureResult.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+    }
+
+}
diff --git a/camera/camera-core/lint-baseline.xml b/camera/camera-core/lint-baseline.xml
index 427bce4b..71a8477 100644
--- a/camera/camera-core/lint-baseline.xml
+++ b/camera/camera-core/lint-baseline.xml
@@ -3315,28 +3315,6 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="                UseCaseError useCaseError, String message, @Nullable Throwable cause) {"
-        errorLine2="                ~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/camera/core/ImageCapture.java"
-            line="1031"
-            column="17"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="                UseCaseError useCaseError, String message, @Nullable Throwable cause) {"
-        errorLine2="                                           ~~~~~~">
-        <location
-            file="src/main/java/androidx/camera/core/ImageCapture.java"
-            line="1031"
-            column="44"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
         errorLine1="        public ImageCaptureConfig getConfig(LensFacing lensFacing) {"
         errorLine2="               ~~~~~~~~~~~~~~~~~~">
         <location
@@ -7033,28 +7011,6 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="        void onError(UseCaseError useCaseError, String message, @Nullable Throwable cause);"
-        errorLine2="                     ~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/camera/core/VideoCapture.java"
-            line="865"
-            column="22"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="        void onError(UseCaseError useCaseError, String message, @Nullable Throwable cause);"
-        errorLine2="                                                ~~~~~~">
-        <location
-            file="src/main/java/androidx/camera/core/VideoCapture.java"
-            line="865"
-            column="49"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
         errorLine1="        public VideoCaptureConfig getConfig(LensFacing lensFacing) {"
         errorLine2="               ~~~~~~~~~~~~~~~~~~">
         <location
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/BaseCamera.java b/camera/camera-core/src/main/java/androidx/camera/core/BaseCamera.java
index 8c7d14a..2e953de 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/BaseCamera.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/BaseCamera.java
@@ -16,9 +16,12 @@
 
 package androidx.camera.core;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
 
+import com.google.common.util.concurrent.ListenableFuture;
+
 import java.util.Collection;
 
 /**
@@ -30,6 +33,52 @@
 public interface BaseCamera extends UseCase.StateChangeListener,
         CameraControlInternal.ControlUpdateListener {
     /**
+     * The state of a camera within the process.
+     *
+     * <p>The camera state is used to communicate events like when the camera is opening or
+     * closing and can be used to determine when it is safe to interact with the camera.
+     */
+    enum State {
+        /**
+         * Camera is waiting for resources to become available before opening.
+         *
+         * <p>The camera will automatically transition to an {@link #OPENING} state once resources
+         * have become available. Resources are typically made available by other cameras closing.
+         */
+        PENDING_OPEN,
+        /**
+         * Camera is in the process of opening.
+         *
+         * <p>This is a transitive state.
+         */
+        OPENING,
+        /**
+         * Camera is open and producing (or ready to produce) image data.
+         */
+        OPEN,
+        /**
+         * Camera is in the process of closing.
+         *
+         * <p>This is a transitive state.
+         */
+        CLOSING,
+        /**
+         * Camera has been closed and should not be producing data.
+         */
+        CLOSED,
+        /**
+         * Camera is in the process of being released and cannot be reopened.
+         *
+         * <p>This is a transitive state.
+         */
+        RELEASING,
+        /**
+         * Camera has been closed and has released all held resources.
+         */
+        RELEASED
+    }
+
+    /**
      * Open the camera asynchronously.
      *
      * <p>Once the camera has been opened use case state transitions can be used to control the
@@ -51,23 +100,32 @@
      * <p>Once the camera is released it is permanently closed. A new instance must be created to
      * access the camera.
      */
-    void release();
+    @NonNull
+    ListenableFuture<Void> release();
+
+    /**
+     * Retrieves an observable stream of the current state of the camera.
+     */
+    @NonNull
+    Observable<State> getCameraState();
 
     /**
      * Sets the use case to be in the state where the capture session will be configured to handle
      * capture requests from the use cases.
      */
-    void addOnlineUseCase(Collection<UseCase> useCases);
+    void addOnlineUseCase(@NonNull Collection<UseCase> useCases);
 
     /**
      * Removes the use case to be in the state where the capture session will be configured to
      * handle capture requests from the use cases.
      */
-    void removeOnlineUseCase(Collection<UseCase> useCases);
+    void removeOnlineUseCase(@NonNull Collection<UseCase> useCases);
 
     /** Returns the global CameraControlInternal attached to this camera. */
+    @NonNull
     CameraControlInternal getCameraControlInternal();
 
     /** Returns an interface to retrieve characteristics of the camera. */
+    @NonNull
     CameraInfo getCameraInfo() throws CameraInfoUnavailableException;
 }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraControl.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraControl.java
index 6d07f6f..f898844 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraControl.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraControl.java
@@ -16,10 +16,33 @@
 
 package androidx.camera.core;
 
+import androidx.annotation.NonNull;
+import androidx.camera.core.FocusMeteringAction.OnAutoFocusListener;
+
 /**
  * An interface for controlling camera's zoom, focus and metering across all use cases.
  *
  * <p>Applications can retrieve the interface via CameraX.getCameraControl.
  */
 public interface CameraControl {
+
+    /**
+     * Starts a focus and metering action by the {@link FocusMeteringAction}.
+     *
+     * The {@link FocusMeteringAction} contains the configuration of multiple 3A
+     * {@link MeteringPoint}s, auto-cancel duration and{@link OnAutoFocusListener} to receive the
+     * auto-focus result. Check {@link FocusMeteringAction} for more details.
+     *
+     * @param action the {@link FocusMeteringAction} to be executed.
+     */
+    void startFocusAndMetering(@NonNull FocusMeteringAction action);
+
+    /**
+     * Cancels current {@link FocusMeteringAction}.
+     *
+     * <p>It clears the 3A regions and update current AF mode to CONTINOUS AF (if supported).
+     * If auto-focus does not completes, it will notify the {@link OnAutoFocusListener} with
+     * isFocusLocked set to false.
+     */
+    void cancelFocusAndMetering();
 }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraControlInternal.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraControlInternal.java
index 1e01a70..5ae32da 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraControlInternal.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraControlInternal.java
@@ -16,7 +16,6 @@
 
 package androidx.camera.core;
 
-import android.annotation.SuppressLint;
 import android.graphics.Rect;
 
 import androidx.annotation.NonNull;
@@ -25,7 +24,6 @@
 import androidx.annotation.RestrictTo.Scope;
 
 import java.util.List;
-import java.util.concurrent.Executor;
 
 /**
  * The CameraControlInternal Interface.
@@ -48,37 +46,6 @@
      */
     void setCropRegion(@Nullable Rect crop);
 
-    /**
-     * Adjusts the camera output according to the properties in some local regions with a callback
-     * called once focus scan has completed.
-     *
-     * <p>The auto-focus (AF), auto-exposure (AE) and auto-whitebalance (AWB) properties will be
-     * recalculated from the local regions.
-     *
-     * @param focus    rectangle with dimensions in sensor coordinate frame for focus
-     * @param metering rectangle with dimensions in sensor coordinate frame for metering
-     * @param executor the executor which will be used to call the listener.
-     * @param listener listener for when focus has completed.
-     */
-    @SuppressLint("LambdaLast")
-    // Remove after https://issuetracker.google.com/135275901
-    void focus(
-            @NonNull Rect focus,
-            @NonNull Rect metering,
-            @NonNull Executor executor,
-            @NonNull OnFocusListener listener);
-
-    /**
-     * Adjusts the camera output according to the properties in some local regions.
-     *
-     * <p>The auto-focus (AF), auto-exposure (AE) and auto-whitebalance (AWB) properties will be
-     * recalculated from the local regions.
-     *
-     * @param focus    rectangle with dimensions in sensor coordinate frame for focus
-     * @param metering rectangle with dimensions in sensor coordinate frame for metering
-     */
-    void focus(@NonNull Rect focus, @NonNull Rect metering);
-
     /** Returns the current flash mode. */
     @NonNull
     FlashMode getFlashMode();
@@ -100,9 +67,6 @@
     /** Returns if current torch is enabled or not. */
     boolean isTorchOn();
 
-    /** Returns if the focus is currently locked or not. */
-    boolean isFocusLocked();
-
     /** Performs a AF trigger. */
     void triggerAf();
 
@@ -122,15 +86,6 @@
         public void setCropRegion(@Nullable Rect crop) {
         }
 
-        @Override
-        public void focus(@NonNull Rect focus, @NonNull Rect metering, @Nullable Executor executor,
-                @Nullable OnFocusListener listener) {
-        }
-
-        @Override
-        public void focus(@NonNull Rect focus, @NonNull Rect metering) {
-        }
-
         @NonNull
         @Override
         public FlashMode getFlashMode() {
@@ -151,11 +106,6 @@
         }
 
         @Override
-        public boolean isFocusLocked() {
-            return false;
-        }
-
-        @Override
         public void triggerAf() {
         }
 
@@ -171,6 +121,16 @@
         @Override
         public void submitCaptureRequests(@NonNull List<CaptureConfig> captureConfigs) {
         }
+
+        @Override
+        public void startFocusAndMetering(@NonNull FocusMeteringAction action) {
+
+        }
+
+        @Override
+        public void cancelFocusAndMetering() {
+
+        }
     };
 
     /** Listener called when CameraControlInternal need to notify event. */
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraRepository.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraRepository.java
index 54e7fad..0bc2aab 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraRepository.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraRepository.java
@@ -63,6 +63,17 @@
             }
         }
     }
+    /**
+     * Clear all cameras from the repository.
+     *
+     * @hide
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    public void clear() {
+        synchronized (mCamerasLock) {
+            mCameras.clear();
+        }
+    }
 
     /**
      * Gets a {@link BaseCamera} for the given id.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraX.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraX.java
index fa8fec7..29bd118 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraX.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraX.java
@@ -405,9 +405,7 @@
      * @return the {@link CameraControl}.
      * @throws CameraInfoUnavailableException if unable to access cameras, perhaps due to
      *                                        insufficient permissions.
-     * @hide
      */
-    @RestrictTo(Scope.LIBRARY_GROUP)
     public static CameraControl getCameraControl(LensFacing lensFacing)
             throws CameraInfoUnavailableException {
 
@@ -488,6 +486,19 @@
     }
 
     /**
+     * Deinitializes CameraX so that it can be initialized again.
+     *
+     * <p>Note: This is only for testing purpose for now.
+     * TODO(b/138544571): Release all cameras in CameraX.deinit
+     *
+     * @hide
+     */
+    @RestrictTo(Scope.TESTS)
+    public static void deinit() {
+        INSTANCE.deinitInternal();
+    }
+
+    /**
      * Returns the context used for CameraX.
      *
      * @hide
@@ -695,6 +706,11 @@
         mCameraRepository.init(mCameraFactory);
     }
 
+    private void deinitInternal() {
+        mInitialized.set(false);
+        mCameraRepository.clear();
+    }
+
     private UseCaseGroupLifecycleController getOrCreateUseCaseGroup(LifecycleOwner lifecycleOwner) {
         return mUseCaseGroupRepository.getOrCreateUseCaseGroup(
                 lifecycleOwner, new UseCaseGroupRepository.UseCaseGroupSetup() {
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/DisplayOrientedMeteringPointFactory.java b/camera/camera-core/src/main/java/androidx/camera/core/DisplayOrientedMeteringPointFactory.java
new file mode 100644
index 0000000..212a14d
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/DisplayOrientedMeteringPointFactory.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2019 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.camera.core;
+
+import android.content.Context;
+import android.graphics.PointF;
+import android.view.Display;
+import android.view.WindowManager;
+
+import androidx.annotation.NonNull;
+import androidx.camera.core.CameraX.LensFacing;
+
+/**
+ * A {@link MeteringPointFactory} that can create {@link MeteringPoint} by display oriented x, y.
+ *
+ * <p>This factory will consider the current display rotation and the lens facing to translate the
+ * x/y correctly. Using this factory, apps do not need to handle the device rotation. They
+ * can simply pass the x/y retrieved from their View. However if the camera preview is cropped,
+ * scaled or rotated, it is apps' duty to transform the coordinates first.
+ *
+ * <p> The width/height of this factory is the logical width/height of the preview FoV and X/Y
+ * is the logical XY inside the FOV. User can set the width and height to 1.0 which will make the
+ * XY the normalized coordinates [0..1].
+ */
+public final class DisplayOrientedMeteringPointFactory extends MeteringPointFactory {
+    /** The logical width of FoV in current display orientation */
+    private final float mWidth;
+    /** The logical height of FoV in current display orientation */
+    private final float mHeight;
+    /** Lens facing is required for correctly adjusted for front camera */
+    private final LensFacing mLensFacing;
+    /** {@link Display} used for detecting display orientation */
+    @NonNull
+    private final Display mDisplay;
+    @NonNull
+    private final CameraInfo mCameraInfo;
+
+    /**
+     * Creates the {@link MeteringPointFactory} with default display orientation.
+     *
+     * <p>The width/height is the logical width/height of the preview FoV and X/Y is the logical
+     * XY inside the FOV. User can set the width and height to 1.0 which will make the XY the
+     * normalized coordinates [0..1]. Or user can set the width/height to the View width/height and
+     * then X/Y becomes the X/Y in the view.
+     *
+     * @param context    context to get the {@link WindowManager} for default display rotation.
+     * @param lensFacing current lens facing.
+     * @param width      the logical width of FoV in current display orientation.
+     * @param height     the logical height of FoV in current display orientation.
+     */
+    public DisplayOrientedMeteringPointFactory(@NonNull Context context,
+            @NonNull LensFacing lensFacing, float width, float height) {
+        this(((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(),
+                lensFacing, width, height);
+    }
+
+    /**
+     * Creates the  {@link MeteringPointFactory}  with custom display orientation. This is used
+     * in multi-display situation.
+     *
+     * <p>The width/height is the logical width/height of the preview FoV and X/Y is the logical
+     * XY inside the FOV. User can set the width and height to 1.0 which will make the XY the
+     * normalized coordinates [0..1]. Or user can set the width/height to the View width/height and
+     * then X/Y becomes the X/Y in the view.
+     * {@link Display} is used to dete
+     * @param display    {@link Display} to get the orientation from.
+     * @param lensFacing current lens facing.
+     * @param width      the logical width of FoV in current display orientation.
+     * @param height     the logical height of FoV in current display orientation.
+     */
+    public DisplayOrientedMeteringPointFactory(@NonNull Display display,
+            @NonNull LensFacing lensFacing, float width, float height) {
+        mWidth = width;
+        mHeight = height;
+        mLensFacing = lensFacing;
+        mDisplay = display;
+        try {
+            String cameraId = CameraX.getCameraWithLensFacing(lensFacing);
+            mCameraInfo = CameraX.getCameraInfo(cameraId);
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Can not find CameraInfo : " + lensFacing);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @NonNull
+    @Override
+    protected PointF translatePoint(float x, float y) {
+        float width = mWidth;
+        float height = mHeight;
+
+        boolean compensateForMirroring = (mLensFacing == LensFacing.FRONT);
+        int relativeCameraOrientation = getRelativeCameraOrientation(compensateForMirroring);
+        float outputX = x;
+        float outputY = y;
+        float outputWidth = width;
+        float outputHeight = height;
+
+        if (relativeCameraOrientation == 90 || relativeCameraOrientation == 270) {
+            // We're horizontal. Swap width/height. Swap x/y.
+            outputX = y;
+            outputY = x;
+            outputWidth = height;
+            outputHeight = width;
+        }
+
+        switch (relativeCameraOrientation) {
+            // Map to correct coordinates according to relativeCameraOrientation
+            case 90:
+                outputY = outputHeight - outputY;
+                break;
+            case 180:
+                outputX = outputWidth - outputX;
+                outputY = outputHeight - outputY;
+                break;
+            case 270:
+                outputX = outputWidth - outputX;
+                break;
+            default:
+                break;
+        }
+
+        // Swap x if it's a mirrored preview
+        if (compensateForMirroring) {
+            outputX = outputWidth - outputX;
+        }
+
+        // Normalized it to [0, 1]
+        outputX = outputX / outputWidth;
+        outputY = outputY / outputHeight;
+
+        return new PointF(outputX, outputY);
+    }
+
+    private int getRelativeCameraOrientation(boolean compensateForMirroring) {
+        int rotationDegrees;
+        try {
+            int displayRotation = mDisplay.getRotation();
+            rotationDegrees = mCameraInfo.getSensorRotationDegrees(displayRotation);
+            if (compensateForMirroring) {
+                rotationDegrees = (360 - rotationDegrees) % 360;
+            }
+        } catch (Exception e) {
+            rotationDegrees = 0;
+        }
+        return rotationDegrees;
+    }
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/FocusMeteringAction.java b/camera/camera-core/src/main/java/androidx/camera/core/FocusMeteringAction.java
new file mode 100644
index 0000000..db1b5b2
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/FocusMeteringAction.java
@@ -0,0 +1,310 @@
+/*
+ * Copyright 2019 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.camera.core;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.annotation.VisibleForTesting;
+import androidx.camera.core.impl.utils.executor.CameraXExecutors;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * A configuration used to trigger a focus and/or metering action.
+ *
+ * <p>To construct a {@link FocusMeteringAction}, apps have to create a {@link Builder} by
+ * {@link Builder#from(MeteringPoint)} or {@link Builder#from(MeteringPoint, MeteringMode)}.
+ * {@link MeteringPoint} is a point used to specify the focus/metering areas. Apps can use various
+ * {@link MeteringPointFactory} to create the points. When the {@link FocusMeteringAction} is built,
+ * pass it to {@link CameraControl#startFocusAndMetering(FocusMeteringAction)} to initiate the focus
+ * and metering action.
+ *
+ * <p>The default {@link MeteringMode} is {@link MeteringMode#AF_AE_AWB} which means the point is
+ * used for all AF/AE/AWB regions. Apps can set the proper {@link MeteringMode} to optionally
+ * exclude some 3A regions. Multiple regions for specific 3A type are also supported via
+ * {@link Builder#addPoint(MeteringPoint)} or
+ * {@link Builder#addPoint(MeteringPoint, MeteringMode)}. App can also this API to enable
+ * different region for AF and AE respectively.
+ *
+ * <p>If any AF points are specified, it will trigger AF to start a manual AF scan and cancel AF
+ * trigger when {@link CameraControl#cancelFocusAndMetering()} is called. When triggering AF is
+ * done, it will call the {@link OnAutoFocusListener#onFocusCompleted(boolean)} which is set via
+ * {@link Builder#setAutoFocusCallback(OnAutoFocusListener)}.  If AF point is not specified or
+ * the action is cancelled before AF is locked, CameraX will call the
+ * {@link OnAutoFocusListener#onFocusCompleted(boolean)} with isFocusLocked set to false.
+ *
+ * <p>App can set a auto-cancel duration to let CameraX call
+ * {@link CameraControl#cancelFocusAndMetering()} automatically in the specified duration. By
+ * default the auto-cancel duration is 5 seconds. Apps can call {@link Builder#disableAutoCancel()}
+ * to disable auto-cancel.
+ */
+public class FocusMeteringAction {
+    static final MeteringMode DEFAULT_METERINGMODE = MeteringMode.AF_AE_AWB;
+    static final long DEFAULT_AUTOCANCEL_DURATION = 5000;
+    private final List<MeteringPoint> mMeteringPointsAF;
+    private final List<MeteringPoint> mMeteringPointsAE;
+    private final List<MeteringPoint> mMeteringPointsAWB;
+    private final Executor mListenerExecutor;
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    final OnAutoFocusListener mOnAutoFocusListener;
+    private final long mAutoCancelDurationInMs;
+    private AtomicBoolean mHasNotifiedListener = new AtomicBoolean(false);
+
+    @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+    FocusMeteringAction(Builder builder) {
+        mMeteringPointsAF = builder.mMeteringPointsAF;
+        mMeteringPointsAE = builder.mMeteringPointsAE;
+        mMeteringPointsAWB = builder.mMeteringPointsAWB;
+        mListenerExecutor = builder.mListenerExecutor;
+        mOnAutoFocusListener = builder.mOnAutoFocusListener;
+        mAutoCancelDurationInMs = builder.mAutoCancelDurationInMs;
+    }
+
+    /**
+     * Returns current {@link OnAutoFocusListener}.
+     */
+    @Nullable
+    public OnAutoFocusListener getOnAutoFocusListener() {
+        return mOnAutoFocusListener;
+    }
+
+    /**
+     * Returns auto-cancel duration.  Returns 0 if auto-cancel is disabled.
+     */
+    public long getAutoCancelDurationInMs() {
+        return mAutoCancelDurationInMs;
+    }
+
+    /**
+     * Returns all {@link MeteringPoint}s used for AF regions.
+     */
+    @NonNull
+    public List<MeteringPoint> getMeteringPointsAF() {
+        return mMeteringPointsAF;
+    }
+
+    /**
+     * Returns all {@link MeteringPoint}s used for AE regions.
+     */
+    @NonNull
+    public List<MeteringPoint> getMeteringPointsAE() {
+        return mMeteringPointsAE;
+    }
+
+    /**
+     * Returns all {@link MeteringPoint}s used for AWB regions.
+     */
+    @NonNull
+    public List<MeteringPoint> getMeteringPointsAWB() {
+        return mMeteringPointsAWB;
+    }
+
+    /**
+     * Returns if auto-cancel is enabled or not.
+     */
+    public boolean isAutoCancelEnabled() {
+        return mAutoCancelDurationInMs != 0;
+    }
+
+    @VisibleForTesting
+    Executor getListenerExecutor() {
+        return mListenerExecutor;
+    }
+
+    /**
+     * Notifies current {@link OnAutoFocusListener} and ensures it is called once.
+     *
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public void notifyAutoFocusCompleted(boolean isFocused) {
+        if (!mHasNotifiedListener.getAndSet(true)) {
+            if (mOnAutoFocusListener != null) {
+                mListenerExecutor.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        mOnAutoFocusListener.onFocusCompleted(isFocused);
+                    }
+                });
+            }
+        }
+    }
+
+    /**
+     * Listener for receiving auto-focus completion event.
+     */
+    public interface OnAutoFocusListener {
+        /**
+         * Called when camera auto focus completes or when the action is cancelled before
+         * auto-focus completes.
+         *
+         * @param isFocusLocked true if focus is locked successfully, false otherwise.
+         */
+        void onFocusCompleted(boolean isFocusLocked);
+    }
+
+    /**
+     * Focus/Metering mode used to specify which 3A regions is activated for corresponding
+     * {@link MeteringPoint}.
+     */
+    public enum MeteringMode {
+        AF_AE_AWB,
+        AF_AE,
+        AE_AWB,
+        AF_AWB,
+        AF_ONLY,
+        AE_ONLY,
+        AWB_ONLY
+    }
+
+    /**
+     * The builder used to create the {@link FocusMeteringAction}. App must use
+     * {@link Builder#from(MeteringPoint)}
+     * or {@link Builder#from(MeteringPoint, MeteringMode)} to create the {@link Builder}.
+     */
+    public static class Builder {
+        @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+        final List<MeteringPoint> mMeteringPointsAF = new ArrayList<>();
+        @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+        final List<MeteringPoint> mMeteringPointsAE = new ArrayList<>();
+        @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+        final List<MeteringPoint> mMeteringPointsAWB = new ArrayList<>();
+        @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+        OnAutoFocusListener mOnAutoFocusListener = null;
+        @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+        Executor mListenerExecutor = CameraXExecutors.mainThreadExecutor();
+        @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+        long mAutoCancelDurationInMs = DEFAULT_AUTOCANCEL_DURATION;
+
+        private Builder(@NonNull MeteringPoint point) {
+            this(point, DEFAULT_METERINGMODE);
+        }
+
+        private Builder(@NonNull MeteringPoint point, @NonNull MeteringMode mode) {
+            addPoint(point, mode);
+        }
+
+        /**
+         * Creates the Builder from a {@link MeteringPoint} with default {@link MeteringMode}.
+         */
+        @NonNull
+        public static Builder from(@NonNull MeteringPoint meteringPoint) {
+            return new Builder(meteringPoint);
+        }
+
+        /**
+         * Creates the Builder from a {@link MeteringPoint} and {@link MeteringMode}
+         */
+        @NonNull
+        public static Builder from(@NonNull MeteringPoint meteringPoint,
+                @NonNull MeteringMode mode) {
+            return new Builder(meteringPoint, mode);
+        }
+
+        /**
+         * Adds another {@link MeteringPoint} with default {@link MeteringMode}.
+         */
+        @NonNull
+        public Builder addPoint(@NonNull MeteringPoint point) {
+            return addPoint(point, DEFAULT_METERINGMODE);
+        }
+
+        /**
+         * Adds another {@link MeteringPoint} with specified {@link MeteringMode}.
+         */
+        @NonNull
+        public Builder addPoint(@NonNull MeteringPoint point, @NonNull MeteringMode mode) {
+            if (mode == MeteringMode.AF_AE_AWB
+                    || mode == MeteringMode.AF_AE
+                    || mode == MeteringMode.AF_AWB
+                    || mode == MeteringMode.AF_ONLY) {
+                mMeteringPointsAF.add(point);
+            }
+
+            if (mode == MeteringMode.AF_AE_AWB
+                    || mode == MeteringMode.AF_AE
+                    || mode == MeteringMode.AE_AWB
+                    || mode == MeteringMode.AE_ONLY) {
+                mMeteringPointsAE.add(point);
+            }
+
+            if (mode == MeteringMode.AF_AE_AWB
+                    || mode == MeteringMode.AE_AWB
+                    || mode == MeteringMode.AF_AWB
+                    || mode == MeteringMode.AWB_ONLY) {
+                mMeteringPointsAWB.add(point);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the {@link OnAutoFocusListener} to be notified when auto-focus completes. The
+         * listener is called on main thread.
+         */
+        @NonNull
+        public Builder setAutoFocusCallback(@NonNull OnAutoFocusListener listener) {
+            mOnAutoFocusListener = listener;
+            return this;
+        }
+
+        /**
+         * Sets the {@link OnAutoFocusListener} to be notified when auto-focus completes. The
+         * listener is called on specified {@link Executor}.
+         */
+        @NonNull
+        public Builder setAutoFocusCallback(@NonNull Executor executor,
+                @NonNull OnAutoFocusListener listener) {
+            mListenerExecutor = executor;
+            mOnAutoFocusListener = listener;
+            return this;
+        }
+
+        /**
+         * Sets the auto-cancel duration. After set, {@link CameraControl#cancelFocusAndMetering()}
+         * will be called in specified duration. By default, auto-cancel is enabled with 5
+         * seconds duration.
+         */
+        @NonNull
+        public Builder setAutoCancelDuration(long duration, @NonNull TimeUnit timeUnit) {
+            mAutoCancelDurationInMs = timeUnit.toMillis(duration);
+            return this;
+        }
+
+        /**
+         * Disables the auto-cancel.
+         */
+        @NonNull
+        public Builder disableAutoCancel() {
+            mAutoCancelDurationInMs = 0;
+            return this;
+        }
+
+        /**
+         * Builds the {@link FocusMeteringAction} instance.
+         */
+        @NonNull
+        public FocusMeteringAction build() {
+            return new FocusMeteringAction(this);
+        }
+
+    }
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysis.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysis.java
index 597356a..506d080 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysis.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysis.java
@@ -63,6 +63,10 @@
     final AtomicInteger mRelativeRotation = new AtomicInteger();
     final Handler mHandler;
     private final ImageAnalysisConfig.Builder mUseCaseConfigBuilder;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    final ImageAnalysisBlockingAnalyzer mImageAnalysisBlockingAnalyzer;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    final ImageAnalysisNonBlockingAnalyzer mImageAnalysisNonBlockingAnalyzer;
     @Nullable
     ImageReaderProxy mImageReader;
     @Nullable
@@ -85,6 +89,14 @@
             throw new IllegalStateException("No default mHandler specified.");
         }
         setImageFormat(ImageReaderFormatRecommender.chooseCombo().imageAnalysisFormat());
+        // Init both instead of lazy loading to void synchronization.
+        mImageAnalysisBlockingAnalyzer = new ImageAnalysisBlockingAnalyzer(mSubscribedAnalyzer,
+                mRelativeRotation,
+                mHandler);
+        mImageAnalysisNonBlockingAnalyzer = new ImageAnalysisNonBlockingAnalyzer(
+                mSubscribedAnalyzer, mRelativeRotation,
+                mHandler, config.getBackgroundExecutor(
+                CameraXExecutors.highPriorityExecutor()));
     }
 
     /**
@@ -209,6 +221,8 @@
                     new DeferrableSurface.OnSurfaceDetachedListener() {
                         @Override
                         public void onSurfaceDetached() {
+                            mImageAnalysisNonBlockingAnalyzer.close();
+                            mImageAnalysisBlockingAnalyzer.close();
                             if (mImageReader != null) {
                                 mImageReader.close();
                                 mImageReader = null;
@@ -277,14 +291,16 @@
 
         tryUpdateRelativeRotation(cameraId);
 
-        ImageReaderProxy.OnImageAvailableListener onImageAvailableListener =
-                config.getImageReaderMode() == ImageReaderMode.ACQUIRE_NEXT_IMAGE
-                        ? new ImageAnalysisBlockingCallback(mSubscribedAnalyzer, mRelativeRotation,
-                        mHandler) :
-                        new ImageAnalysisNonBlockingCallback(mSubscribedAnalyzer, mRelativeRotation,
-                                mHandler, backgroundExecutor);
-        mImageReader.setOnImageAvailableListener(onImageAvailableListener,
-                backgroundExecutor);
+        ImageReaderProxy.OnImageAvailableListener onImageAvailableListener;
+
+        if (config.getImageReaderMode() == ImageReaderMode.ACQUIRE_NEXT_IMAGE) {
+            onImageAvailableListener = mImageAnalysisBlockingAnalyzer;
+            mImageAnalysisBlockingAnalyzer.open();
+        } else {
+            onImageAvailableListener = mImageAnalysisNonBlockingAnalyzer;
+            mImageAnalysisNonBlockingAnalyzer.open();
+        }
+        mImageReader.setOnImageAvailableListener(onImageAvailableListener, backgroundExecutor);
 
         SessionConfig.Builder sessionConfigBuilder = SessionConfig.Builder.createFrom(config);
 
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisAbstractAnalyzer.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisAbstractAnalyzer.java
new file mode 100644
index 0000000..74b18c4
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisAbstractAnalyzer.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2019 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.camera.core;
+
+import android.os.Handler;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Abstract Analyzer that wraps around {@link ImageAnalysis.Analyzer} and implements
+ * {@link ImageReaderProxy.OnImageAvailableListener}.
+ *
+ * This is an extension of {@link ImageAnalysis}. It has the same lifecycle and share part of the
+ * states.
+ */
+abstract class ImageAnalysisAbstractAnalyzer implements ImageReaderProxy.OnImageAvailableListener {
+
+    // Member variables from ImageAnalysis.
+    private final AtomicReference<ImageAnalysis.Analyzer> mSubscribedAnalyzer;
+    private final AtomicInteger mRelativeRotation;
+    final Handler mUserHandler;
+
+    // Flag that reflects the state of ImageAnalysis.
+    private AtomicBoolean mIsClosed;
+
+    ImageAnalysisAbstractAnalyzer(AtomicReference<ImageAnalysis.Analyzer> subscribedAnalyzer,
+            AtomicInteger relativeRotation, Handler userHandler) {
+        mSubscribedAnalyzer = subscribedAnalyzer;
+        mRelativeRotation = relativeRotation;
+        mUserHandler = userHandler;
+        mIsClosed = new AtomicBoolean(false);
+    }
+
+    /**
+     * Analyzes a {@link ImageProxy} using the wrapped {@link ImageAnalysis.Analyzer}.
+     */
+    void analyzeImage(ImageProxy imageProxy) {
+        ImageAnalysis.Analyzer analyzer = mSubscribedAnalyzer.get();
+        if (analyzer != null && !isClosed()) {
+            // When the analyzer exists and ImageAnalysis is active.
+            analyzer.analyze(imageProxy, mRelativeRotation.get());
+        }
+    }
+
+    /**
+     * Initialize the callback.
+     */
+    void open() {
+        mIsClosed.set(false);
+    }
+
+    /**
+     * Closes the callback so that it will stop posting to analyzer.
+     */
+    void close() {
+        mIsClosed.set(true);
+    }
+
+    boolean isClosed() {
+        return mIsClosed.get();
+    }
+
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisBlockingAnalyzer.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisBlockingAnalyzer.java
new file mode 100644
index 0000000..1283f8d
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisBlockingAnalyzer.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2019 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.camera.core;
+
+import android.os.Handler;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * OnImageAvailableListener with blocking behavior. It never drops image without analyzing it.
+ *
+ * <p> Used with {@link ImageAnalysis}.
+ */
+final class ImageAnalysisBlockingAnalyzer extends ImageAnalysisAbstractAnalyzer {
+
+    ImageAnalysisBlockingAnalyzer(
+            AtomicReference<ImageAnalysis.Analyzer> subscribedAnalyzer,
+            AtomicInteger relativeRotation, Handler userHandler) {
+        super(subscribedAnalyzer, relativeRotation, userHandler);
+    }
+
+    @Override
+    public void onImageAvailable(ImageReaderProxy imageReaderProxy) {
+        ImageProxy image = imageReaderProxy.acquireNextImage();
+        if (image == null) {
+            return;
+        }
+        try {
+            mUserHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        analyzeImage(image);
+                    } finally {
+                        image.close();
+                    }
+                }
+            });
+        } catch (RuntimeException e) {
+            image.close();
+        }
+    }
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisBlockingCallback.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisBlockingCallback.java
deleted file mode 100644
index ce59f70..0000000
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisBlockingCallback.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2019 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.camera.core;
-
-import android.os.Handler;
-
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * OnImageAvailableListener with blocking behavior. It never drops image without analyzing it.
- *
- * <p> Used with {@link ImageAnalysis}.
- */
-final class ImageAnalysisBlockingCallback implements ImageReaderProxy.OnImageAvailableListener {
-
-    private static final String TAG = "BlockingCallback";
-
-    final AtomicReference<ImageAnalysis.Analyzer> mSubscribedAnalyzer;
-    final AtomicInteger mRelativeRotation;
-
-    private final Handler mUserHandler;
-
-    ImageAnalysisBlockingCallback(AtomicReference<ImageAnalysis.Analyzer> subscribedAnalyzer,
-            AtomicInteger relativeRotation, Handler userHandler) {
-        mSubscribedAnalyzer = subscribedAnalyzer;
-        mRelativeRotation = relativeRotation;
-        mUserHandler = userHandler;
-    }
-
-    @Override
-    public void onImageAvailable(ImageReaderProxy imageReaderProxy) {
-        ImageProxy image = imageReaderProxy.acquireNextImage();
-        if (image == null) {
-            return;
-        }
-        try {
-            mUserHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        ImageAnalysis.Analyzer analyzer = mSubscribedAnalyzer.get();
-                        if (analyzer != null) {
-                            analyzer.analyze(image, mRelativeRotation.get());
-                        }
-                    } finally {
-                        image.close();
-                    }
-                }
-            });
-        } catch (RuntimeException e) {
-            image.close();
-        }
-    }
-}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisNonBlockingAnalyzer.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisNonBlockingAnalyzer.java
new file mode 100644
index 0000000..fe8420e
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisNonBlockingAnalyzer.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2019 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.camera.core;
+
+import android.os.Handler;
+import android.util.Log;
+
+import androidx.annotation.GuardedBy;
+import androidx.annotation.NonNull;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * OnImageAvailableListener with non-blocking behavior. Analyzes images in a non-blocking way by
+ * dropping images when analyzer is busy.
+ *
+ * <p> Used with {@link ImageAnalysis}.
+ */
+final class ImageAnalysisNonBlockingAnalyzer extends ImageAnalysisAbstractAnalyzer {
+
+    private static final String TAG = "NonBlockingCallback";
+
+    // The executor for managing cached image.
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    final Executor mBackgroundExecutor;
+
+    // The cached image when analyzer is busy. Image removed from cache must be closed by 1) closing
+    // it directly or 2) re-posting it to close it eventually.
+    @GuardedBy("this")
+    private ImageProxy mCachedImage;
+
+    // Timestamp of the last image posted to user callback thread.
+    private final AtomicLong mPostedImageTimestamp;
+    // Timestamp of the last image finished being processed by user callback thread.
+    private final AtomicLong mFinishedImageTimestamp;
+
+    ImageAnalysisNonBlockingAnalyzer(AtomicReference<ImageAnalysis.Analyzer> subscribedAnalyzer,
+            AtomicInteger relativeRotation, Handler userHandler, Executor executor) {
+        super(subscribedAnalyzer, relativeRotation, userHandler);
+        mBackgroundExecutor = executor;
+        mPostedImageTimestamp = new AtomicLong();
+        mFinishedImageTimestamp = new AtomicLong();
+        open();
+    }
+
+    @Override
+    public void onImageAvailable(ImageReaderProxy imageReaderProxy) {
+        ImageProxy imageProxy = imageReaderProxy.acquireLatestImage();
+        if (imageProxy == null) {
+            return;
+        }
+        analyze(imageProxy);
+    }
+
+    @Override
+    synchronized void open() {
+        super.open();
+        mCachedImage = null;
+        mPostedImageTimestamp.set(-1);
+        mFinishedImageTimestamp.set(mPostedImageTimestamp.get());
+    }
+
+
+    @Override
+    synchronized void close() {
+        super.close();
+        if (mCachedImage != null) {
+            mCachedImage.close();
+            mCachedImage = null;
+        }
+    }
+
+    /**
+     * Removes cached image from cache and analyze it.
+     */
+    synchronized void analyzeCachedImage() {
+        if (mCachedImage != null) {
+            ImageProxy cachedImage = mCachedImage;
+            mCachedImage = null;
+            analyze(cachedImage);
+        }
+    }
+
+    /**
+     * This method guarantees closing the image by either 1) closing the image in the current
+     * thread, 2) caching it for later or 3) posting it to user Thread to close it.
+     *
+     * @param imageProxy the incoming image frame.
+     */
+    private synchronized void analyze(@NonNull ImageProxy imageProxy) {
+        if (isClosed()) {
+            return;
+        }
+        long postedImageTimestamp = mPostedImageTimestamp.get();
+        long finishedImageTimestamp = mFinishedImageTimestamp.get();
+
+        if (imageProxy.getTimestamp() <= postedImageTimestamp) {
+            // Discard image that is in wrong order. Reposted cached image can be in this state.
+            imageProxy.close();
+            return;
+        }
+
+        if (postedImageTimestamp > finishedImageTimestamp) {
+            // If analyzer is busy, cache the new image.
+            if (mCachedImage != null) {
+                mCachedImage.close();
+            }
+            mCachedImage = imageProxy;
+            return;
+        }
+
+        mPostedImageTimestamp.set(imageProxy.getTimestamp());
+        try {
+            mUserHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        analyzeImage(imageProxy);
+                    } finally {
+                        finishImage(imageProxy);
+                        mBackgroundExecutor.execute(new Runnable() {
+                            @Override
+                            public void run() {
+                                analyzeCachedImage();
+                            }
+                        });
+                    }
+                }
+            });
+        } catch (RuntimeException e) {
+            // Unblock if fails to post to user thread.
+            Log.e(TAG, "Error calling user callback", e);
+            finishImage(imageProxy);
+        }
+    }
+
+    synchronized void finishImage(ImageProxy imageProxy) {
+        if (isClosed()) {
+            return;
+        }
+        mFinishedImageTimestamp.set(imageProxy.getTimestamp());
+        imageProxy.close();
+    }
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisNonBlockingCallback.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisNonBlockingCallback.java
deleted file mode 100644
index 1d226f4..0000000
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisNonBlockingCallback.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright 2019 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.camera.core;
-
-import android.os.Handler;
-import android.util.Log;
-
-import androidx.annotation.GuardedBy;
-import androidx.annotation.NonNull;
-
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * OnImageAvailableListener with non-blocking behavior. Analyzes images in a non-blocking way by
- * dropping images when analyzer is busy.
- *
- * <p> Used with {@link ImageAnalysis}.
- */
-final class ImageAnalysisNonBlockingCallback implements ImageReaderProxy.OnImageAvailableListener {
-
-    private static final String TAG = "NonBlockingCallback";
-
-    final AtomicReference<ImageAnalysis.Analyzer> mSubscribedAnalyzer;
-    final AtomicInteger mRelativeRotation;
-
-    final Executor mBackgroundExecutor;
-    private final Handler mUserHandler;
-
-    // The cached image when analyzer is busy. Image removed from cache must be closed by 1) closing
-    // it directly or 2) re-posting it to close it eventually.
-    @GuardedBy("this")
-    private ImageProxy mCachedImage;
-
-    // Timestamp of the last image posted to user callback thread.
-    private final AtomicLong mPostedImageTimestamp;
-    // Timestamp of the last image finished being processed by user callback thread.
-    private final AtomicLong mFinishedImageTimestamp;
-
-    ImageAnalysisNonBlockingCallback(AtomicReference<ImageAnalysis.Analyzer> subscribedAnalyzer,
-            AtomicInteger relativeRotation, Handler userHandler,
-            Executor backgroundExecutor) {
-        mSubscribedAnalyzer = subscribedAnalyzer;
-        mRelativeRotation = relativeRotation;
-        mUserHandler = userHandler;
-        mBackgroundExecutor = backgroundExecutor;
-        mPostedImageTimestamp = new AtomicLong(-1);
-        mFinishedImageTimestamp = new AtomicLong(mPostedImageTimestamp.get());
-    }
-
-    @Override
-    public void onImageAvailable(ImageReaderProxy imageReaderProxy) {
-        ImageProxy imageProxy = imageReaderProxy.acquireLatestImage();
-        if (imageProxy == null) {
-            return;
-        }
-        analyze(imageProxy);
-    }
-
-    /**
-     * Removes cached image from cache and analyze it.
-     */
-    synchronized void analyzeCachedImage() {
-        if (mCachedImage != null) {
-            ImageProxy cachedImage = mCachedImage;
-            mCachedImage = null;
-            analyze(cachedImage);
-        }
-    }
-
-    /**
-     * This method guarantees closing the image by either 1) closing the image in the current
-     * thread, 2) caching it for later or 3) posting it to user Thread to close it.
-     *
-     * @param imageProxy the incoming image frame.
-     */
-    private synchronized void analyze(@NonNull ImageProxy imageProxy) {
-        long postedImageTimestamp = mPostedImageTimestamp.get();
-        long finishedImageTimestamp = mFinishedImageTimestamp.get();
-
-        if (imageProxy.getTimestamp() <= postedImageTimestamp) {
-            // Discard image that is in wrong order. Reposted cached image can be in this state.
-            imageProxy.close();
-            return;
-        }
-
-        if (postedImageTimestamp > finishedImageTimestamp) {
-            // If analyzer is busy, cache the new image.
-            if (mCachedImage != null) {
-                mCachedImage.close();
-            }
-            mCachedImage = imageProxy;
-            return;
-        }
-
-        mPostedImageTimestamp.set(imageProxy.getTimestamp());
-        try {
-            mUserHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        ImageAnalysis.Analyzer analyzer = mSubscribedAnalyzer.get();
-                        if (analyzer != null) {
-                            analyzer.analyze(imageProxy, mRelativeRotation.get());
-                        }
-                    } finally {
-                        finishImage(imageProxy);
-                        mBackgroundExecutor.execute(new Runnable() {
-                            @Override
-                            public void run() {
-                                analyzeCachedImage();
-                            }
-                        });
-                    }
-                }
-            });
-        } catch (RuntimeException e) {
-            // Unblock if fails to post to user thread.
-            Log.e(TAG, "Error calling user callback", e);
-            finishImage(imageProxy);
-        }
-    }
-
-    synchronized void finishImage(ImageProxy imageProxy) {
-        mFinishedImageTimestamp.set(imageProxy.getTimestamp());
-        imageProxy.close();
-    }
-}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
index 23cc100..1302d0f 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
@@ -408,17 +408,17 @@
                     @Override
                     public void onError(
                             ImageSaver.SaveError error, String message, @Nullable Throwable cause) {
-                        UseCaseError useCaseError = UseCaseError.UNKNOWN_ERROR;
+                        ImageCaptureError imageCaptureError = ImageCaptureError.UNKNOWN_ERROR;
                         switch (error) {
                             case FILE_IO_FAILED:
-                                useCaseError = UseCaseError.FILE_IO_ERROR;
+                                imageCaptureError = ImageCaptureError.FILE_IO_ERROR;
                                 break;
                             default:
-                                // Keep the useCaseError as UNKNOWN_ERROR
+                                // Keep the imageCaptureError as UNKNOWN_ERROR
                                 break;
                         }
 
-                        imageSavedListener.onError(useCaseError, message, cause);
+                        imageSavedListener.onError(imageCaptureError, message, cause);
                     }
                 };
 
@@ -444,7 +444,8 @@
 
                     @Override
                     public void onError(
-                            UseCaseError error, String message, @Nullable Throwable cause) {
+                            @NonNull ImageCaptureError error, @NonNull String message,
+                            @Nullable Throwable cause) {
                         imageSavedListener.onError(error, message, cause);
                     }
                 };
@@ -548,7 +549,8 @@
                                             ImageCaptureRequest request =
                                                     mImageCaptureRequests.poll();
                                             if (request != null) {
-                                                request.callbackError(UseCaseError.UNKNOWN_ERROR,
+                                                request.callbackError(
+                                                        ImageCaptureError.UNKNOWN_ERROR,
                                                         (error != null) ? error.getMessage()
                                                                 : "Unknown error", error);
                                                 // Handle the next request.
@@ -1010,9 +1012,9 @@
      * ImageCapture#takePicture(OnImageCapturedListener)}).
      *
      * <p>This is a parameter sent to the error callback functions set in listeners such as {@link
-     * ImageCapture.OnImageSavedListener#onError(UseCaseError, String, Throwable)}.
+     * ImageCapture.OnImageSavedListener#onError(ImageCaptureError, String, Throwable)}.
      */
-    public enum UseCaseError {
+    public enum ImageCaptureError {
         /**
          * An unknown error occurred.
          *
@@ -1051,7 +1053,7 @@
 
         /** Called when an error occurs while attempting to save an image. */
         void onError(
-                @NonNull UseCaseError useCaseError,
+                @NonNull ImageCaptureError imageCaptureError,
                 @NonNull String message,
                 @Nullable Throwable cause);
     }
@@ -1093,7 +1095,8 @@
 
         /** Callback for when an error occurred during image capture. */
         public void onError(
-                UseCaseError useCaseError, String message, @Nullable Throwable cause) {
+                @NonNull ImageCaptureError imageCaptureError, @NonNull String message,
+                @Nullable Throwable cause) {
         }
     }
 
@@ -1341,13 +1344,13 @@
             mListener.onCaptureSuccess(image, mRotationDegrees);
         }
 
-        void callbackError(final UseCaseError useCaseError, final String message,
+        void callbackError(final ImageCaptureError imageCaptureError, final String message,
                 final Throwable cause) {
             if (mHandler != null && Looper.myLooper() != mHandler.getLooper()) {
                 boolean posted = mHandler.post(new Runnable() {
                     @Override
                     public void run() {
-                        ImageCaptureRequest.this.callbackError(useCaseError, message, cause);
+                        ImageCaptureRequest.this.callbackError(imageCaptureError, message, cause);
                     }
                 });
                 if (!posted) {
@@ -1356,7 +1359,7 @@
                 return;
             }
 
-            mListener.onError(useCaseError, message, cause);
+            mListener.onError(imageCaptureError, message, cause);
         }
     }
 }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/MeteringPoint.java b/camera/camera-core/src/main/java/androidx/camera/core/MeteringPoint.java
new file mode 100644
index 0000000..fcf01b5
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/MeteringPoint.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2019 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.camera.core;
+
+import android.util.Rational;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+
+/**
+ * A MeteringPoint used to specify a region in sensor coordinates for focusing and metering
+ * Purpose.
+ *
+ * <p>To create a {@link MeteringPoint}, apps have to use
+ * {@link DisplayOrientedMeteringPointFactory} or {@link SensorOrientedMeteringPointFactory}.
+ * The X/Y insides a MeteringPoint represents the normalized X/Y inside current crop region. If no
+ * crop region is set, the the whole sensor area is used. AreaSize represents the width and the
+ * height of the metering area and Weight can also be specified. By default, a MeteringPoint is
+ * mapped to the sensor coordinates using Preview aspect ratio.  A custom FOV aspect ratio can be
+ * set if apps want to use aspect ratio other than Preview.
+ */
+public class MeteringPoint {
+    private float mNormalizedCropRegionX;
+    private float mNormalizedCropRegionY;
+    private float mSize;
+    private float mWeight;
+    @Nullable
+    private Rational mFOVAspectRatio; // null for preview aspect ratio.
+
+    /**
+     * Constructor is restricted for use within library.
+     *
+     * @param normalizedCropRegionX normalized X (ranging from 0 to 1) in current crop region.
+     * @param normalizedCropRegionY normalized Y (ranging from 0 to 1) in current crop region.
+     * @param size            size of the MeteringPoint(ranging from 0 to 1). The value
+     *                       represents the percentage of current crop region width/height.
+     * @param weight                weight of this metering point ranging from 0 to 1.
+     * @param fovAspectRatio        if specified, use this aspect ratio. Otherwise use Preview's
+     *                              aspect
+     *                              ratio.
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public MeteringPoint(float normalizedCropRegionX, float normalizedCropRegionY, float size,
+            float weight, @Nullable Rational fovAspectRatio) {
+        mNormalizedCropRegionX = normalizedCropRegionX;
+        mNormalizedCropRegionY = normalizedCropRegionY;
+        mSize = size;
+        mWeight = weight;
+        mFOVAspectRatio = fovAspectRatio;
+    }
+
+    /**
+     * Normalized crop region X (Ranging from 0 to 1)
+     */
+    public float getNormalizedCropRegionX() {
+        return mNormalizedCropRegionX;
+    }
+
+    /**
+     * Normalized crop region Y (Ranging from 0 to 1)
+     */
+    public float getNormalizedCropRegionY() {
+        return mNormalizedCropRegionY;
+    }
+
+    /**
+     * Size of the MeteringPoint(ranging from 0 to 1). The value represents the percentage of
+     * current crop region width/height
+     */
+    public float getSize() {
+        return mSize;
+    }
+
+    /**
+     * Weight of the MeteringPoint (Ranging from 0 to 1)
+     */
+    public float getWeight() {
+        return mWeight;
+    }
+
+    /**
+     * Sets the size of MeteringPoint (ranging from 0 to 1). It is the percentage of the sensor
+     * width/height (or cropRegion width/height if crop region is set)
+     *
+     * <p><pre>Metering Area width = size * cropRegion.width
+     * Metering Area height = size * cropRegion.height
+     * </pre>
+     *
+     */
+    public void setSize(float size) {
+        mSize = size;
+    }
+
+    /**
+     * Sets weight of this metering point (ranging from 0 to 1)
+     */
+    public void setWeight(float weight) {
+        mWeight = weight;
+    }
+
+    /**
+     * Set custom aspect ratio to be adjusted for final sensor coordinates.
+     */
+    public void setFOVAspectRatio(@Nullable Rational fovAspectRatio) {
+        mFOVAspectRatio = fovAspectRatio;
+    }
+
+
+    /**
+     * Get custom aspect ratio to be adjusted for final sensor coordinates.
+     */
+    @Nullable
+    public Rational getFOVAspectRatio() {
+        return mFOVAspectRatio;
+    }
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/MeteringPointFactory.java b/camera/camera-core/src/main/java/androidx/camera/core/MeteringPointFactory.java
new file mode 100644
index 0000000..f1cbe0c
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/MeteringPointFactory.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2019 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.camera.core;
+
+import android.graphics.PointF;
+import android.util.Rational;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * A Factory to create a {@link MeteringPoint}.
+ *
+ * <p>MeteringPointFactory implementations must extends this class and implement
+ * translatePoint(float x, float y). Users can call createPoint(float x, float y) to create a
+ * {@link MeteringPoint} with default areaSize and weight. There is a variation of createPoint
+ * that accepts areaSize and weight as well.
+ */
+public abstract class MeteringPointFactory {
+    public static final float DEFAULT_AREASIZE = 0.15f;
+    public static final float DEFAULT_WEIGHT = 1.0f;
+    @Nullable
+    protected Rational mFOVAspectRatio = null; // null for using Preview aspect ratio.
+
+    /**
+     * Translates a logical x/y into the normalized crop region x/y.
+     *
+     * <p>The logical x/y is with respect to related to the implementations. Implementations specify
+     * the logical width/height and define the orientation of the area. Some are sensor-oriented and
+     * some are display-oriented. The logical x/y is the position from the area defined by the width
+     * , height and the orientation.
+     *
+     * Implementation must implement this method for coordinates translation.
+     *
+     * @param x the logical x to be translated.
+     * @param y the logical y to be translated.
+     * @return a {@link PointF} consisting of translated normalized crop region x/y,
+     */
+    @NonNull
+    protected abstract PointF translatePoint(float x, float y);
+
+    /**
+     * Creates a {@link MeteringPoint} by x, y.
+     *
+     * <p>The x/y is the position from the area defined by the width, height and the orientation in
+     * specific {@link MeteringPointFactory} implementation.
+     */
+    @NonNull
+    public final MeteringPoint createPoint(float x, float y) {
+        return createPoint(x, y, DEFAULT_AREASIZE, DEFAULT_WEIGHT);
+    }
+
+    /**
+     * Creates a {@link MeteringPoint} by x , y , areaSize and weight.
+     *
+     * <p>The x/y is the position from the area defined by the width, height and the orientation in
+     * specific {@link MeteringPointFactory} implementation.
+     *
+     * @param x          the logical x to be translated
+     * @param y          the logical y to be translated
+     * @param size  size of the point. The value is ranging from 0 to 1 meaning the
+     *                   percentage of crop region width/height.
+     * @param weight     weight of metering region ranging from 0 to 1.
+     * @return A {@link MeteringPoint} that is translated into normalized crop region x/y.
+     */
+    @NonNull
+    public final MeteringPoint createPoint(float x, float y, float size, float weight) {
+        PointF translatedXY = translatePoint(x, y);
+        return new MeteringPoint(translatedXY.x, translatedXY.y, size, weight,
+                mFOVAspectRatio);
+    }
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/OnFocusListener.java b/camera/camera-core/src/main/java/androidx/camera/core/OnFocusListener.java
deleted file mode 100644
index 1c1350e..0000000
--- a/camera/camera-core/src/main/java/androidx/camera/core/OnFocusListener.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2019 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.camera.core;
-
-import android.graphics.Rect;
-
-/** Listener called when focus scan has completed. */
-public interface OnFocusListener {
-    /** Callback when focus has been locked. */
-    void onFocusLocked(Rect afRect);
-
-    /** Callback when unable to acquire focus. */
-    void onFocusUnableToLock(Rect afRect);
-
-    /** Callback when timeout is reached and af state haven't settled. */
-    void onFocusTimedOut(Rect afRect);
-}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/Preview.java b/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
index abc44f7..b7f7f45 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
@@ -36,7 +36,6 @@
 import androidx.annotation.UiThread;
 import androidx.camera.core.CameraX.LensFacing;
 import androidx.camera.core.ImageOutputConfig.RotationValue;
-import androidx.camera.core.impl.utils.executor.CameraXExecutors;
 
 import com.google.auto.value.AutoValue;
 
@@ -240,45 +239,6 @@
     }
 
     /**
-     * Adjusts the preview according to the properties in some local regions.
-     *
-     * <p>The auto-focus (AF) and auto-exposure (AE) properties will be recalculated from the local
-     * regions.
-     *
-     * <p>Dimensions of the sensor coordinate frame can be found using Camera2.
-     *
-     * @param focus    rectangle with dimensions in sensor coordinate frame for focus
-     * @param metering rectangle with dimensions in sensor coordinate frame for metering
-     */
-    public void focus(Rect focus, Rect metering) {
-        focus(focus, metering, null);
-    }
-
-    /**
-     * Adjusts the preview according to the properties in some local regions with a callback
-     * called once focus scan has completed.
-     *
-     * <p>The auto-focus (AF) and auto-exposure (AE) properties will be recalculated from the local
-     * regions.
-     *
-     * <p>Dimensions of the sensor coordinate frame can be found using Camera2.
-     *
-     * @param focus    rectangle with dimensions in sensor coordinate frame for focus
-     * @param metering rectangle with dimensions in sensor coordinate frame for metering
-     * @param listener listener for when focus has completed
-     */
-    public void focus(Rect focus, Rect metering, @Nullable OnFocusListener listener) {
-        // If the listener is not null, we will call it back on the main thread.
-        if (listener == null) {
-            getCurrentCameraControl().focus(focus, metering);
-        } else {
-            getCurrentCameraControl().focus(focus, metering, CameraXExecutors.mainThreadExecutor(),
-                    listener);
-        }
-
-    }
-
-    /**
      * Adjusts the preview to zoom to a local region.
      *
      * <p>Setting the zoom is equivalent to setting a scalar crop region (digital zoom), and zoom
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/SensorOrientedMeteringPointFactory.java b/camera/camera-core/src/main/java/androidx/camera/core/SensorOrientedMeteringPointFactory.java
new file mode 100644
index 0000000..dac6cff
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/SensorOrientedMeteringPointFactory.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2019 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.camera.core;
+
+import android.graphics.PointF;
+import android.util.Rational;
+import android.util.Size;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.lifecycle.LifecycleOwner;
+
+import java.util.Set;
+
+/**
+ * A {@link MeteringPointFactory} that can create {@link MeteringPoint} by sensor oriented x, y ,
+ * width and height.
+ *
+ * <p>This factory is suitable for apps that already have coordinates translated into sensor
+ * coordinates. It is also useful for apps that want to focus on something detected in
+ * {@link ImageAnalysis}. Apps can pass the {@link ImageAnalysis} instance for useCaseForFOV
+ * argument and CameraX will then adjust the final sensor coordinates by aspect ratio of
+ * ImageAnalysis.
+ */
+public class SensorOrientedMeteringPointFactory extends MeteringPointFactory {
+    /** the logical width of FoV in sensor orientation*/
+    private final float mWidth;
+    /** the logical height of FoV in sensor orientation */
+    private final float mHeight;
+
+    /**
+     * Creates the SensorOrientedMeteringPointFactory by width and height
+     *
+     * <p>The width/height is the logical width/height of the preview FoV in sensor orientation and
+     * X/Y is the logical XY inside the FOV. User can set the width and height to 1.0 which will
+     * make the XY the normalized coordinates [0..1].
+     *
+     * <p>By default, it will use active {@link Preview} as the FoV for final coordinates
+     * translation.
+     *
+     * @param width the logical width of FoV in sensor orientation
+     * @param height the logical height of FoV in sensor orientation
+     */
+    public SensorOrientedMeteringPointFactory(float width, float height) {
+        mWidth = width;
+        mHeight = height;
+        mFOVAspectRatio = null;
+    }
+
+    /**
+     * Creates the SensorOrientedMeteringPointFactory by width, height and useCaseForFOV.
+     *
+     * <p>The width/height is the logical width/height of the preview FoV in sensor orientation and
+     * X/Y is the logical XY inside the FOV. User can set the width and height to 1.0 which will
+     * make the XY the normalized coordinates [0..1].
+     *
+     * <p>useCaseForFOV is used to determine the FOV of this translation. This useCaseForFOV needs
+     * to be bound via {@link CameraX#bindToLifecycle(LifecycleOwner, UseCase...)} first. Otherwise
+     * it will throw a {@link IllegalStateException}
+     *
+     * @param width the logical width of FOV in sensor orientation.
+     * @param height the logical height of FOV in sensor orientation.
+     * @param useCaseForFOV the {@link UseCase} to be the FOV.
+     */
+    public SensorOrientedMeteringPointFactory(float width, float height,
+            @NonNull UseCase useCaseForFOV) {
+        mWidth = width;
+        mHeight = height;
+        mFOVAspectRatio = getUseCaseAspectRatio(useCaseForFOV);
+    }
+
+    @Nullable
+    private Rational getUseCaseAspectRatio(@Nullable UseCase useCase) {
+        if (useCase == null) {
+            return null;
+        }
+
+        Set<String> cameraIds = useCase.getAttachedCameraIds();
+        if (cameraIds.isEmpty()) {
+            throw new IllegalStateException("UseCase " + useCase + " is not bound.");
+        }
+
+        for (String id : cameraIds) {
+            Size resolution = useCase.getAttachedSurfaceResolution(id);
+            // Returns an aspect ratio of first found attachedSurfaceResolution.
+            return new Rational(resolution.getWidth(), resolution.getHeight());
+        }
+
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    @NonNull
+    protected PointF translatePoint(float x, float y) {
+        PointF pt = new PointF(x / mWidth, y / mHeight);
+        return pt;
+    }
+
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/VideoCapture.java b/camera/camera-core/src/main/java/androidx/camera/core/VideoCapture.java
index f248a24..ead0f52 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/VideoCapture.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/VideoCapture.java
@@ -225,7 +225,7 @@
      * called.
      *
      * <p>StartRecording() is asynchronous. User needs to check if any error occurs by setting the
-     * {@link OnVideoSavedListener#onError(UseCaseError, String, Throwable)}.
+     * {@link OnVideoSavedListener#onError(VideoCaptureError, String, Throwable)}.
      *
      * @param saveLocation Location to save the video capture
      * @param listener     Listener to call for the recorded video
@@ -241,7 +241,7 @@
      * called.
      *
      * <p>StartRecording() is asynchronous. User needs to check if any error occurs by setting the
-     * {@link OnVideoSavedListener#onError(UseCaseError, String, Throwable)}.
+     * {@link OnVideoSavedListener#onError(VideoCaptureError, String, Throwable)}.
      *
      * @param saveLocation Location to save the video capture
      * @param listener     Listener to call for the recorded video
@@ -253,7 +253,8 @@
 
         if (!mEndOfAudioVideoSignal.get()) {
             listener.onError(
-                    UseCaseError.RECORDING_IN_PROGRESS, "It is still in video recording!", null);
+                    VideoCaptureError.RECORDING_IN_PROGRESS, "It is still in video recording!",
+                    null);
             return;
         }
 
@@ -261,7 +262,7 @@
             // audioRecord start
             mAudioRecorder.startRecording();
         } catch (IllegalStateException e) {
-            listener.onError(UseCaseError.ENCODER_ERROR, "AudioRecorder start fail", e);
+            listener.onError(VideoCaptureError.ENCODER_ERROR, "AudioRecorder start fail", e);
             return;
         }
 
@@ -277,7 +278,7 @@
 
         } catch (IllegalStateException e) {
             setupEncoder(getAttachedSurfaceResolution(cameraId));
-            listener.onError(UseCaseError.ENCODER_ERROR, "Audio/Video encoder start fail", e);
+            listener.onError(VideoCaptureError.ENCODER_ERROR, "Audio/Video encoder start fail", e);
             return;
         }
 
@@ -309,7 +310,7 @@
             }
         } catch (IOException e) {
             setupEncoder(getAttachedSurfaceResolution(cameraId));
-            listener.onError(UseCaseError.MUXER_ERROR, "MediaMuxer creation failed!", e);
+            listener.onError(VideoCaptureError.MUXER_ERROR, "MediaMuxer creation failed!", e);
             return;
         }
 
@@ -344,8 +345,9 @@
      * VideoCapture#startRecording(File, OnVideoSavedListener, Metadata)} is called.
      *
      * <p>stopRecording() is asynchronous API. User need to check if {@link
-     * OnVideoSavedListener#onVideoSaved(File)} or {@link OnVideoSavedListener#onError(UseCaseError,
-     * String, Throwable)} be called before startRecording.
+     * OnVideoSavedListener#onVideoSaved(File)} or
+     * {@link OnVideoSavedListener#onError(VideoCaptureError, String, Throwable)} be called
+     * before startRecording.
      */
     public void stopRecording() {
         Log.i(TAG, "stopRecording");
@@ -581,7 +583,7 @@
                 case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
                     if (mMuxerStarted) {
                         videoSavedListener.onError(
-                                UseCaseError.ENCODER_ERROR,
+                                VideoCaptureError.ENCODER_ERROR,
                                 "Unexpected change in video encoding format.",
                                 null);
                         errorOccurred = true;
@@ -611,7 +613,8 @@
             Log.i(TAG, "videoEncoder stop");
             mVideoEncoder.stop();
         } catch (IllegalStateException e) {
-            videoSavedListener.onError(UseCaseError.ENCODER_ERROR, "Video encoder stop failed!", e);
+            videoSavedListener.onError(VideoCaptureError.ENCODER_ERROR,
+                    "Video encoder stop failed!", e);
             errorOccurred = true;
         }
 
@@ -627,7 +630,7 @@
                 }
             }
         } catch (IllegalStateException e) {
-            videoSavedListener.onError(UseCaseError.MUXER_ERROR, "Muxer stop failed!", e);
+            videoSavedListener.onError(VideoCaptureError.MUXER_ERROR, "Muxer stop failed!", e);
             errorOccurred = true;
         }
 
@@ -702,13 +705,14 @@
             mAudioRecorder.stop();
         } catch (IllegalStateException e) {
             videoSavedListener.onError(
-                    UseCaseError.ENCODER_ERROR, "Audio recorder stop failed!", e);
+                    VideoCaptureError.ENCODER_ERROR, "Audio recorder stop failed!", e);
         }
 
         try {
             mAudioEncoder.stop();
         } catch (IllegalStateException e) {
-            videoSavedListener.onError(UseCaseError.ENCODER_ERROR, "Audio encoder stop failed!", e);
+            videoSavedListener.onError(VideoCaptureError.ENCODER_ERROR,
+                    "Audio encoder stop failed!", e);
         }
 
         Log.i(TAG, "Audio encode thread end");
@@ -823,11 +827,11 @@
      * Describes the error that occurred during video capture operations.
      *
      * <p>This is a parameter sent to the error callback functions set in listeners such as {@link
-     * VideoCapture.OnVideoSavedListener#onError(UseCaseError, String, Throwable)}.
+     * VideoCapture.OnVideoSavedListener#onError(VideoCaptureError, String, Throwable)}.
      *
      * <p>See message parameter in onError callback or log for more details.
      */
-    public enum UseCaseError {
+    public enum VideoCaptureError {
         /**
          * An unknown error occurred.
          *
@@ -850,10 +854,11 @@
     /** Listener containing callbacks for video file I/O events. */
     public interface OnVideoSavedListener {
         /** Called when the video has been successfully saved. */
-        void onVideoSaved(File file);
+        void onVideoSaved(@NonNull File file);
 
         /** Called when an error occurs while attempting to save the video. */
-        void onError(UseCaseError useCaseError, String message, @Nullable Throwable cause);
+        void onError(@NonNull VideoCaptureError videoCaptureError, @NonNull String message,
+                @Nullable Throwable cause);
     }
 
     /**
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/utils/executor/SequentialExecutor.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/utils/executor/SequentialExecutor.java
index 67c284b..a90d1ae 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/utils/executor/SequentialExecutor.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/utils/executor/SequentialExecutor.java
@@ -73,7 +73,7 @@
 
     /** Use {@link CameraXExecutors#newSequentialExecutor} */
     SequentialExecutor(Executor executor) {
-        this.mExecutor = Preconditions.checkNotNull(executor);
+        mExecutor = Preconditions.checkNotNull(executor);
     }
 
     /**
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/utils/futures/Futures.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/utils/futures/Futures.java
index 2bab1e5..46b5a2d 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/utils/futures/Futures.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/utils/futures/Futures.java
@@ -19,6 +19,8 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.arch.core.util.Function;
+import androidx.camera.core.impl.utils.executor.CameraXExecutors;
+import androidx.concurrent.futures.CallbackToFutureAdapter;
 import androidx.core.util.Preconditions;
 
 import com.google.common.util.concurrent.ListenableFuture;
@@ -85,12 +87,12 @@
      * of the given {@code Future}. If the given {@code Future} fails, the returned {@code Future}
      * fails with the same exception (and the function is not invoked).
      *
-     * @param input The future to transform
+     * @param input    The future to transform
      * @param function A function to transform the result of the input future to the result of the
-     *     output future
+     *                 output future
      * @param executor Executor to run the function in.
      * @return A future that holds result of the function (if the input succeeded) or the original
-     *     input's failure (if not)
+     * input's failure (if not)
      */
     @NonNull
     public static <I, O> ListenableFuture<O> transformAsync(
@@ -105,9 +107,9 @@
      * Future}. If {@code input} fails, the returned {@code Future} fails with the same
      * exception (and the function is not invoked)
      *
-     * @param input The future to transform
-     * @param function A Function to transform the results of the provided future to the results of
-     *     the returned future.
+     * @param input    The future to transform
+     * @param function A function to transform the results of the provided future to the results of
+     *                 the returned future.
      * @param executor Executor to run the function in.
      * @return A future that holds result of the transformation.
      */
@@ -118,6 +120,81 @@
         return AbstractTransformFuture.create(input, function, executor);
     }
 
+    private static final Function<?, ?> IDENTITY_FUNCTION = new Function<Object, Object>() {
+        @Override
+        public Object apply(Object input) {
+            return input;
+        }
+    };
+
+    /**
+     * Propagates the result of the given {@code ListenableFuture} to the given {@link
+     * CallbackToFutureAdapter.Completer} directly.
+     *
+     * <p>If {@code input} fails, the failure will be propagated to the {@code completer}.
+     *
+     * @param input     The future being propagated.
+     * @param completer The completer which will receive the result of the provided future.
+     */
+    @SuppressWarnings("LambdaLast") // ListenableFuture not needed for SAM conversion
+    public static <V> void propagate(
+            @NonNull ListenableFuture<V> input,
+            @NonNull final CallbackToFutureAdapter.Completer<V> completer) {
+        @SuppressWarnings({"unchecked"}) // Input of function is same as output
+                Function<? super V, ? extends V> identityTransform =
+                (Function<? super V, ? extends V>) IDENTITY_FUNCTION;
+        // Use direct executor here since function is just unpacking the output and should be quick
+        propagateTransform(input, identityTransform, completer, CameraXExecutors.directExecutor());
+    }
+
+    /**
+     * Propagates the result of the given {@code ListenableFuture} to the given {@link
+     * CallbackToFutureAdapter.Completer} by applying the provided transformation function.
+     *
+     * <p>If {@code input} fails, the failure will be propagated to the {@code completer} (and the
+     * function is not invoked)
+     *
+     * @param input     The future to transform.
+     * @param function  A function to transform the results of the provided future to the results of
+     *                  the provided completer.
+     * @param completer The completer which will receive the result of the provided future.
+     * @param executor  Executor to run the function in.
+     */
+    public static <I, O> void propagateTransform(
+            @NonNull final ListenableFuture<I> input,
+            @NonNull final Function<? super I, ? extends O> function,
+            @NonNull final CallbackToFutureAdapter.Completer<O> completer,
+            @NonNull Executor executor) {
+        Preconditions.checkNotNull(input);
+        Preconditions.checkNotNull(function);
+        Preconditions.checkNotNull(completer);
+        Preconditions.checkNotNull(executor);
+
+        addCallback(input, new FutureCallback<I>() {
+            @Override
+            public void onSuccess(@Nullable I result) {
+                try {
+                    completer.set(function.apply(result));
+                } catch (Throwable t) {
+                    completer.setException(t);
+                }
+            }
+
+            @Override
+            public void onFailure(Throwable t) {
+                completer.setException(t);
+            }
+        }, executor);
+
+        // Propagate cancellation from completer to input future
+        completer.addCancellationListener(new Runnable() {
+            @Override
+            public void run() {
+                input.cancel(true);
+            }
+        }, CameraXExecutors.directExecutor());
+    }
+
     /**
      * Creates a new {@code ListenableFuture} whose value is a list containing the values of all its
      * successful input futures. The list of results is in the same order as the input list, and if
@@ -159,7 +236,7 @@
      * computation is {@linkplain java.util.concurrent.Future#isDone() complete} or, if the
      * computation is already complete, immediately.
      *
-     * @param future The future attach the callback to.
+     * @param future   The future attach the callback to.
      * @param callback The callback to invoke when {@code future} is completed.
      * @param executor The executor to run {@code callback} when the future completes.
      */
@@ -211,7 +288,7 @@
      * that the {@code Future} is already done. Second, if buggy code calls {@code getDone} on a
      * {@code Future} that is still pending, the program will throw instead of block.
      *
-     * @throws ExecutionException if the {@code Future} failed with an exception
+     * @throws ExecutionException    if the {@code Future} failed with an exception
      * @throws CancellationException if the {@code Future} was cancelled
      * @throws IllegalStateException if the {@code Future} is not done
      */
@@ -235,7 +312,7 @@
     /**
      * Invokes {@code Future.}{@link Future#get() get()} uninterruptibly.
      *
-     * @throws ExecutionException if the computation threw an exception
+     * @throws ExecutionException    if the computation threw an exception
      * @throws CancellationException if the computation was cancelled
      */
     @Nullable
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/FocusMeteringActionTest.java b/camera/camera-core/src/test/java/androidx/camera/core/FocusMeteringActionTest.java
new file mode 100644
index 0000000..6f7bc0e
--- /dev/null
+++ b/camera/camera-core/src/test/java/androidx/camera/core/FocusMeteringActionTest.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright 2019 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.camera.core;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.camera.core.FocusMeteringAction.MeteringMode;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.internal.DoNotInstrument;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+@SmallTest
+@RunWith(RobolectricTestRunner.class)
+@DoNotInstrument
+public class FocusMeteringActionTest {
+    private SensorOrientedMeteringPointFactory mPointFactory =
+            new SensorOrientedMeteringPointFactory(1.0f, 1.0f);
+
+    MeteringPoint mPoint1 = mPointFactory.createPoint(0, 0);
+    MeteringPoint mPoint2 = mPointFactory.createPoint(1, 1);
+    MeteringPoint mPoint3 = mPointFactory.createPoint(1, 0);
+
+    @Test
+    public void defaultBuilder_valueIsDefault() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1).build();
+
+        assertThat(action.getMeteringPointsAF()).containsExactly(mPoint1);
+        assertThat(action.getMeteringPointsAE()).containsExactly(mPoint1);
+        assertThat(action.getMeteringPointsAWB()).containsExactly(mPoint1);
+        assertThat(action.getAutoCancelDurationInMs()).isEqualTo(
+                FocusMeteringAction.DEFAULT_AUTOCANCEL_DURATION);
+        assertThat(action.getOnAutoFocusListener()).isNull();
+    }
+
+    @Test
+    public void fromPointWithAFAEAWB() {
+        FocusMeteringAction action = FocusMeteringAction.Builder
+                .from(mPoint1, MeteringMode.AF_AE_AWB).build();
+        assertThat(action.getMeteringPointsAF()).containsExactly(mPoint1);
+        assertThat(action.getMeteringPointsAE()).containsExactly(mPoint1);
+        assertThat(action.getMeteringPointsAWB()).containsExactly(mPoint1);
+    }
+
+    @Test
+    public void fromPointWithAFAE() {
+        FocusMeteringAction action = FocusMeteringAction.Builder
+                .from(mPoint1, MeteringMode.AF_AE).build();
+        assertThat(action.getMeteringPointsAF()).containsExactly(mPoint1);
+        assertThat(action.getMeteringPointsAE()).containsExactly(mPoint1);
+        assertThat(action.getMeteringPointsAWB()).isEmpty();
+    }
+
+    @Test
+    public void fromPointWithAFAWB() {
+        FocusMeteringAction action = FocusMeteringAction.Builder
+                .from(mPoint1, MeteringMode.AF_AWB).build();
+        assertThat(action.getMeteringPointsAF()).containsExactly(mPoint1);
+        assertThat(action.getMeteringPointsAE()).isEmpty();
+        assertThat(action.getMeteringPointsAWB()).containsExactly(mPoint1);
+    }
+
+    @Test
+    public void fromPointWithAEAWB() {
+        FocusMeteringAction action = FocusMeteringAction.Builder
+                .from(mPoint1, MeteringMode.AE_AWB).build();
+        assertThat(action.getMeteringPointsAF()).isEmpty();
+        assertThat(action.getMeteringPointsAE()).containsExactly(mPoint1);
+        assertThat(action.getMeteringPointsAWB()).containsExactly(mPoint1);
+    }
+
+    @Test
+    public void fromPointWithAF() {
+        FocusMeteringAction action = FocusMeteringAction.Builder
+                .from(mPoint1, MeteringMode.AF_ONLY).build();
+        assertThat(action.getMeteringPointsAF()).containsExactly(mPoint1);
+        assertThat(action.getMeteringPointsAE()).isEmpty();
+        assertThat(action.getMeteringPointsAWB()).isEmpty();
+    }
+
+    @Test
+    public void fromPointWithAE() {
+        FocusMeteringAction action = FocusMeteringAction.Builder
+                .from(mPoint1, MeteringMode.AE_ONLY).build();
+        assertThat(action.getMeteringPointsAF()).isEmpty();
+        assertThat(action.getMeteringPointsAE()).containsExactly(mPoint1);
+        assertThat(action.getMeteringPointsAWB()).isEmpty();
+    }
+
+    @Test
+    public void fromPointWithAWB() {
+        FocusMeteringAction action = FocusMeteringAction.Builder
+                .from(mPoint1, MeteringMode.AWB_ONLY).build();
+        assertThat(action.getMeteringPointsAF()).isEmpty();
+        assertThat(action.getMeteringPointsAE()).isEmpty();
+        assertThat(action.getMeteringPointsAWB()).containsExactly(mPoint1);
+    }
+
+    @Test
+    public void multiplePointsWithDefaultMeteringMode() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1)
+                .addPoint(mPoint2)
+                .addPoint(mPoint3)
+                .build();
+        assertThat(action.getMeteringPointsAF()).containsExactly(mPoint1, mPoint2, mPoint3);
+        assertThat(action.getMeteringPointsAE()).containsExactly(mPoint1, mPoint2, mPoint3);
+        assertThat(action.getMeteringPointsAWB()).containsExactly(mPoint1, mPoint2, mPoint3);
+    }
+
+    @Test
+    public void multiplePointsWithSameAF_AE_AWB() {
+        FocusMeteringAction action = FocusMeteringAction.Builder
+                .from(mPoint1, MeteringMode.AF_AE_AWB)
+                .addPoint(mPoint2, MeteringMode.AF_AE_AWB)
+                .addPoint(mPoint3, MeteringMode.AF_AE_AWB)
+                .build();
+        assertThat(action.getMeteringPointsAF()).containsExactly(mPoint1, mPoint2, mPoint3);
+        assertThat(action.getMeteringPointsAE()).containsExactly(mPoint1, mPoint2, mPoint3);
+        assertThat(action.getMeteringPointsAWB()).containsExactly(mPoint1, mPoint2, mPoint3);
+    }
+
+    @Test
+    public void multiplePointsWithSameAF_AE() {
+        FocusMeteringAction action = FocusMeteringAction.Builder
+                .from(mPoint1, MeteringMode.AF_AE)
+                .addPoint(mPoint2, MeteringMode.AF_AE)
+                .addPoint(mPoint3, MeteringMode.AF_AE)
+                .build();
+        assertThat(action.getMeteringPointsAF()).containsExactly(mPoint1, mPoint2, mPoint3);
+        assertThat(action.getMeteringPointsAE()).containsExactly(mPoint1, mPoint2, mPoint3);
+        assertThat(action.getMeteringPointsAWB()).isEmpty();
+    }
+
+    @Test
+    public void multiplePointsWithSameAE_AWB() {
+        FocusMeteringAction action = FocusMeteringAction.Builder
+                .from(mPoint1, MeteringMode.AE_AWB)
+                .addPoint(mPoint2, MeteringMode.AE_AWB)
+                .addPoint(mPoint3, MeteringMode.AE_AWB)
+                .build();
+        assertThat(action.getMeteringPointsAF()).isEmpty();
+        assertThat(action.getMeteringPointsAE()).containsExactly(mPoint1, mPoint2, mPoint3);
+        assertThat(action.getMeteringPointsAWB()).containsExactly(mPoint1, mPoint2, mPoint3);
+    }
+
+    @Test
+    public void multiplePointsWithSameAF_AWB() {
+        FocusMeteringAction action = FocusMeteringAction.Builder
+                .from(mPoint1, MeteringMode.AF_AWB)
+                .addPoint(mPoint2, MeteringMode.AF_AWB)
+                .addPoint(mPoint3, MeteringMode.AF_AWB)
+                .build();
+        assertThat(action.getMeteringPointsAF()).containsExactly(mPoint1, mPoint2, mPoint3);
+        assertThat(action.getMeteringPointsAE()).isEmpty();
+        assertThat(action.getMeteringPointsAWB()).containsExactly(mPoint1, mPoint2, mPoint3);
+    }
+
+    @Test
+    public void multiplePointsWithSameAWBOnly() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
+                MeteringMode.AWB_ONLY)
+                .addPoint(mPoint2, MeteringMode.AWB_ONLY)
+                .addPoint(mPoint3, MeteringMode.AWB_ONLY)
+                .build();
+        assertThat(action.getMeteringPointsAF()).isEmpty();
+        assertThat(action.getMeteringPointsAE()).isEmpty();
+        assertThat(action.getMeteringPointsAWB()).containsExactly(mPoint1, mPoint2, mPoint3);
+    }
+
+    @Test
+    public void multiplePointsWithSameAEOnly() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
+                MeteringMode.AE_ONLY)
+                .addPoint(mPoint2, MeteringMode.AE_ONLY)
+                .addPoint(mPoint3, MeteringMode.AE_ONLY)
+                .build();
+        assertThat(action.getMeteringPointsAF()).isEmpty();
+        assertThat(action.getMeteringPointsAE()).containsExactly(mPoint1, mPoint2, mPoint3);
+        assertThat(action.getMeteringPointsAWB()).isEmpty();
+    }
+
+    @Test
+    public void multiplePointsWithSameAFOnly() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
+                MeteringMode.AF_ONLY)
+                .addPoint(mPoint2, MeteringMode.AF_ONLY)
+                .addPoint(mPoint3, MeteringMode.AF_ONLY)
+                .build();
+        assertThat(action.getMeteringPointsAF()).containsExactly(mPoint1, mPoint2, mPoint3);
+        assertThat(action.getMeteringPointsAE()).isEmpty();
+        assertThat(action.getMeteringPointsAWB()).isEmpty();
+    }
+
+    @Test
+    public void multiplePointsWithAFOnly_AEOnly_AWBOnly() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
+                MeteringMode.AF_ONLY)
+                .addPoint(mPoint2, MeteringMode.AE_ONLY)
+                .addPoint(mPoint3, MeteringMode.AWB_ONLY)
+                .build();
+        assertThat(action.getMeteringPointsAF()).containsExactly(mPoint1);
+        assertThat(action.getMeteringPointsAE()).containsExactly(mPoint2);
+        assertThat(action.getMeteringPointsAWB()).containsExactly(mPoint3);
+    }
+
+    @Test
+    public void multiplePointsWithAFAE_AEAWB_AFAWB() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
+                MeteringMode.AF_AE)
+                .addPoint(mPoint2, MeteringMode.AE_AWB)
+                .addPoint(mPoint3, MeteringMode.AF_AWB)
+                .build();
+        assertThat(action.getMeteringPointsAF()).containsExactly(mPoint1, mPoint3);
+        assertThat(action.getMeteringPointsAE()).containsExactly(mPoint2, mPoint1);
+        assertThat(action.getMeteringPointsAWB()).containsExactly(mPoint3, mPoint2);
+    }
+
+    @Test
+    public void multiplePointsWithAFAEAWB_AEAWB_AFOnly() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
+                MeteringMode.AF_AE_AWB)
+                .addPoint(mPoint2, MeteringMode.AE_AWB)
+                .addPoint(mPoint3, MeteringMode.AF_ONLY)
+                .build();
+        assertThat(action.getMeteringPointsAF()).containsExactly(mPoint1, mPoint3);
+        assertThat(action.getMeteringPointsAE()).containsExactly(mPoint1, mPoint2);
+        assertThat(action.getMeteringPointsAWB()).containsExactly(mPoint1, mPoint2);
+    }
+
+    @Test
+    public void multiplePointsWithAEOnly_AFAWAEB_AEOnly() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
+                MeteringMode.AE_ONLY)
+                .addPoint(mPoint2, MeteringMode.AF_AE_AWB)
+                .addPoint(mPoint3, MeteringMode.AE_ONLY)
+                .build();
+        assertThat(action.getMeteringPointsAF()).containsExactly(mPoint2);
+        assertThat(action.getMeteringPointsAE()).containsExactly(mPoint1, mPoint2, mPoint3);
+        assertThat(action.getMeteringPointsAWB()).containsExactly(mPoint2);
+    }
+
+    @Test
+    public void onAutoFocusListenerIsSet() {
+        MeteringPoint mPoint1 = mPointFactory.createPoint(0, 0);
+        FocusMeteringAction.OnAutoFocusListener onAutoFocusListener =
+                new FocusMeteringAction.OnAutoFocusListener() {
+                    @Override
+                    public void onFocusCompleted(boolean isFocused) {
+
+                    }
+                };
+
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1)
+                .setAutoFocusCallback(onAutoFocusListener)
+                .build();
+
+        assertThat(action.getOnAutoFocusListener()).isEqualTo(onAutoFocusListener);
+    }
+
+    @Test
+    public void onAutoFocusListenerAndExecutorIsSet() {
+        MeteringPoint mPoint1 = mPointFactory.createPoint(0, 0);
+        FocusMeteringAction.OnAutoFocusListener onAutoFocusListener =
+                Mockito.mock(FocusMeteringAction.OnAutoFocusListener.class);
+
+        Executor executor = Mockito.mock(Executor.class);
+
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1)
+                .setAutoFocusCallback(executor, onAutoFocusListener)
+                .build();
+
+        assertThat(action.getOnAutoFocusListener()).isEqualTo(onAutoFocusListener);
+        assertThat(action.getListenerExecutor()).isEqualTo(executor);
+    }
+
+    @Test
+    public void setAutoCancelDurationBySeconds() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1)
+                .setAutoCancelDuration(3, TimeUnit.SECONDS)
+                .build();
+        assertThat(action.getAutoCancelDurationInMs()).isEqualTo(3000);
+    }
+
+    @Test
+    public void setAutoCancelDurationByMinutes() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1)
+                .setAutoCancelDuration(2, TimeUnit.MINUTES)
+                .build();
+        assertThat(action.getAutoCancelDurationInMs()).isEqualTo(120000);
+    }
+
+    @Test
+    public void setAutoCancelDurationByMilliseconds() {
+        FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1)
+                .setAutoCancelDuration(1500, TimeUnit.MILLISECONDS)
+                .build();
+        assertThat(action.getAutoCancelDurationInMs()).isEqualTo(1500);
+    }
+}
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/ImageAnalysisTest.java b/camera/camera-core/src/test/java/androidx/camera/core/ImageAnalysisTest.java
index 2e22966..cec54b0 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/ImageAnalysisTest.java
+++ b/camera/camera-core/src/test/java/androidx/camera/core/ImageAnalysisTest.java
@@ -30,6 +30,7 @@
 import androidx.camera.core.impl.utils.executor.CameraXExecutors;
 import androidx.test.filters.MediumTest;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -65,6 +66,7 @@
     private Handler mBackgroundHandler;
     private Executor mBackgroundExecutor;
     private List<Image> mImagesReceived;
+    private ImageAnalysis mImageAnalysis;
 
     @Before
     public void setUp() {
@@ -82,6 +84,60 @@
         ShadowImageReader.clear();
     }
 
+    @After
+    public void tearDown() {
+        mImageAnalysis.clear();
+        mImagesReceived.clear();
+    }
+
+    @Test
+    public void nonBlockingAnalyzerClosed_imageNotAnalyzed() {
+        // Arrange.
+        setUpImageAnalysisWithMode(ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE);
+
+        // Act.
+        // Receive images from camera feed.
+        ShadowImageReader.triggerCallbackWithImage(MOCK_IMAGE_1);
+        flushHandler(mBackgroundHandler);
+        ShadowImageReader.triggerCallbackWithImage(MOCK_IMAGE_2);
+        flushHandler(mBackgroundHandler);
+
+        // Assert.
+        // No image is received because callback handler is blocked.
+        assertThat(mImagesReceived).isEmpty();
+
+        // Flush callback handler and image1 is received.
+        flushHandler(mCallbackHandler);
+        assertThat(mImagesReceived).containsExactly(MOCK_IMAGE_1);
+
+        // Clear ImageAnalysis and flush both handlers. No more image should be received because
+        // it's closed.
+        mImageAnalysis.clear();
+        flushHandler(mBackgroundHandler);
+        flushHandler(mCallbackHandler);
+        assertThat(mImagesReceived).containsExactly(MOCK_IMAGE_1);
+    }
+
+    @Test
+    public void blockingAnalyzerClosed_imageNotAnalyzed() {
+        // Arrange.
+        setUpImageAnalysisWithMode(ImageAnalysis.ImageReaderMode.ACQUIRE_NEXT_IMAGE);
+
+        // Act.
+        // Receive images from camera feed.
+        ShadowImageReader.triggerCallbackWithImage(MOCK_IMAGE_1);
+        flushHandler(mBackgroundHandler);
+
+        // Assert.
+        // No image is received because callback handler is blocked.
+        assertThat(mImagesReceived).isEmpty();
+
+        // Flush callback handler and it's still empty because it's close.
+        mImageAnalysis.clear();
+        flushHandler(mCallbackHandler);
+        assertThat(mImagesReceived).isEmpty();
+    }
+
     @Test
     public void acquireLatestMode_doesNotBlock() {
         // Arrange.
@@ -140,14 +196,14 @@
     }
 
     private void setUpImageAnalysisWithMode(ImageAnalysis.ImageReaderMode imageReaderMode) {
-        ImageAnalysis imageAnalysis = new ImageAnalysis(new ImageAnalysisConfig.Builder()
+        mImageAnalysis = new ImageAnalysis(new ImageAnalysisConfig.Builder()
                 .setCallbackHandler(mCallbackHandler)
                 .setBackgroundExecutor(mBackgroundExecutor)
                 .setImageQueueDepth(QUEUE_DEPTH)
                 .setImageReaderMode(imageReaderMode)
                 .build());
 
-        imageAnalysis.setAnalyzer(new ImageAnalysis.Analyzer() {
+        mImageAnalysis.setAnalyzer(new ImageAnalysis.Analyzer() {
             @Override
             public void analyze(ImageProxy image, int rotationDegrees) {
                 mImagesReceived.add(image.getImage());
@@ -156,7 +212,7 @@
 
         Map<String, Size> suggestedResolutionMap = new HashMap<>();
         suggestedResolutionMap.put(ShadowCameraX.DEFAULT_CAMERA_ID, DEFAULT_RESOLUTION);
-        imageAnalysis.updateSuggestedResolution(suggestedResolutionMap);
+        mImageAnalysis.updateSuggestedResolution(suggestedResolutionMap);
     }
 
     /**
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/ShadowImageReader.java b/camera/camera-core/src/test/java/androidx/camera/core/ShadowImageReader.java
index 40b067d..ed5d2c3 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/ShadowImageReader.java
+++ b/camera/camera-core/src/test/java/androidx/camera/core/ShadowImageReader.java
@@ -63,6 +63,11 @@
         sShadowImageReader.getListener().onImageAvailable(sImageReader);
     }
 
+    @Implementation
+    public void close() {
+        // no-op.
+    }
+
     /**
      * Clears incoming images.
      */
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionTest.java b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionTest.java
index 471b902..a33632d9 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionTest.java
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionTest.java
@@ -37,6 +37,7 @@
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CaptureRequest;
+import android.os.Build;
 
 import androidx.annotation.NonNull;
 import androidx.camera.camera2.Camera2AppConfig;
@@ -60,6 +61,7 @@
 import androidx.camera.testing.fakes.FakeLifecycleOwner;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.filters.LargeTest;
+import androidx.test.filters.SdkSuppress;
 import androidx.test.rule.GrantPermissionRule;
 
 import org.junit.After;
@@ -77,6 +79,7 @@
 
 @RunWith(Parameterized.class)
 @LargeTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.M)
 public class ExtensionTest {
 
     @Rule
@@ -195,7 +198,7 @@
 
         // Verify the take picture should not have any error happen.
         verify(mockOnImageCapturedListener, never()).onError(
-                any(ImageCapture.UseCaseError.class), anyString(), any(Throwable.class));
+                any(ImageCapture.ImageCaptureError.class), anyString(), any(Throwable.class));
     }
 
     @Test
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsErrorListenerTest.java b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsErrorListenerTest.java
index 1cc603b..3bd8dac 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsErrorListenerTest.java
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsErrorListenerTest.java
@@ -49,6 +49,7 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
+import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 import androidx.test.rule.GrantPermissionRule;
 
@@ -68,6 +69,7 @@
 /**
  * Unit tests for {@link androidx.camera.extensions.ExtensionsErrorListener}.
  * */
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.M)
 public final class ExtensionsErrorListenerTest {
     @Rule
     public GrantPermissionRule mRuntimePermissionRule = GrantPermissionRule.grant(
@@ -97,10 +99,6 @@
 
     @Before
     public void setUp() {
-        // Ignore the tests if SDK is before M since extension implementation is only supported
-        // after M.
-        assumeTrue(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M);
-
         Context context = ApplicationProvider.getApplicationContext();
         CameraDeviceSurfaceManager surfaceManager = new FakeCameraDeviceSurfaceManager();
         ExtendableUseCaseConfigFactory defaultConfigFactory = new ExtendableUseCaseConfigFactory();
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
index 64378b6..8182818 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
@@ -17,6 +17,7 @@
 
 import android.os.Handler;
 import android.os.Looper;
+import android.util.Log;
 
 import androidx.annotation.GuardedBy;
 import androidx.annotation.Nullable;
@@ -31,6 +32,7 @@
  * functions.
  */
 public final class ExtensionsManager {
+    private static final String TAG = "ExtensionsManager";
     /** The effect mode options applied on the bound use cases */
     public enum EffectMode {
         /** Normal mode without any specific effect applied. */
@@ -75,8 +77,16 @@
      * @return True if the specific extension function is supported for the camera device.
      */
     public static boolean isExtensionAvailable(EffectMode effectMode, LensFacing lensFacing) {
-        return checkImageCaptureExtensionCapability(effectMode, lensFacing)
-                || checkPreviewExtensionCapability(effectMode, lensFacing);
+        boolean isImageCaptureAvailable = checkImageCaptureExtensionCapability(effectMode,
+                lensFacing);
+        boolean isPreviewAvailable = checkPreviewExtensionCapability(effectMode, lensFacing);
+
+        if (isImageCaptureAvailable != isPreviewAvailable) {
+            Log.e(TAG, "ImageCapture and Preview are not available simultaneously for "
+                    + effectMode.name());
+        }
+
+        return isImageCaptureAvailable && isPreviewAvailable;
     }
 
     /**
diff --git a/camera/camera-testing/build.gradle b/camera/camera-testing/build.gradle
index 396ab3c..87b88cc 100644
--- a/camera/camera-testing/build.gradle
+++ b/camera/camera-testing/build.gradle
@@ -33,6 +33,13 @@
     implementation("androidx.core:core:1.1.0-rc01")
     implementation("androidx.concurrent:concurrent-futures:1.0.0-alpha03")
     implementation(JUNIT)
+
+    testImplementation(ANDROIDX_TEST_CORE)
+    testImplementation(ANDROIDX_TEST_RUNNER)
+    testImplementation(JUNIT)
+    testImplementation(TRUTH)
+    testImplementation(ROBOLECTRIC)
+    testImplementation(MOCKITO_CORE)
 }
 
 android {
diff --git a/camera/camera-testing/lint-baseline.xml b/camera/camera-testing/lint-baseline.xml
index 0255bbf..1a680f2 100644
--- a/camera/camera-testing/lint-baseline.xml
+++ b/camera/camera-testing/lint-baseline.xml
@@ -609,72 +609,6 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="    public BaseCamera getCamera(String cameraId) {"
-        errorLine2="           ~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java"
-            line="56"
-            column="12"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="    public BaseCamera getCamera(String cameraId) {"
-        errorLine2="                                ~~~~~~">
-        <location
-            file="src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java"
-            line="56"
-            column="33"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="    public void insertCamera(String cameraId, BaseCamera camera) {"
-        errorLine2="                             ~~~~~~">
-        <location
-            file="src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java"
-            line="74"
-            column="30"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="    public void insertCamera(String cameraId, BaseCamera camera) {"
-        errorLine2="                                              ~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java"
-            line="74"
-            column="47"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="    public Set&lt;String> getAvailableCameraIds() {"
-        errorLine2="           ~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java"
-            line="85"
-            column="12"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="    public String cameraIdForLensFacing(LensFacing lensFacing) {"
-        errorLine2="                                        ~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java"
-            line="91"
-            column="41"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
         errorLine1="    public FakeCameraInfo(int sensorRotation, LensFacing lensFacing) {"
         errorLine2="                                              ~~~~~~~~~~">
         <location
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCamera.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCamera.java
index a8b083c..541eda4 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCamera.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCamera.java
@@ -20,6 +20,7 @@
 import android.util.Log;
 import android.view.Surface;
 
+import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.camera.core.BaseCamera;
@@ -28,9 +29,15 @@
 import androidx.camera.core.CaptureConfig;
 import androidx.camera.core.DeferrableSurface;
 import androidx.camera.core.DeferrableSurfaces;
+import androidx.camera.core.Observable;
 import androidx.camera.core.SessionConfig;
 import androidx.camera.core.UseCase;
 import androidx.camera.core.UseCaseAttachState;
+import androidx.camera.core.impl.LiveDataObservable;
+import androidx.camera.core.impl.utils.futures.Futures;
+import androidx.core.util.Preconditions;
+
+import com.google.common.util.concurrent.ListenableFuture;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -43,11 +50,14 @@
 public class FakeCamera implements BaseCamera {
     private static final String TAG = "FakeCamera";
     private static final String DEFAULT_CAMERA_ID = "0";
+    private final LiveDataObservable<BaseCamera.State> mObservableState =
+            new LiveDataObservable<>();
     private final CameraControlInternal mCameraControlInternal;
     private final CameraInfo mCameraInfo;
     private String mCameraId;
     private UseCaseAttachState mUseCaseAttachState;
-    private State mState = State.INITIALIZED;
+    private State mState = State.CLOSED;
+    private int mAvailableCameraCount = 1;
 
     @Nullable
     private SessionConfig mSessionConfig;
@@ -60,54 +70,107 @@
         this(DEFAULT_CAMERA_ID, new FakeCameraInfo(), /*cameraControl=*/null);
     }
 
-    public FakeCamera(String cameraId) {
+    public FakeCamera(@NonNull String cameraId) {
         this(cameraId, new FakeCameraInfo(), /*cameraControl=*/null);
     }
 
-    public FakeCamera(CameraInfo cameraInfo, @Nullable CameraControlInternal cameraControl) {
+    public FakeCamera(@NonNull CameraInfo cameraInfo,
+            @Nullable CameraControlInternal cameraControl) {
         this(DEFAULT_CAMERA_ID, cameraInfo, cameraControl);
     }
 
-    public FakeCamera(String cameraId,
-            CameraInfo cameraInfo,
+    public FakeCamera(@NonNull String cameraId,
+            @NonNull CameraInfo cameraInfo,
             @Nullable CameraControlInternal cameraControl) {
         mCameraInfo = cameraInfo;
         mCameraId = cameraId;
         mUseCaseAttachState = new UseCaseAttachState(cameraId);
         mCameraControlInternal = cameraControl == null ? new FakeCameraControl(this)
                 : cameraControl;
+        mObservableState.postValue(State.CLOSED);
+    }
+
+    /**
+     * Sets the number of cameras that are available to open.
+     *
+     * <p>If this number is set to 0, then calling {@link #open()} will wait in a {@code
+     * PENDING_OPEN} state until the number is set to a value greater than 0 before entering an
+     * {@code OPEN} state.
+     *
+     * @param count An integer number greater than 0 representing the number of available cameras
+     *              to open on this device.
+     */
+    public void setAvailableCameraCount(@IntRange(from = 0) int count) {
+        Preconditions.checkArgumentNonnegative(count);
+        mAvailableCameraCount = count;
+        if (mAvailableCameraCount > 0 && mState == State.PENDING_OPEN) {
+            open();
+        }
+    }
+
+    /**
+     * Retrieves the number of cameras available to open on this device, as seen by this camera.
+     *
+     * @return An integer number greater than 0 representing the number of available cameras to
+     * open on this device.
+     */
+    @IntRange(from = 0)
+    public int getAvailableCameraCount() {
+        return mAvailableCameraCount;
     }
 
     @Override
     public void open() {
         checkNotReleased();
-        if (mState == State.INITIALIZED) {
-            mState = State.OPENED;
+        if (mState == State.CLOSED || mState == State.PENDING_OPEN) {
+            if (mAvailableCameraCount > 0) {
+                mState = State.OPEN;
+                mObservableState.postValue(State.OPEN);
+            } else {
+                mState = State.PENDING_OPEN;
+                mObservableState.postValue(State.PENDING_OPEN);
+            }
         }
     }
 
     @Override
     public void close() {
         checkNotReleased();
-        if (mState == State.OPENED) {
-            mSessionConfig = null;
-            reconfigure();
-            mState = State.INITIALIZED;
+        switch (mState) {
+            case OPEN:
+                mSessionConfig = null;
+                reconfigure();
+                // fall through
+            case PENDING_OPEN:
+                mState = State.CLOSED;
+                mObservableState.postValue(State.CLOSED);
+                break;
+            default:
+                break;
         }
     }
 
     @Override
-    public void release() {
+    @NonNull
+    public ListenableFuture<Void> release() {
         checkNotReleased();
-        if (mState == State.OPENED) {
+        if (mState == State.OPEN) {
             close();
         }
 
         mState = State.RELEASED;
+        mObservableState.postValue(State.RELEASED);
+        return Futures.immediateFuture(null);
+    }
+
+    @NonNull
+    @Override
+    public Observable<BaseCamera.State> getCameraState() {
+        return mObservableState;
     }
 
     @Override
-    public void onUseCaseActive(final UseCase useCase) {
+    public void onUseCaseActive(@NonNull UseCase useCase) {
         Log.d(TAG, "Use case " + useCase + " ACTIVE for camera " + mCameraId);
 
         mUseCaseAttachState.setUseCaseActive(useCase);
@@ -116,7 +179,7 @@
 
     /** Removes the use case from a state of issuing capture requests. */
     @Override
-    public void onUseCaseInactive(final UseCase useCase) {
+    public void onUseCaseInactive(@NonNull UseCase useCase) {
         Log.d(TAG, "Use case " + useCase + " INACTIVE for camera " + mCameraId);
 
         mUseCaseAttachState.setUseCaseInactive(useCase);
@@ -125,7 +188,7 @@
 
     /** Updates the capture requests based on the latest settings. */
     @Override
-    public void onUseCaseUpdated(final UseCase useCase) {
+    public void onUseCaseUpdated(@NonNull UseCase useCase) {
         Log.d(TAG, "Use case " + useCase + " UPDATED for camera " + mCameraId);
 
         mUseCaseAttachState.updateUseCase(useCase);
@@ -133,7 +196,7 @@
     }
 
     @Override
-    public void onUseCaseReset(@NonNull final UseCase useCase) {
+    public void onUseCaseReset(@NonNull UseCase useCase) {
         Log.d(TAG, "Use case " + useCase + " RESET for camera " + mCameraId);
 
         mUseCaseAttachState.updateUseCase(useCase);
@@ -146,7 +209,7 @@
      * capture requests from the use case.
      */
     @Override
-    public void addOnlineUseCase(final Collection<UseCase> useCases) {
+    public void addOnlineUseCase(@NonNull final Collection<UseCase> useCases) {
         if (useCases.isEmpty()) {
             return;
         }
@@ -166,7 +229,7 @@
      * handle capture requests from the use case.
      */
     @Override
-    public void removeOnlineUseCase(final Collection<UseCase> useCases) {
+    public void removeOnlineUseCase(@NonNull final Collection<UseCase> useCases) {
         if (useCases.isEmpty()) {
             return;
         }
@@ -187,11 +250,13 @@
 
     // Returns fixed CameraControlInternal instance in order to verify the instance is correctly
     // attached.
+    @NonNull
     @Override
     public CameraControlInternal getCameraControlInternal() {
         return mCameraControlInternal;
     }
 
+    @NonNull
     @Override
     public CameraInfo getCameraInfo() {
         return mCameraInfo;
@@ -222,7 +287,7 @@
             return;
         }
 
-        if (mState != State.OPENED) {
+        if (mState != State.OPEN) {
             Log.d(TAG, "CameraDevice is not opened");
             return;
         }
@@ -238,7 +303,9 @@
         if (validatingBuilder.isValid()) {
             // Apply CameraControlInternal's SessionConfig to let CameraControlInternal be able
             // to control Repeating Request and process results.
-            validatingBuilder.add(mCameraControlSessionConfig);
+            if (mCameraControlSessionConfig != null) {
+                validatingBuilder.add(mCameraControlSessionConfig);
+            }
 
             mSessionConfig = validatingBuilder.build();
         }
@@ -283,20 +350,4 @@
         // notifySurfaceDetached calls.
         mConfiguredDeferrableSurfaces.clear();
     }
-
-    enum State {
-        /**
-         * Stable state once the camera has been constructed.
-         */
-        INITIALIZED,
-        /**
-         * A stable state where the camera has been opened.
-         */
-        OPENED,
-        /**
-         * A stable state where the camera has been permanently closed.
-         */
-        RELEASED
-    }
-
 }
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraControl.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraControl.java
index 683f5fa..37de5a7 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraControl.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraControl.java
@@ -16,7 +16,6 @@
 
 package androidx.camera.testing.fakes;
 
-import android.annotation.SuppressLint;
 import android.graphics.Rect;
 import android.util.Log;
 
@@ -25,11 +24,10 @@
 import androidx.camera.core.CameraControlInternal;
 import androidx.camera.core.CaptureConfig;
 import androidx.camera.core.FlashMode;
-import androidx.camera.core.OnFocusListener;
+import androidx.camera.core.FocusMeteringAction;
 import androidx.camera.core.SessionConfig;
 
 import java.util.List;
-import java.util.concurrent.Executor;
 
 /**
  * A fake implementation for the CameraControlInternal interface.
@@ -51,21 +49,6 @@
         Log.d(TAG, "setCropRegion(" + crop + ")");
     }
 
-    @SuppressLint("LambdaLast") // Remove after https://issuetracker.google.com/135275901
-    @Override
-    public void focus(
-            @NonNull final Rect focus,
-            @NonNull final Rect metering,
-            @NonNull final Executor listenerExecutor,
-            @NonNull final OnFocusListener listener) {
-        focus(focus, metering);
-    }
-
-    @Override
-    public void focus(@NonNull Rect focus, @NonNull Rect metering) {
-        Log.d(TAG, "focus(\n    " + focus + ",\n    " + metering + ")");
-    }
-
     @NonNull
     @Override
     public FlashMode getFlashMode() {
@@ -90,11 +73,6 @@
     }
 
     @Override
-    public boolean isFocusLocked() {
-        return false;
-    }
-
-    @Override
     public void triggerAf() {
         Log.d(TAG, "triggerAf()");
     }
@@ -119,4 +97,12 @@
     private void updateSessionConfig() {
         mControlUpdateListener.onCameraControlUpdateSessionConfig(mSessionConfigBuilder.build());
     }
+
+    @Override
+    public void startFocusAndMetering(FocusMeteringAction action) {
+    }
+
+    @Override
+    public void cancelFocusAndMetering() {
+    }
 }
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java
index e470bda..f892b8c 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java
@@ -59,7 +59,8 @@
     }
 
     @Override
-    public BaseCamera getCamera(String cameraId) {
+    @NonNull
+    public BaseCamera getCamera(@NonNull String cameraId) {
         if (mCameraIds.contains(cameraId)) {
             BaseCamera camera = mCameraMap.get(cameraId);
             if (camera == null) {
@@ -77,7 +78,7 @@
      * @param cameraId Identifier to use for the camera.
      * @param camera   Camera implementation.
      */
-    public void insertCamera(String cameraId, BaseCamera camera) {
+    public void insertCamera(@NonNull String cameraId, @NonNull BaseCamera camera) {
         if (!mCameraIds.contains(cameraId)) {
             HashSet<String> newCameraIds = new HashSet<>(mCameraIds);
             newCameraIds.add(cameraId);
@@ -87,7 +88,26 @@
         mCameraMap.put(cameraId, camera);
     }
 
+    /**
+     * Inserts a camera with front camera id.
+     *
+     * @param camera Camera implementation.
+     */
+    public void insertFrontCamera(@NonNull BaseCamera camera) {
+        insertCamera(FRONT_ID, camera);
+    }
+
+    /**
+     * Inserts a camera with back camera id.
+     *
+     * @param camera Camera implementation.
+     */
+    public void insertBackCamera(@NonNull BaseCamera camera) {
+        insertCamera(BACK_ID, camera);
+    }
+
     @Override
+    @NonNull
     public Set<String> getAvailableCameraIds() {
         return mCameraIds;
     }
diff --git a/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraDeviceSurfaceManagerTest.java b/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraDeviceSurfaceManagerTest.java
new file mode 100644
index 0000000..5fc3689
--- /dev/null
+++ b/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraDeviceSurfaceManagerTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2019 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.camera.testing.fakes;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+
+import android.os.Build;
+import android.util.Size;
+
+import androidx.camera.core.UseCase;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.internal.DoNotInstrument;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+@SmallTest
+@RunWith(RobolectricTestRunner.class)
+@DoNotInstrument
+@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
+public class FakeCameraDeviceSurfaceManagerTest {
+
+    private static final int FAKE_WIDTH0 = 400;
+    private static final int FAKE_HEIGHT0 = 300;
+
+    private static final int FAKE_WIDTH1 = 800;
+    private static final int FAKE_HEIGHT1 = 600;
+
+    private static final String FAKE_CAMERA_ID0 = "0";
+    private static final String FAKE_CAMERA_ID1 = "1";
+
+    private FakeCameraDeviceSurfaceManager mFakeCameraDeviceSurfaceManager;
+
+    private FakeUseCase mFakeUseCase;
+
+    private List<UseCase> mUseCaseList;
+
+    @Before
+    public void setUp() {
+        mFakeCameraDeviceSurfaceManager = new FakeCameraDeviceSurfaceManager();
+        mFakeUseCase = mock(FakeUseCase.class);
+
+        mFakeCameraDeviceSurfaceManager.setSuggestedResolution(FAKE_CAMERA_ID0,
+                mFakeUseCase.getClass(), new Size(FAKE_WIDTH0, FAKE_HEIGHT0));
+        mFakeCameraDeviceSurfaceManager.setSuggestedResolution(FAKE_CAMERA_ID1,
+                mFakeUseCase.getClass(), new Size(FAKE_WIDTH1, FAKE_HEIGHT1));
+
+        mUseCaseList = Collections.singletonList((UseCase) mFakeUseCase);
+    }
+
+    @Test
+    public void canRetrieveInsertedSuggestedResolutions() {
+        Map<UseCase, Size> suggestedSizesCamera0 =
+                mFakeCameraDeviceSurfaceManager.getSuggestedResolutions(FAKE_CAMERA_ID0,
+                        Collections.<UseCase>emptyList(), mUseCaseList);
+        Map<UseCase, Size> suggestedSizesCamera1 =
+                mFakeCameraDeviceSurfaceManager.getSuggestedResolutions(FAKE_CAMERA_ID1,
+                        Collections.<UseCase>emptyList(), mUseCaseList);
+
+        assertThat(suggestedSizesCamera0.get(mFakeUseCase)).isEqualTo(
+                new Size(FAKE_WIDTH0, FAKE_HEIGHT0));
+        assertThat(suggestedSizesCamera1.get(mFakeUseCase)).isEqualTo(
+                new Size(FAKE_WIDTH1, FAKE_HEIGHT1));
+
+    }
+
+}
diff --git a/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraInfoTest.java b/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraInfoTest.java
new file mode 100644
index 0000000..3c11b96
--- /dev/null
+++ b/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraInfoTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2019 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.camera.testing.fakes;
+
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Build;
+
+import androidx.camera.core.CameraX;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.internal.DoNotInstrument;
+
+@SmallTest
+@RunWith(RobolectricTestRunner.class)
+@DoNotInstrument
+@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
+public final class FakeCameraInfoTest {
+
+    private static final int SENSOR_ROTATION_DEGREES = 90;
+    private static final CameraX.LensFacing LENS_FACING = CameraX.LensFacing.FRONT;
+
+    private FakeCameraInfo mFakeCameraInfo;
+
+    @Before
+    public void setUp() {
+        mFakeCameraInfo = new FakeCameraInfo(SENSOR_ROTATION_DEGREES, LENS_FACING);
+    }
+
+    @Test
+    public void canRetrieveLensFacingDirection() {
+        assertThat(mFakeCameraInfo.getLensFacing()).isSameInstanceAs(LENS_FACING);
+    }
+
+    @Test
+    public void canRetrieveSensorRotation() {
+        assertThat(mFakeCameraInfo.getSensorRotationDegrees()).isEqualTo(SENSOR_ROTATION_DEGREES);
+    }
+}
diff --git a/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraTest.java b/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraTest.java
new file mode 100644
index 0000000..8648c44a
--- /dev/null
+++ b/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2019 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.camera.testing.fakes;
+
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.camera.core.BaseCamera;
+import androidx.camera.core.Observable;
+import androidx.camera.core.impl.utils.executor.CameraXExecutors;
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.internal.DoNotInstrument;
+import org.robolectric.shadows.ShadowLooper;
+
+@SmallTest
+@RunWith(RobolectricTestRunner.class)
+@DoNotInstrument
+@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
+public final class FakeCameraTest {
+
+    private FakeCamera mCamera;
+    private BaseCamera.State mLatestState;
+    private Observable.Observer<BaseCamera.State> mStateObserver =
+            new Observable.Observer<BaseCamera.State>() {
+                @Override
+                public void onNewData(@Nullable BaseCamera.State value) {
+                    mLatestState = value;
+                }
+
+                @Override
+                public void onError(@NonNull Throwable t) {
+
+                }
+            };
+
+    @Before
+    public void setUp() {
+        mCamera = new FakeCamera();
+        mCamera.getCameraState().addObserver(CameraXExecutors.directExecutor(), mStateObserver);
+        ShadowLooper.runUiThreadTasks();
+    }
+
+    @After
+    public void tearDown() {
+        mCamera.getCameraState().removeObserver(mStateObserver);
+    }
+
+    @Test
+    public void cameraEntersOpenState_whenOpened() {
+        mCamera.open();
+        ShadowLooper.runUiThreadTasks();
+        assertThat(mLatestState).isEqualTo(BaseCamera.State.OPEN);
+    }
+
+    @Test
+    public void cameraIsInClosedState_whenInitialized() {
+        assertThat(mLatestState).isEqualTo(BaseCamera.State.CLOSED);
+    }
+
+    @Test
+    public void cameraEntersPendingState_whenOpened_withZeroCamerasAvailable() {
+        mCamera.setAvailableCameraCount(0);
+        mCamera.open();
+        ShadowLooper.runUiThreadTasks();
+        assertThat(mLatestState).isEqualTo(BaseCamera.State.PENDING_OPEN);
+    }
+
+    @Test
+    public void cameraEntersOpenState_whenCameraBecomesAvailable() {
+        mCamera.setAvailableCameraCount(0);
+        mCamera.open();
+        ShadowLooper.runUiThreadTasks();
+        BaseCamera.State intermediateState = mLatestState;
+        mCamera.setAvailableCameraCount(1);
+        ShadowLooper.runUiThreadTasks();
+
+        assertThat(intermediateState).isEqualTo(BaseCamera.State.PENDING_OPEN);
+        assertThat(mLatestState).isEqualTo(BaseCamera.State.OPEN);
+    }
+
+    @Test
+    public void cameraCanBeClosed_afterOpened() {
+        mCamera.open();
+        ShadowLooper.runUiThreadTasks();
+        BaseCamera.State intermediateState = mLatestState;
+        mCamera.close();
+        ShadowLooper.runUiThreadTasks();
+
+        assertThat(intermediateState).isEqualTo(BaseCamera.State.OPEN);
+        assertThat(mLatestState).isEqualTo(BaseCamera.State.CLOSED);
+    }
+
+    @Test
+    public void cameraCanBeClosed_fromPendingState() {
+        mCamera.setAvailableCameraCount(0);
+        mCamera.open();
+        ShadowLooper.runUiThreadTasks();
+        BaseCamera.State intermediateState = mLatestState;
+        mCamera.close();
+        ShadowLooper.runUiThreadTasks();
+
+        assertThat(intermediateState).isEqualTo(BaseCamera.State.PENDING_OPEN);
+        assertThat(mLatestState).isEqualTo(BaseCamera.State.CLOSED);
+    }
+
+    @Test
+    public void canSetAndRetrieveAvailableCameraCount() {
+        mCamera.setAvailableCameraCount(400);
+        assertThat(mCamera.getAvailableCameraCount()).isEqualTo(400);
+    }
+}
diff --git a/camera/camera-view/build.gradle b/camera/camera-view/build.gradle
index a222329..8c3f455 100644
--- a/camera/camera-view/build.gradle
+++ b/camera/camera-view/build.gradle
@@ -29,6 +29,15 @@
     implementation("androidx.annotation:annotation:1.0.0")
 
     api(project(":camera:camera-core"))
+    androidTestImplementation(project(":camera:camera-testing"))
+    androidTestImplementation(MOCKITO_CORE)
+    androidTestImplementation(ESPRESSO_CORE)
+    androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
+    androidTestImplementation(ANDROIDX_TEST_CORE)
+    androidTestImplementation(ANDROIDX_TEST_RUNNER)
+    androidTestImplementation(ANDROIDX_TEST_RULES)
+    androidTestImplementation(TRUTH)
+    androidTestImplementation(project(":camera:camera-camera2"))
 }
 android {
     defaultConfig {
diff --git a/camera/camera-view/src/androidTest/AndroidManifest.xml b/camera/camera-view/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..f6bc677
--- /dev/null
+++ b/camera/camera-view/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.camera.camera2.view">
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
+    <application>
+         <activity
+            android:name="androidx.camera.testing.fakes.FakeActivity"
+            android:label="Fake Activity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/camera/camera-view/src/androidTest/java/androidx/camera/view/TextureViewMeteringPointFactoryTest.java b/camera/camera-view/src/androidTest/java/androidx/camera/view/TextureViewMeteringPointFactoryTest.java
new file mode 100644
index 0000000..c928e91
--- /dev/null
+++ b/camera/camera-view/src/androidTest/java/androidx/camera/view/TextureViewMeteringPointFactoryTest.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright 2019 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.camera.view;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.SurfaceTexture;
+import android.hardware.camera2.CameraDevice;
+import android.view.TextureView;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.camera.camera2.Camera2AppConfig;
+import androidx.camera.camera2.Camera2Config;
+import androidx.camera.core.AppConfig;
+import androidx.camera.core.CameraX;
+import androidx.camera.core.DisplayOrientedMeteringPointFactory;
+import androidx.camera.core.MeteringPoint;
+import androidx.camera.core.MeteringPointFactory;
+import androidx.camera.core.Preview;
+import androidx.camera.core.PreviewConfig;
+import androidx.camera.testing.CameraUtil;
+import androidx.camera.testing.fakes.FakeActivity;
+import androidx.camera.testing.fakes.FakeLifecycleOwner;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.LargeTest;
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.rule.GrantPermissionRule;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class TextureViewMeteringPointFactoryTest {
+    public static final float TOLERANCE = 0.000001f;
+    @Rule
+    public GrantPermissionRule mRuntimePermissionRule = GrantPermissionRule.grant(
+            Manifest.permission.CAMERA);
+    @Rule
+    public ActivityTestRule<FakeActivity> mActivityRule =
+            new ActivityTestRule<>(FakeActivity.class);
+
+    private void setContentView(View view) throws Throwable {
+        final Activity activity = mActivityRule.getActivity();
+        mActivityRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                activity.setContentView(view);
+            }
+        });
+    }
+
+    private static final int WAIT_FRAMECOUNT = 1;
+    private FakeLifecycleOwner mLifecycle;
+    private CountDownLatch mLatchForFrameReady;
+    private CountDownLatch mLatchForCameraClose;
+    private Context mContext;
+    private TextureView mTextureView;
+    private int mWidth;
+    private int mHeight;
+
+    @Before
+    public void setUp() throws Throwable {
+        assumeTrue(CameraUtil.deviceHasCamera());
+        mContext = ApplicationProvider.getApplicationContext();
+        AppConfig config = Camera2AppConfig.create(mContext);
+        CameraX.init(mContext, config);
+        mLifecycle = new FakeLifecycleOwner();
+        mLatchForFrameReady = new CountDownLatch(1);
+        mLatchForCameraClose = new CountDownLatch(1);
+        mTextureView = new TextureView(mContext);
+        setContentView(mTextureView);
+    }
+
+    @After
+    public void tearDown() throws InterruptedException {
+        CameraX.unbindAll();
+        mLatchForCameraClose.await(3, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void backCamera_translatedPoint_SameAsDisplayOriented() throws Throwable {
+        startAndWaitForCameraReady(CameraX.LensFacing.BACK);
+
+        TextureViewMeteringPointFactory factory = new TextureViewMeteringPointFactory(mTextureView);
+
+        // Creates the DisplayOrientedMeteringPointFactory with same width / height as TextureView
+        DisplayOrientedMeteringPointFactory displayFactory =
+                new DisplayOrientedMeteringPointFactory(mContext, CameraX.LensFacing.BACK,
+                        mTextureView.getWidth(), mTextureView.getHeight());
+
+        // Uses DisplayOrientedMeteringPointFactory to verify if coordinates are correct.
+        // DisplayOrientedMeteringPointFactory has the same width / height as the TextureView and
+        // TextureViewMeteringPointFactory
+        assertFactoryOuputSamePoints(factory, displayFactory);
+    }
+
+    @Test
+    public void frontCamera_translatedPoint_SameAsDisplayOriented() throws Throwable {
+        startAndWaitForCameraReady(CameraX.LensFacing.FRONT);
+
+        TextureViewMeteringPointFactory factory = new TextureViewMeteringPointFactory(mTextureView);
+
+        // Creates the DisplayOrientedMeteringPointFactory with same width / height as TextureView
+        DisplayOrientedMeteringPointFactory displayFactory =
+                new DisplayOrientedMeteringPointFactory(mContext, CameraX.LensFacing.FRONT,
+                        mWidth, mHeight);
+
+        // Uses DisplayOrientedMeteringPointFactory to verify if coordinates are correct.
+        // DisplayOrientedMeteringPointFactory has the same width / height as the TextureView and
+        // TextureViewMeteringPointFactory
+        assertFactoryOuputSamePoints(factory, displayFactory);
+
+    }
+
+
+    @Test
+    public void xy_OutOfRange() throws Throwable {
+        startAndWaitForCameraReady(CameraX.LensFacing.BACK);
+
+        TextureViewMeteringPointFactory factory = new TextureViewMeteringPointFactory(mTextureView);
+
+        // if x or y is not in range [0.. width or height],  the output will not be valid normalized
+        // point ( value not in [0..1])
+        MeteringPoint pt1 = factory.createPoint(-1, 0);
+        assertThat(isValid(pt1)).isFalse();
+
+        pt1 = factory.createPoint(0, -1);
+        assertThat(isValid(pt1)).isFalse();
+
+        pt1 = factory.createPoint(mWidth + 1, 0);
+        assertThat(isValid(pt1)).isFalse();
+
+        pt1 = factory.createPoint(0, mHeight + 1);
+        assertThat(isValid(pt1)).isFalse();
+
+        pt1 = factory.createPoint(-1, mHeight + 1);
+        assertThat(isValid(pt1)).isFalse();
+
+        pt1 = factory.createPoint(mWidth + 1, mHeight + 1);
+        assertThat(isValid(pt1)).isFalse();
+
+        pt1 = factory.createPoint(-1, -1);
+        assertThat(isValid(pt1)).isFalse();
+
+    }
+
+    private boolean isValid(MeteringPoint pt) {
+        boolean xValid = pt.getNormalizedCropRegionX() >= 0 && pt.getNormalizedCropRegionX() <= 1f;
+        boolean yValid = pt.getNormalizedCropRegionY() >= 0 && pt.getNormalizedCropRegionY() <= 1f;
+        return xValid && yValid;
+    }
+
+    private void startAndWaitForCameraReady(CameraX.LensFacing lensFacing)
+            throws InterruptedException {
+        PreviewConfig.Builder previewConfigBuilder =
+                new PreviewConfig.Builder()
+                        .setLensFacing(lensFacing);
+
+        new Camera2Config.Extender(previewConfigBuilder)
+                .setDeviceStateCallback(new CameraDevice.StateCallback() {
+                    @Override
+                    public void onOpened(@NonNull CameraDevice cameraDevice) {
+                    }
+
+                    @Override
+                    public void onClosed(@NonNull CameraDevice camera) {
+                        mLatchForCameraClose.countDown();
+                    }
+
+                    @Override
+                    public void onDisconnected(@NonNull CameraDevice cameraDevice) {
+                    }
+
+                    @Override
+                    public void onError(@NonNull CameraDevice cameraDevice, int i) {
+                    }
+                });
+
+        Preview preview = new Preview(previewConfigBuilder.build());
+        preview.setOnPreviewOutputUpdateListener(
+                new Preview.OnPreviewOutputUpdateListener() {
+                    @Override
+                    public void onUpdated(Preview.PreviewOutput output) {
+                        mActivityRule.getActivity().runOnUiThread(new Runnable() {
+                            @Override
+                            public void run() {
+                                ViewGroup viewGroup = (ViewGroup) mTextureView.getParent();
+                                viewGroup.removeView(mTextureView);
+                                viewGroup.addView(mTextureView);
+
+                                mTextureView.setSurfaceTexture(output.getSurfaceTexture());
+                                output.getSurfaceTexture().setOnFrameAvailableListener(
+                                        new SurfaceTexture.OnFrameAvailableListener() {
+                                            int mFrameCount = 0;
+                                            @Override
+                                            public void onFrameAvailable(
+                                                    SurfaceTexture surfaceTexture) {
+                                                mFrameCount++;
+                                                if (mFrameCount == WAIT_FRAMECOUNT) {
+                                                    mLatchForFrameReady.countDown();
+                                                }
+                                            }
+                                        });
+                            }
+                        });
+                    }
+                });
+
+        // SurfaceTexture#getTransformMatrix is initialized properly when camera starts to ouput.
+        CameraX.bindToLifecycle(mLifecycle, preview);
+        mLifecycle.startAndResume();
+
+        mLatchForFrameReady.await(3, TimeUnit.SECONDS);
+        mWidth = mTextureView.getWidth();
+        mHeight = mTextureView.getHeight();
+    }
+
+    private void assertFactoryOuputSamePoints(MeteringPointFactory factory1,
+            MeteringPointFactory factory2) {
+        MeteringPoint point1;
+        MeteringPoint point2;
+
+        // left-top corner
+        point1 = factory1.createPoint(0f, 0f);
+        point2 = factory2.createPoint(0f, 0f);
+        assertThat(isValid(point1)).isTrue();
+        Assert.assertEquals(point1.getNormalizedCropRegionX(), point2.getNormalizedCropRegionX(),
+                TOLERANCE);
+        Assert.assertEquals(point1.getNormalizedCropRegionY(), point2.getNormalizedCropRegionY(),
+                TOLERANCE);
+
+        // left-bottom corner
+        point1 = factory1.createPoint(0f, mHeight);
+        point2 = factory2.createPoint(0f, mHeight);
+
+        assertThat(isValid(point1)).isTrue();
+        Assert.assertEquals(point1.getNormalizedCropRegionX(), point2.getNormalizedCropRegionX(),
+                TOLERANCE);
+        Assert.assertEquals(point1.getNormalizedCropRegionY(), point2.getNormalizedCropRegionY(),
+                TOLERANCE);
+
+        // right-top corner
+        point1 = factory1.createPoint(mWidth, 0f);
+        point2 = factory2.createPoint(mWidth, 0f);
+
+        assertThat(isValid(point1)).isTrue();
+        Assert.assertEquals(point1.getNormalizedCropRegionX(), point2.getNormalizedCropRegionX(),
+                TOLERANCE);
+        Assert.assertEquals(point1.getNormalizedCropRegionY(), point2.getNormalizedCropRegionY(),
+                TOLERANCE);
+
+        // right-bottom corner
+        point1 = factory1.createPoint(mWidth, mHeight);
+        point2 = factory2.createPoint(mWidth, mHeight);
+
+        assertThat(isValid(point1)).isTrue();
+        Assert.assertEquals(point1.getNormalizedCropRegionX(), point2.getNormalizedCropRegionX(),
+                TOLERANCE);
+        Assert.assertEquals(point1.getNormalizedCropRegionY(), point2.getNormalizedCropRegionY(),
+                TOLERANCE);
+
+        // some random point
+        point1 = factory1.createPoint(100, 120);
+        point2 = factory2.createPoint(100, 120);
+
+        assertThat(isValid(point1)).isTrue();
+        Assert.assertEquals(point1.getNormalizedCropRegionX(), point2.getNormalizedCropRegionX(),
+                TOLERANCE);
+        Assert.assertEquals(point1.getNormalizedCropRegionY(), point2.getNormalizedCropRegionY(),
+                TOLERANCE);
+    }
+}
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/CameraView.java b/camera/camera-view/src/main/java/androidx/camera/view/CameraView.java
index cf72ffb..3a0ade2 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/CameraView.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/CameraView.java
@@ -51,11 +51,16 @@
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
 import androidx.annotation.UiThread;
+import androidx.camera.core.CameraInfoUnavailableException;
+import androidx.camera.core.CameraX;
 import androidx.camera.core.CameraX.LensFacing;
 import androidx.camera.core.FlashMode;
+import androidx.camera.core.FocusMeteringAction;
+import androidx.camera.core.FocusMeteringAction.MeteringMode;
 import androidx.camera.core.ImageCapture.OnImageCapturedListener;
 import androidx.camera.core.ImageCapture.OnImageSavedListener;
 import androidx.camera.core.ImageProxy;
+import androidx.camera.core.MeteringPoint;
 import androidx.camera.core.VideoCapture.OnVideoSavedListener;
 import androidx.lifecycle.LifecycleOwner;
 
@@ -93,8 +98,6 @@
     private static final int FLASH_MODE_AUTO = 1;
     private static final int FLASH_MODE_ON = 2;
     private static final int FLASH_MODE_OFF = 4;
-    private final Rect mFocusingRect = new Rect();
-    private final Rect mMeteringRect = new Rect();
     // For tap-to-focus
     private long mDownEventTimestamp;
     // For pinch-to-zoom
@@ -121,8 +124,7 @@
     private ScaleType mScaleType = ScaleType.CENTER_CROP;
     // For accessibility event
     private MotionEvent mUpEvent;
-    private @Nullable
-            Paint mLayerPaint;
+    private @Nullable Paint mLayerPaint;
 
     public CameraView(Context context) {
         this(context, null);
@@ -705,20 +707,6 @@
         return mCameraModule.getLensFacing();
     }
 
-    /**
-     * Focuses the camera on the given area.
-     *
-     * <p>Sets the focus and exposure metering rectangles. Coordinates for both X and Y dimensions
-     * are Limited from -1000 to 1000, where (0, 0) is the center of the image and the width/height
-     * represent the values from -1000 to 1000.
-     *
-     * @param focus    Area used to focus the camera.
-     * @param metering Area used for exposure metering.
-     */
-    public void focus(Rect focus, Rect metering) {
-        mCameraModule.focus(focus, metering);
-    }
-
     /** Gets the active flash strategy. */
     public FlashMode getFlash() {
         return mCameraModule.getFlash();
@@ -781,10 +769,21 @@
         final float x = (mUpEvent != null) ? mUpEvent.getX() : getX() + getWidth() / 2f;
         final float y = (mUpEvent != null) ? mUpEvent.getY() : getY() + getHeight() / 2f;
         mUpEvent = null;
-        calculateTapArea(mFocusingRect, x, y, 1f);
-        calculateTapArea(mMeteringRect, x, y, 1.5f);
-        if (area(mFocusingRect) > 0 && area(mMeteringRect) > 0) {
-            focus(mFocusingRect, mMeteringRect);
+
+        TextureViewMeteringPointFactory pointFactory = new TextureViewMeteringPointFactory(
+                mCameraTextureView);
+        float afPointWidth = 1.0f / 6.0f;  // 1/6 total area
+        float aePointWidth = afPointWidth * 1.5f;
+        MeteringPoint afPoint = pointFactory.createPoint(x, y, afPointWidth, 1.0f);
+        MeteringPoint aePoint = pointFactory.createPoint(x, y, aePointWidth, 1.0f);
+
+        try {
+            CameraX.getCameraControl(getCameraLensFacing()).startFocusAndMetering(
+                    FocusMeteringAction.Builder.from(afPoint, MeteringMode.AF_ONLY)
+                            .addPoint(aePoint, MeteringMode.AE_ONLY)
+                            .build());
+        } catch (CameraInfoUnavailableException e) {
+            Log.d(TAG, "cannot access camera", e);
         }
 
         return true;
@@ -795,80 +794,6 @@
         return rect.width() * rect.height();
     }
 
-    /** The area must be between -1000,-1000 and 1000,1000 */
-    private void calculateTapArea(Rect rect, float x, float y, float coefficient) {
-        int max = 1000;
-        int min = -1000;
-
-        // Default to 300 (1/6th the total area) and scale by the coefficient
-        int areaSize = (int) (300 * coefficient);
-
-        // Rotate the coordinates if the camera orientation is different
-        int width = getWidth();
-        int height = getHeight();
-
-        // Compensate orientation as it's mirrored on preview for forward facing cameras
-        boolean compensateForMirroring = (getCameraLensFacing() == LensFacing.FRONT);
-        int relativeCameraOrientation = getRelativeCameraOrientation(compensateForMirroring);
-        int temp;
-        float tempf;
-        switch (relativeCameraOrientation) {
-            case 90:
-                // Fall-through
-            case 270:
-                // We're horizontal. Swap width/height. Swap x/y.
-                temp = width;
-                //noinspection SuspiciousNameCombination
-                width = height;
-                height = temp;
-
-                tempf = x;
-                //noinspection SuspiciousNameCombination
-                x = y;
-                y = tempf;
-                break;
-            default:
-                break;
-        }
-
-        switch (relativeCameraOrientation) {
-            // Map to correct coordinates according to relativeCameraOrientation
-            case 90:
-                y = height - y;
-                break;
-            case 180:
-                x = width - x;
-                y = height - y;
-                break;
-            case 270:
-                x = width - x;
-                break;
-            default:
-                break;
-        }
-
-        // Swap x if it's a mirrored preview
-        if (compensateForMirroring) {
-            x = width - x;
-        }
-
-        // Grab the x, y position from within the View and normalize it to -1000 to 1000
-        x = min + distance(max, min) * (x / width);
-        y = min + distance(max, min) * (y / height);
-
-        // Modify the rect to the bounding area
-        rect.top = (int) y - areaSize / 2;
-        rect.left = (int) x - areaSize / 2;
-        rect.bottom = rect.top + areaSize;
-        rect.right = rect.left + areaSize;
-
-        // Cap at -1000 to 1000
-        rect.top = rangeLimit(rect.top, max, min);
-        rect.left = rangeLimit(rect.left, max, min);
-        rect.bottom = rangeLimit(rect.bottom, max, min);
-        rect.right = rangeLimit(rect.right, max, min);
-    }
-
     private int rangeLimit(int val, int max, int min) {
         return Math.min(Math.max(val, min), max);
     }
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/CameraXModule.java b/camera/camera-view/src/main/java/androidx/camera/view/CameraXModule.java
index cab946e..3fc3a44 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/CameraXModule.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/CameraXModule.java
@@ -30,6 +30,7 @@
 import android.util.Rational;
 import android.util.Size;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresPermission;
 import androidx.annotation.UiThread;
@@ -350,19 +351,19 @@
                 file,
                 new VideoCapture.OnVideoSavedListener() {
                     @Override
-                    public void onVideoSaved(File savedFile) {
+                    public void onVideoSaved(@NonNull File savedFile) {
                         mVideoIsRecording.set(false);
                         listener.onVideoSaved(savedFile);
                     }
 
                     @Override
                     public void onError(
-                            VideoCapture.UseCaseError useCaseError,
-                            String message,
+                            @NonNull VideoCapture.VideoCaptureError videoCaptureError,
+                            @NonNull String message,
                             @Nullable Throwable cause) {
                         mVideoIsRecording.set(false);
                         Log.e(TAG, message, cause);
-                        listener.onError(useCaseError, message, cause);
+                        listener.onError(videoCaptureError, message, cause);
                     }
                 });
     }
@@ -439,31 +440,6 @@
         }
     }
 
-    public void focus(Rect focus, Rect metering) {
-        if (mPreview == null) {
-            // Nothing to focus on since we don't yet have a preview
-            return;
-        }
-
-        Rect rescaledFocus;
-        Rect rescaledMetering;
-        try {
-            Rect sensorRegion;
-            if (mCropRegion != null) {
-                sensorRegion = mCropRegion;
-            } else {
-                sensorRegion = getSensorSize(getActiveCamera());
-            }
-            rescaledFocus = rescaleViewRectToSensorRect(focus, sensorRegion);
-            rescaledMetering = rescaleViewRectToSensorRect(metering, sensorRegion);
-        } catch (Exception e) {
-            Log.e(TAG, "Failed to rescale the focus and metering rectangles.", e);
-            return;
-        }
-
-        mPreview.focus(rescaledFocus, rescaledMetering);
-    }
-
     public float getZoomLevel() {
         return mZoomLevel;
     }
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/TextureViewMeteringPointFactory.java b/camera/camera-view/src/main/java/androidx/camera/view/TextureViewMeteringPointFactory.java
new file mode 100644
index 0000000..dab8a31
--- /dev/null
+++ b/camera/camera-view/src/main/java/androidx/camera/view/TextureViewMeteringPointFactory.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2019 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.camera.view;
+
+import android.graphics.Matrix;
+import android.graphics.PointF;
+import android.graphics.SurfaceTexture;
+import android.view.TextureView;
+
+import androidx.annotation.NonNull;
+import androidx.camera.core.MeteringPoint;
+import androidx.camera.core.MeteringPointFactory;
+
+/**
+ * A {@link MeteringPointFactory} for creating a {@link MeteringPoint} by {@link TextureView} and
+ * (x,y).
+ *
+ * <p>SurfaceTexture in TextureView could be cropped, scaled or rotated by
+ * {@link TextureView#getTransform(Matrix)}. This factory translates the (x, y) into the sensor
+ * crop region normalized (x,y) by this transform. {@link SurfaceTexture#getTransformMatrix} is
+ * also used during the translation. No lens facing information is required because
+ * {@link SurfaceTexture#getTransformMatrix} contains the necessary transformation corresponding
+ * to the lens face of current camera ouput.
+ */
+public class TextureViewMeteringPointFactory extends MeteringPointFactory {
+    private final TextureView mTextureView;
+
+    public TextureViewMeteringPointFactory(@NonNull TextureView textureView) {
+        mTextureView = textureView;
+    }
+
+    /**
+     * Translates a (x,y) from TextureView.
+     */
+    @NonNull
+    @Override
+    protected PointF translatePoint(float x, float y) {
+        Matrix transform = new Matrix();
+        mTextureView.getTransform(transform);
+
+        // applying reverse of TextureView#getTransform
+        Matrix inverse = new Matrix();
+        transform.invert(inverse);
+        float[] pt = new float[]{x, y};
+        inverse.mapPoints(pt);
+
+        // get SurfaceTexture#getTransformMatrix
+        float[] surfaceTextureMat = new float[16];
+        mTextureView.getSurfaceTexture().getTransformMatrix(surfaceTextureMat);
+
+        // convert SurfaceTexture#getTransformMatrix(4x4 column major 3D matrix) to
+        // android.graphics.Matrix(3x3 row major 2D matrix)
+        Matrix surfaceTextureTransform = glMatrixToGraphicsMatrix(surfaceTextureMat);
+
+        float[] pt2 = new float[2];
+        // convert to texture coordinates first.
+        pt2[0] = pt[0] / mTextureView.getWidth();
+        pt2[1] = (mTextureView.getHeight() - pt[1]) / mTextureView.getHeight();
+        surfaceTextureTransform.mapPoints(pt2);
+
+        return new PointF(pt2[0], pt2[1]);
+    }
+
+    private Matrix glMatrixToGraphicsMatrix(float[] glMatrix) {
+        float[] convert = new float[9];
+        convert[0] = glMatrix[0];
+        convert[1] = glMatrix[4];
+        convert[2] = glMatrix[12];
+        convert[3] = glMatrix[1];
+        convert[4] = glMatrix[5];
+        convert[5] = glMatrix[13];
+        convert[6] = glMatrix[3];
+        convert[7] = glMatrix[7];
+        convert[8] = glMatrix[15];
+        Matrix graphicsMatrix = new Matrix();
+        graphicsMatrix.setValues(convert);
+        return graphicsMatrix;
+    }
+}
diff --git a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
index ef7c6fc..553a0d8 100644
--- a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
+++ b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
@@ -40,6 +40,7 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 import androidx.appcompat.app.AppCompatActivity;
 import androidx.camera.core.CameraInfoUnavailableException;
@@ -491,7 +492,7 @@
                                                 + ".jpg"),
                                 new ImageCapture.OnImageSavedListener() {
                                     @Override
-                                    public void onImageSaved(File file) {
+                                    public void onImageSaved(@NonNull File file) {
                                         Log.d(TAG, "Saved image to " + file);
                                         if (!mImageSavedIdlingResource.isIdleNow()) {
                                             mImageSavedIdlingResource.decrement();
@@ -511,8 +512,8 @@
 
                                     @Override
                                     public void onError(
-                                            ImageCapture.UseCaseError useCaseError,
-                                            String message,
+                                            @NonNull ImageCapture.ImageCaptureError error,
+                                            @NonNull String message,
                                             Throwable cause) {
                                         Log.e(TAG, "Failed to save image.", cause);
                                         if (!mImageSavedIdlingResource.isIdleNow()) {
diff --git a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/VideoFileSaver.java b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/VideoFileSaver.java
index 0e2a819..84c541d 100644
--- a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/VideoFileSaver.java
+++ b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/VideoFileSaver.java
@@ -19,10 +19,11 @@
 import android.util.Log;
 
 import androidx.annotation.GuardedBy;
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.camera.core.VideoCapture;
 import androidx.camera.core.VideoCapture.OnVideoSavedListener;
-import androidx.camera.core.VideoCapture.UseCaseError;
+import androidx.camera.core.VideoCapture.VideoCaptureError;
 
 import java.io.File;
 import java.text.Format;
@@ -43,7 +44,7 @@
     private boolean mIsSaving = false;
 
     @Override
-    public void onVideoSaved(File file) {
+    public void onVideoSaved(@NonNull File file) {
 
         Log.d(TAG, "Saved file: " + file.getPath());
         synchronized (mLock) {
@@ -52,9 +53,10 @@
     }
 
     @Override
-    public void onError(UseCaseError useCaseError, String message, @Nullable Throwable cause) {
+    public void onError(@NonNull VideoCaptureError videoCaptureError, @NonNull String message,
+            @Nullable Throwable cause) {
 
-        Log.e(TAG, "Error: " + useCaseError + ", " + message);
+        Log.e(TAG, "Error: " + videoCaptureError + ", " + message);
         if (cause != null) {
             Log.e(TAG, "Error cause: " + cause.getCause());
         }
diff --git a/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/CameraExtensionsActivity.java b/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/CameraExtensionsActivity.java
index 31106c0..e767b76 100644
--- a/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/CameraExtensionsActivity.java
+++ b/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/CameraExtensionsActivity.java
@@ -310,7 +310,7 @@
                                                 + ".jpg"),
                                 new ImageCapture.OnImageSavedListener() {
                                     @Override
-                                    public void onImageSaved(File file) {
+                                    public void onImageSaved(@NonNull File file) {
                                         Log.d(TAG, "Saved image to " + file);
 
                                         if (!mTakePictureIdlingResource.isIdleNow()) {
@@ -330,8 +330,8 @@
 
                                     @Override
                                     public void onError(
-                                            ImageCapture.UseCaseError useCaseError,
-                                            String message,
+                                            @NonNull ImageCapture.ImageCaptureError error,
+                                            @NonNull String message,
                                             Throwable cause) {
                                         Log.e(TAG, "Failed to save image - " + message, cause);
                                     }
diff --git a/camera/integration-tests/timingtestapp/build.gradle b/camera/integration-tests/timingtestapp/build.gradle
index d88e11f..86a50ac 100644
--- a/camera/integration-tests/timingtestapp/build.gradle
+++ b/camera/integration-tests/timingtestapp/build.gradle
@@ -59,7 +59,7 @@
     implementation(project(":fragment:fragment"))
     implementation(project(":appcompat"))
     implementation(ANDROIDX_COLLECTION)
-    implementation(project(":preference")) // Still in alpha
+    implementation(project(":preference:preference")) // Still in alpha
     implementation("androidx.exifinterface:exifinterface:1.0.0")
     implementation(CONSTRAINT_LAYOUT, { transitive = true })
     implementation(KOTLIN_STDLIB)
diff --git a/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/ImageUtils.kt b/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/ImageUtils.kt
index 0f8d309..903dd99 100644
--- a/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/ImageUtils.kt
+++ b/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/ImageUtils.kt
@@ -325,8 +325,8 @@
 
     /** Camera X was unable to capture a still image and threw an error */
     override fun onError(
-        useCaseError: ImageCapture.UseCaseError?,
-        message: String?,
+        imageCaptureError: ImageCapture.ImageCaptureError,
+        message: String,
         cause: Throwable?
     ) {
         logd("CameraX ImageCallback onError. Error: " + message)
diff --git a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CaptureViewOnTouchListener.java b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CaptureViewOnTouchListener.java
index e28e8e6..043604b 100644
--- a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CaptureViewOnTouchListener.java
+++ b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CaptureViewOnTouchListener.java
@@ -30,9 +30,10 @@
 import android.view.ViewConfiguration;
 import android.widget.Toast;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.camera.core.ImageCapture.ImageCaptureError;
 import androidx.camera.core.ImageCapture.OnImageSavedListener;
-import androidx.camera.core.ImageCapture.UseCaseError;
 import androidx.camera.core.VideoCapture;
 import androidx.camera.core.VideoCapture.OnVideoSavedListener;
 import androidx.camera.view.CameraView;
@@ -182,7 +183,7 @@
     }
 
     @Override
-    public void onImageSaved(File file) {
+    public void onImageSaved(@NonNull File file) {
         report("Picture saved to " + file.getAbsolutePath());
 
         // Print out metadata about the picture
@@ -192,20 +193,21 @@
     }
 
     @Override
-    public void onVideoSaved(File file) {
+    public void onVideoSaved(@NonNull File file) {
         report("Video saved to " + file.getAbsolutePath());
         broadcastVideo(file);
     }
 
     @Override
-    public void onError(UseCaseError useCaseError, String message, @Nullable Throwable cause) {
+    public void onError(@NonNull ImageCaptureError imageCaptureError, @NonNull String message,
+            @Nullable Throwable cause) {
         report("Failure");
     }
 
     @Override
     public void onError(
-            VideoCapture.UseCaseError useCaseError,
-            String message,
+            @NonNull VideoCapture.VideoCaptureError videoCaptureError,
+            @NonNull String message,
             @Nullable Throwable cause) {
         report("Failure");
     }
diff --git a/car/cluster/api/api_lint.ignore b/car/cluster/api/api_lint.ignore
new file mode 100644
index 0000000..de62e79
--- /dev/null
+++ b/car/cluster/api/api_lint.ignore
@@ -0,0 +1,51 @@
+// Baseline format: 1.0
+MissingNullability: androidx.car.cluster.navigation.Destination#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.car.cluster.navigation.Destination#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.car.cluster.navigation.Distance#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.car.cluster.navigation.Distance#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.car.cluster.navigation.ImageReference#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.car.cluster.navigation.ImageReference#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.car.cluster.navigation.Lane#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.car.cluster.navigation.Lane#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.car.cluster.navigation.LaneDirection#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.car.cluster.navigation.LaneDirection#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.car.cluster.navigation.LatLng#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.car.cluster.navigation.LatLng#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.car.cluster.navigation.Maneuver#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.car.cluster.navigation.Maneuver#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.car.cluster.navigation.NavigationState#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.car.cluster.navigation.NavigationState#fromParcelable(android.os.Parcelable):
+    Missing nullability on method `fromParcelable` return
+MissingNullability: androidx.car.cluster.navigation.NavigationState#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.car.cluster.navigation.RichText#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.car.cluster.navigation.RichText#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.car.cluster.navigation.RichTextElement#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.car.cluster.navigation.RichTextElement#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.car.cluster.navigation.Segment#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.car.cluster.navigation.Segment#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.car.cluster.navigation.Step#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.car.cluster.navigation.Step#toString():
+    Missing nullability on method `toString` return
diff --git a/car/core/api/api_lint.ignore b/car/core/api/api_lint.ignore
index 5a9daf1..aea3d8a 100644
--- a/car/core/api/api_lint.ignore
+++ b/car/core/api/api_lint.ignore
@@ -1,3 +1,241 @@
 // Baseline format: 1.0
 KotlinOperator: androidx.car.widget.ListItemProvider#get(int):
     Method can be invoked with an indexing operator from Kotlin: `get` (this is usually desirable; just make sure it makes sense for this type of object)
+
+
+MissingNullability: androidx.car.app.CarAlertDialog#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.car.app.CarAlertDialog#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.car.app.CarListDialog#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.car.app.CarListDialog#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.car.app.CarListDialog.Builder#Builder(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `Builder`
+MissingNullability: androidx.car.app.CarListDialog.Builder#create():
+    Missing nullability on method `create` return
+MissingNullability: androidx.car.app.CarMultipleChoiceDialog#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.car.app.CarMultipleChoiceDialog#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.car.app.CarSingleChoiceDialog#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.car.app.CarSingleChoiceDialog#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.car.drawer.CarDrawerAdapter#CarDrawerAdapter(android.content.Context, boolean) parameter #0:
+    Missing nullability on parameter `context` in method `CarDrawerAdapter`
+MissingNullability: androidx.car.drawer.CarDrawerAdapter#onBindViewHolder(androidx.car.drawer.DrawerItemViewHolder, int) parameter #0:
+    Missing nullability on parameter `holder` in method `onBindViewHolder`
+MissingNullability: androidx.car.drawer.CarDrawerAdapter#onCreateViewHolder(android.view.ViewGroup, int):
+    Missing nullability on method `onCreateViewHolder` return
+MissingNullability: androidx.car.drawer.CarDrawerAdapter#onCreateViewHolder(android.view.ViewGroup, int) parameter #0:
+    Missing nullability on parameter `parent` in method `onCreateViewHolder`
+MissingNullability: androidx.car.drawer.CarDrawerAdapter#populateViewHolder(androidx.car.drawer.DrawerItemViewHolder, int) parameter #0:
+    Missing nullability on parameter `holder` in method `populateViewHolder`
+MissingNullability: androidx.car.drawer.CarDrawerController#onConfigurationChanged(android.content.res.Configuration) parameter #0:
+    Missing nullability on parameter `newConfig` in method `onConfigurationChanged`
+MissingNullability: androidx.car.drawer.CarDrawerController#onOptionsItemSelected(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `onOptionsItemSelected`
+MissingNullability: androidx.car.drawer.CarDrawerController#pushAdapter(androidx.car.drawer.CarDrawerAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `pushAdapter`
+MissingNullability: androidx.car.drawer.DrawerItemViewHolder#onUxRestrictionsChanged(androidx.car.uxrestrictions.CarUxRestrictions) parameter #0:
+    Missing nullability on parameter `restrictionsInfo` in method `onUxRestrictionsChanged`
+MissingNullability: androidx.car.util.ColumnCalculator#getInstance(android.content.Context):
+    Missing nullability on method `getInstance` return
+MissingNullability: androidx.car.util.ColumnCalculator#getInstance(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `getInstance`
+MissingNullability: androidx.car.uxrestrictions.CarUxRestrictions#CarUxRestrictions(androidx.car.uxrestrictions.CarUxRestrictions) parameter #0:
+    Missing nullability on parameter `uxRestrictions` in method `CarUxRestrictions`
+MissingNullability: androidx.car.uxrestrictions.CarUxRestrictions#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.car.uxrestrictions.CarUxRestrictions#hasSameRestrictionsAs(androidx.car.uxrestrictions.CarUxRestrictions) parameter #0:
+    Missing nullability on parameter `other` in method `hasSameRestrictionsAs`
+MissingNullability: androidx.car.uxrestrictions.CarUxRestrictions#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.car.uxrestrictions.OnUxRestrictionsChangedListener#onUxRestrictionsChanged(androidx.car.uxrestrictions.CarUxRestrictions) parameter #0:
+    Missing nullability on parameter `restrictionInfo` in method `onUxRestrictionsChanged`
+MissingNullability: androidx.car.widget.ActionListItem#createViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `itemView` in method `createViewHolder`
+MissingNullability: androidx.car.widget.ActionListItem#onBind(androidx.car.widget.ActionListItem.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onBind`
+MissingNullability: androidx.car.widget.ActionListItem#setOnClickListener(android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnClickListener`
+MissingNullability: androidx.car.widget.AlphaJumpAdapter#getAlphaJumpBuckets():
+    Missing nullability on method `getAlphaJumpBuckets` return
+MissingNullability: androidx.car.widget.AlphaJumpAdapter#onAlphaJumpLeave(androidx.car.widget.AlphaJumpBucket) parameter #0:
+    Missing nullability on parameter `bucket` in method `onAlphaJumpLeave`
+MissingNullability: androidx.car.widget.AlphaJumpBucket#getLabel():
+    Missing nullability on method `getLabel` return
+MissingNullability: androidx.car.widget.AlphaJumpBucketer#AlphaJumpBucketer(androidx.car.widget.AlphaJumpBucketer.Bucket[]) parameter #0:
+    Missing nullability on parameter `buckets` in method `AlphaJumpBucketer`
+MissingNullability: androidx.car.widget.AlphaJumpBucketer#createBuckets(Iterable<java.lang.String>):
+    Missing nullability on method `createBuckets` return
+MissingNullability: androidx.car.widget.AlphaJumpBucketer#createBuckets(Iterable<java.lang.String>) parameter #0:
+    Missing nullability on parameter `values` in method `createBuckets`
+MissingNullability: androidx.car.widget.AlphaJumpBucketer#createBuckets(String[]):
+    Missing nullability on method `createBuckets` return
+MissingNullability: androidx.car.widget.AlphaJumpBucketer#createBuckets(String[]) parameter #0:
+    Missing nullability on parameter `values` in method `createBuckets`
+MissingNullability: androidx.car.widget.AlphaJumpBucketer#createBuckets(java.util.Iterator<java.lang.String>):
+    Missing nullability on method `createBuckets` return
+MissingNullability: androidx.car.widget.AlphaJumpBucketer#createBuckets(java.util.Iterator<java.lang.String>) parameter #0:
+    Missing nullability on parameter `values` in method `createBuckets`
+MissingNullability: androidx.car.widget.AlphaJumpBucketer.Bucket#getLabel():
+    Missing nullability on method `getLabel` return
+MissingNullability: androidx.car.widget.CarMenuItem.OnClickListener#onClick(androidx.car.widget.CarMenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `onClick`
+MissingNullability: androidx.car.widget.CarToolbar#CarToolbar(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `CarToolbar`
+MissingNullability: androidx.car.widget.CarToolbar#CarToolbar(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `CarToolbar`
+MissingNullability: androidx.car.widget.CarToolbar#CarToolbar(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `CarToolbar`
+MissingNullability: androidx.car.widget.CarToolbar#CarToolbar(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `CarToolbar`
+MissingNullability: androidx.car.widget.CarToolbar#CarToolbar(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `CarToolbar`
+MissingNullability: androidx.car.widget.CarToolbar#CarToolbar(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `CarToolbar`
+MissingNullability: androidx.car.widget.CarToolbar#CarToolbar(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `CarToolbar`
+MissingNullability: androidx.car.widget.CarToolbar#checkLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `checkLayoutParams`
+MissingNullability: androidx.car.widget.CarToolbar#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.car.widget.CarToolbar#generateLayoutParams(android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.car.widget.CarToolbar#generateLayoutParams(android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.car.widget.CarToolbar#generateLayoutParams(android.view.ViewGroup.LayoutParams):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.car.widget.CarToolbar#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `generateLayoutParams`
+MissingNullability: androidx.car.widget.CarToolbar#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.car.widget.ColumnCardView#ColumnCardView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `ColumnCardView`
+MissingNullability: androidx.car.widget.ColumnCardView#ColumnCardView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `ColumnCardView`
+MissingNullability: androidx.car.widget.ColumnCardView#ColumnCardView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `ColumnCardView`
+MissingNullability: androidx.car.widget.ColumnCardView#ColumnCardView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `ColumnCardView`
+MissingNullability: androidx.car.widget.ColumnCardView#ColumnCardView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `ColumnCardView`
+MissingNullability: androidx.car.widget.ListItem#addViewBinder(androidx.car.widget.ListItem.ViewBinder<VH>) parameter #0:
+    Missing nullability on parameter `binder` in method `addViewBinder`
+MissingNullability: androidx.car.widget.ListItem#addViewBinder(androidx.car.widget.ListItem.ViewBinder<VH>, androidx.car.widget.ListItem.ViewBinder<VH>) parameter #0:
+    Missing nullability on parameter `binder` in method `addViewBinder`
+MissingNullability: androidx.car.widget.ListItem#removeViewBinder(androidx.car.widget.ListItem.ViewBinder<VH>) parameter #0:
+    Missing nullability on parameter `binder` in method `removeViewBinder`
+MissingNullability: androidx.car.widget.ListItem.ViewHolder#ViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `itemView` in method `ViewHolder`
+MissingNullability: androidx.car.widget.ListItemAdapter#onAttachedToRecyclerView(androidx.recyclerview.widget.RecyclerView) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `onAttachedToRecyclerView`
+MissingNullability: androidx.car.widget.ListItemAdapter#onBindViewHolder(androidx.car.widget.ListItem.ViewHolder, int) parameter #0:
+    Missing nullability on parameter `holder` in method `onBindViewHolder`
+MissingNullability: androidx.car.widget.ListItemAdapter#onCreateViewHolder(android.view.ViewGroup, int):
+    Missing nullability on method `onCreateViewHolder` return
+MissingNullability: androidx.car.widget.ListItemAdapter#onCreateViewHolder(android.view.ViewGroup, int) parameter #0:
+    Missing nullability on parameter `parent` in method `onCreateViewHolder`
+MissingNullability: androidx.car.widget.ListItemAdapter#registerListItemViewType(int, int, androidx.arch.core.util.Function<android.view.View,androidx.car.widget.ListItem.ViewHolder>) parameter #2:
+    Missing nullability on parameter `function` in method `registerListItemViewType`
+MissingNullability: androidx.car.widget.PagedListView#PagedListView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `PagedListView`
+MissingNullability: androidx.car.widget.PagedListView#PagedListView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `PagedListView`
+MissingNullability: androidx.car.widget.PagedListView#PagedListView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `PagedListView`
+MissingNullability: androidx.car.widget.PagedListView#PagedListView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `PagedListView`
+MissingNullability: androidx.car.widget.PagedListView#PagedListView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `PagedListView`
+MissingNullability: androidx.car.widget.PagedListView#PagedListView(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `PagedListView`
+MissingNullability: androidx.car.widget.PagedListView#PagedListView(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `PagedListView`
+MissingNullability: androidx.car.widget.PagedListView#dispatchRestoreInstanceState(android.util.SparseArray<android.os.Parcelable>) parameter #0:
+    Missing nullability on parameter `container` in method `dispatchRestoreInstanceState`
+MissingNullability: androidx.car.widget.PagedListView#dispatchSaveInstanceState(android.util.SparseArray<android.os.Parcelable>) parameter #0:
+    Missing nullability on parameter `container` in method `dispatchSaveInstanceState`
+MissingNullability: androidx.car.widget.PagedListView#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.car.widget.PagedListView#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.car.widget.PagedListView#setDividerVisibilityManager(androidx.car.widget.PagedListView.DividerVisibilityManager) parameter #0:
+    Missing nullability on parameter `dvm` in method `setDividerVisibilityManager`
+MissingNullability: androidx.car.widget.PagedListView#setDownButtonIcon(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `icon` in method `setDownButtonIcon`
+MissingNullability: androidx.car.widget.PagedListView#setOnScrollListener(androidx.car.widget.PagedListView.OnScrollListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnScrollListener`
+MissingNullability: androidx.car.widget.PagedListView#setUpButtonIcon(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `icon` in method `setUpButtonIcon`
+MissingNullability: androidx.car.widget.PagedListView.OnScrollListener#onScrollStateChanged(androidx.recyclerview.widget.RecyclerView, int) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `onScrollStateChanged`
+MissingNullability: androidx.car.widget.PagedListView.OnScrollListener#onScrolled(androidx.recyclerview.widget.RecyclerView, int, int) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `onScrolled`
+MissingNullability: androidx.car.widget.PagedScrollBarView#PagedScrollBarView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `PagedScrollBarView`
+MissingNullability: androidx.car.widget.PagedScrollBarView#PagedScrollBarView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `PagedScrollBarView`
+MissingNullability: androidx.car.widget.PagedScrollBarView#PagedScrollBarView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `PagedScrollBarView`
+MissingNullability: androidx.car.widget.PagedScrollBarView#PagedScrollBarView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `PagedScrollBarView`
+MissingNullability: androidx.car.widget.PagedScrollBarView#PagedScrollBarView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `PagedScrollBarView`
+MissingNullability: androidx.car.widget.PagedScrollBarView#PagedScrollBarView(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `PagedScrollBarView`
+MissingNullability: androidx.car.widget.PagedScrollBarView#PagedScrollBarView(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `PagedScrollBarView`
+MissingNullability: androidx.car.widget.PagedScrollBarView#setDownButtonIcon(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `icon` in method `setDownButtonIcon`
+MissingNullability: androidx.car.widget.PagedScrollBarView#setPaginationListener(androidx.car.widget.PagedScrollBarView.PaginationListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setPaginationListener`
+MissingNullability: androidx.car.widget.PagedScrollBarView#setUpButtonIcon(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `icon` in method `setUpButtonIcon`
+MissingNullability: androidx.car.widget.SeekbarListItem#createViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `itemView` in method `createViewHolder`
+MissingNullability: androidx.car.widget.SeekbarListItem#onBind(androidx.car.widget.SeekbarListItem.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onBind`
+MissingNullability: androidx.car.widget.SeekbarListItem#setOnSeekBarChangeListener(android.widget.SeekBar.OnSeekBarChangeListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnSeekBarChangeListener`
+MissingNullability: androidx.car.widget.SeekbarListItem#setPrimaryActionIconListener(android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `onClickListener` in method `setPrimaryActionIconListener`
+MissingNullability: androidx.car.widget.SeekbarListItem#setSupplementalIconListener(android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setSupplementalIconListener`
+MissingNullability: androidx.car.widget.SeekbarListItem.ViewHolder#ViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `itemView` in method `ViewHolder`
+MissingNullability: androidx.car.widget.SeekbarListItem.ViewHolder#onUxRestrictionsChanged(androidx.car.uxrestrictions.CarUxRestrictions) parameter #0:
+    Missing nullability on parameter `restrictionsInfo` in method `onUxRestrictionsChanged`
+MissingNullability: androidx.car.widget.SubheaderListItem#createViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `itemView` in method `createViewHolder`
+MissingNullability: androidx.car.widget.SubheaderListItem#onBind(androidx.car.widget.SubheaderListItem.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onBind`
+MissingNullability: androidx.car.widget.SubheaderListItem.ViewHolder#ViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `itemView` in method `ViewHolder`
+MissingNullability: androidx.car.widget.SubheaderListItem.ViewHolder#onUxRestrictionsChanged(androidx.car.uxrestrictions.CarUxRestrictions) parameter #0:
+    Missing nullability on parameter `restrictionsInfo` in method `onUxRestrictionsChanged`
+MissingNullability: androidx.car.widget.TextListItem#createViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `itemView` in method `createViewHolder`
+MissingNullability: androidx.car.widget.TextListItem#onBind(androidx.car.widget.TextListItem.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onBind`
+MissingNullability: androidx.car.widget.TextListItem#setBody(CharSequence) parameter #0:
+    Missing nullability on parameter `body` in method `setBody`
+MissingNullability: androidx.car.widget.TextListItem#setOnClickListener(android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnClickListener`
+MissingNullability: androidx.car.widget.TextListItem#setSupplementalIcon(android.graphics.drawable.Drawable, boolean, android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `drawable` in method `setSupplementalIcon`
+MissingNullability: androidx.car.widget.TextListItem#setSupplementalIcon(android.graphics.drawable.Drawable, boolean, android.view.View.OnClickListener) parameter #2:
+    Missing nullability on parameter `listener` in method `setSupplementalIcon`
+MissingNullability: androidx.car.widget.TextListItem#setSupplementalIcon(int, boolean, android.view.View.OnClickListener) parameter #2:
+    Missing nullability on parameter `listener` in method `setSupplementalIcon`
+MissingNullability: androidx.car.widget.TextListItem#setSwitch(boolean, boolean, android.widget.CompoundButton.OnCheckedChangeListener) parameter #2:
+    Missing nullability on parameter `listener` in method `setSwitch`
+MissingNullability: androidx.car.widget.TextListItem#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.car.widget.TextListItem.ViewHolder#ViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `itemView` in method `ViewHolder`
+MissingNullability: androidx.car.widget.TextListItem.ViewHolder#onUxRestrictionsChanged(androidx.car.uxrestrictions.CarUxRestrictions) parameter #0:
+    Missing nullability on parameter `restrictionsInfo` in method `onUxRestrictionsChanged`
diff --git a/car/core/src/main/java/androidx/car/app/CarSingleChoiceDialog.java b/car/core/src/main/java/androidx/car/app/CarSingleChoiceDialog.java
index d3f6066..570e1cc 100644
--- a/car/core/src/main/java/androidx/car/app/CarSingleChoiceDialog.java
+++ b/car/core/src/main/java/androidx/car/app/CarSingleChoiceDialog.java
@@ -166,7 +166,7 @@
             positiveButtonView.requestLayout();
 
             int buttonExtraSpace = CarDialogUtil.calculateExtraButtonSpace(negativeButtonView);
-            negativeButtonLayoutParams.setMarginStart(buttonOffset - buttonExtraSpace);
+            negativeButtonLayoutParams.setMarginStart(buttonOffset - buttonExtraSpace / 2);
             negativeButtonLayoutParams.setMarginEnd(buttonSpacing);
             negativeButtonView.requestLayout();
         } else {
diff --git a/car/moderator/api/api_lint.ignore b/car/moderator/api/api_lint.ignore
new file mode 100644
index 0000000..fb898ce
--- /dev/null
+++ b/car/moderator/api/api_lint.ignore
@@ -0,0 +1,21 @@
+// Baseline format: 1.0
+MissingNullability: androidx.car.moderator.SpeedBumpView#SpeedBumpView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `SpeedBumpView`
+MissingNullability: androidx.car.moderator.SpeedBumpView#SpeedBumpView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `SpeedBumpView`
+MissingNullability: androidx.car.moderator.SpeedBumpView#SpeedBumpView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `SpeedBumpView`
+MissingNullability: androidx.car.moderator.SpeedBumpView#SpeedBumpView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `SpeedBumpView`
+MissingNullability: androidx.car.moderator.SpeedBumpView#SpeedBumpView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `SpeedBumpView`
+MissingNullability: androidx.car.moderator.SpeedBumpView#SpeedBumpView(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `SpeedBumpView`
+MissingNullability: androidx.car.moderator.SpeedBumpView#SpeedBumpView(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `SpeedBumpView`
+MissingNullability: androidx.car.moderator.SpeedBumpView#addView(android.view.View, int, android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `child` in method `addView`
+MissingNullability: androidx.car.moderator.SpeedBumpView#addView(android.view.View, int, android.view.ViewGroup.LayoutParams) parameter #2:
+    Missing nullability on parameter `params` in method `addView`
+MissingNullability: androidx.car.moderator.SpeedBumpView#dispatchTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `dispatchTouchEvent`
diff --git a/collection/collection/api/api_lint.ignore b/collection/collection/api/api_lint.ignore
index c01fd32..d3bdfc2 100644
--- a/collection/collection/api/api_lint.ignore
+++ b/collection/collection/api/api_lint.ignore
@@ -17,6 +17,58 @@
     Method can be invoked with an indexing operator from Kotlin: `get` (this is usually desirable; just make sure it makes sense for this type of object)
 
 
+MissingNullability: androidx.collection.ArrayMap#ArrayMap(androidx.collection.SimpleArrayMap) parameter #0:
+    Missing nullability on parameter `map` in method `ArrayMap`
+MissingNullability: androidx.collection.ArrayMap#entrySet():
+    Missing nullability on method `entrySet` return
+MissingNullability: androidx.collection.ArrayMap#keySet():
+    Missing nullability on method `keySet` return
+MissingNullability: androidx.collection.ArrayMap#putAll(java.util.Map<? extends K,? extends V>) parameter #0:
+    Missing nullability on parameter `map` in method `putAll`
+MissingNullability: androidx.collection.ArrayMap#values():
+    Missing nullability on method `values` return
+MissingNullability: androidx.collection.ArraySet#equals(Object) parameter #0:
+    Missing nullability on parameter `object` in method `equals`
+MissingNullability: androidx.collection.ArraySet#iterator():
+    Missing nullability on method `iterator` return
+MissingNullability: androidx.collection.ArraySet#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.collection.LongSparseArray#clone():
+    Missing nullability on method `clone` return
+MissingNullability: androidx.collection.LongSparseArray#remove(long, Object) parameter #1:
+    Missing nullability on parameter `value` in method `remove`
+MissingNullability: androidx.collection.LongSparseArray#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.collection.LruCache#snapshot():
+    Missing nullability on method `snapshot` return
+MissingNullability: androidx.collection.LruCache#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.collection.SimpleArrayMap#SimpleArrayMap(androidx.collection.SimpleArrayMap<K,V>) parameter #0:
+    Missing nullability on parameter `map` in method `SimpleArrayMap`
+MissingNullability: androidx.collection.SimpleArrayMap#containsValue(Object) parameter #0:
+    Missing nullability on parameter `value` in method `containsValue`
+MissingNullability: androidx.collection.SimpleArrayMap#equals(Object) parameter #0:
+    Missing nullability on parameter `object` in method `equals`
+MissingNullability: androidx.collection.SimpleArrayMap#get(Object) parameter #0:
+    Missing nullability on parameter `key` in method `get`
+MissingNullability: androidx.collection.SimpleArrayMap#getOrDefault(Object, V) parameter #0:
+    Missing nullability on parameter `key` in method `getOrDefault`
+MissingNullability: androidx.collection.SimpleArrayMap#remove(Object) parameter #0:
+    Missing nullability on parameter `key` in method `remove`
+MissingNullability: androidx.collection.SimpleArrayMap#remove(Object, Object) parameter #0:
+    Missing nullability on parameter `key` in method `remove`
+MissingNullability: androidx.collection.SimpleArrayMap#remove(Object, Object) parameter #1:
+    Missing nullability on parameter `value` in method `remove`
+MissingNullability: androidx.collection.SimpleArrayMap#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.collection.SparseArrayCompat#clone():
+    Missing nullability on method `clone` return
+MissingNullability: androidx.collection.SparseArrayCompat#remove(int, Object) parameter #1:
+    Missing nullability on parameter `value` in method `remove`
+MissingNullability: androidx.collection.SparseArrayCompat#toString():
+    Missing nullability on method `toString` return
+
+
 NoClone: androidx.collection.LongSparseArray#clone():
     Provide an explicit copy constructor instead of implementing `clone()`
 NoClone: androidx.collection.SparseArrayCompat#clone():
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/ComposableCheckerTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/ComposableCheckerTests.kt
index c1ebba3..6c81875 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/ComposableCheckerTests.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/ComposableCheckerTests.kt
@@ -871,13 +871,13 @@
             import android.widget.TextView;
 
             @Composable
-            fun CraneWrapperComposable(@Children children: () -> Unit) {
+            fun CraneWrapperComposable(children: @Composable() () -> Unit) {
                 <MyCraneWrapper>
                     <children />
                 </MyCraneWrapper>
             }
 
-            class MyCraneWrapper(@Children var children: () -> Unit) : Component() {
+            class MyCraneWrapper(var children: @Composable() () -> Unit) : Component() {
                 override fun compose() { }
             }
         """)
@@ -889,16 +889,16 @@
             import androidx.compose.*
             import android.widget.TextView;
 
-            typealias UNIT_LAMBDA = () -> Unit
+            typealias COMPOSABLE_UNIT_LAMBDA = @Composable() () -> Unit
 
             @Composable
-            fun CraneWrapperComposable(@Children children: UNIT_LAMBDA) {
+            fun CraneWrapperComposable(children: COMPOSABLE_UNIT_LAMBDA) {
                 <MyCraneWrapper>
                     <children />
                 </MyCraneWrapper>
             }
 
-            class MyCraneWrapper(@Children var children: UNIT_LAMBDA) : Component() {
+            class MyCraneWrapper(var children: COMPOSABLE_UNIT_LAMBDA) : Component() {
                 override fun compose() { }
             }
         """)
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/TryCatchComposableCheckerTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/TryCatchComposableCheckerTests.kt
new file mode 100644
index 0000000..0af9864
--- /dev/null
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/TryCatchComposableCheckerTests.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2019 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.plugins.kotlin.analysis
+
+import androidx.compose.plugins.kotlin.AbstractComposeDiagnosticsTest
+
+
+/**
+ * We're strongly considering supporting try-catch-finally blocks in the future.
+ * If/when we do support them, these tests should be deleted.
+ */
+class TryCatchComposableCheckerTests : AbstractComposeDiagnosticsTest() {
+
+    fun testTryCatchReporting001() {
+        doTest(
+            """
+            import androidx.compose.*;
+
+            @Composable fun foo() { }
+
+            @Composable fun bar() {
+                <!ILLEGAL_TRY_CATCH_AROUND_COMPOSABLE!>try<!> {
+                    foo()
+                } catch(e: Exception) {
+                }
+            }
+        """)
+    }
+
+    fun testTryCatchReporting002() {
+        doTest(
+            """
+            import androidx.compose.*;
+
+            fun foo() { }
+
+            @Composable fun bar() {
+                try {
+                    foo()
+                } catch(e: Exception) {
+                }
+            }
+        """)
+    }
+
+    fun testTryCatchReporting003() {
+        doTest(
+            """
+            import androidx.compose.*;
+
+            @Composable fun foo() { }
+
+            @Composable fun bar() {
+                try {
+                } catch(e: Exception) {
+                    foo()
+                } finally {
+                    foo()
+                }
+            }
+        """)
+    }
+
+    fun testTryCatchReporting004() {
+        doTest(
+            """
+            import androidx.compose.*;
+
+            @Composable fun foo() { }
+
+            @Composable fun bar() {
+                <!ILLEGAL_TRY_CATCH_AROUND_COMPOSABLE!>try<!> {
+                    (1..10).forEach { foo() }
+                } catch(e: Exception) {
+                }
+            }
+        """)
+    }
+}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposePlugin.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposePlugin.kt
index bab14b9..807cdb4 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposePlugin.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposePlugin.kt
@@ -117,6 +117,10 @@
                 project,
                 UnionAnnotationCheckerProvider()
             )
+            StorageComponentContainerContributor.registerExtension(
+                project,
+                TryCatchComposableChecker()
+            )
             KtxParsingExtension.registerExtension(project,
                 ComposeKtxParsingExtension()
             )
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/TryCatchComposableChecker.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/TryCatchComposableChecker.kt
new file mode 100644
index 0000000..8f2a6c3
--- /dev/null
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/TryCatchComposableChecker.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2019 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.plugins.kotlin
+
+import com.intellij.psi.PsiElement
+import org.jetbrains.kotlin.container.StorageComponentContainer
+import org.jetbrains.kotlin.container.useInstance
+import org.jetbrains.kotlin.descriptors.ModuleDescriptor
+import org.jetbrains.kotlin.diagnostics.reportFromPlugin
+import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
+import org.jetbrains.kotlin.psi.KtFunction
+import androidx.compose.plugins.kotlin.analysis.ComposeDefaultErrorMessages
+import androidx.compose.plugins.kotlin.analysis.ComposeErrors
+import org.jetbrains.kotlin.psi.KtTryExpression
+import org.jetbrains.kotlin.resolve.TargetPlatform
+import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
+import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
+import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
+import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
+
+open class TryCatchComposableChecker: CallChecker, StorageComponentContainerContributor {
+
+    override fun registerModuleComponents(
+        container: StorageComponentContainer,
+        platform: TargetPlatform,
+        moduleDescriptor: ModuleDescriptor
+    ) {
+        if (platform != JvmPlatform) return
+        container.useInstance(this)
+    }
+
+    override fun check(
+        resolvedCall: ResolvedCall<*>,
+        reportOn: PsiElement,
+        context: CallCheckerContext
+    ) {
+        val trace = context.trace
+        val call = resolvedCall.call.callElement
+        val shouldBeTag = ComposableAnnotationChecker.get(call.project).shouldInvokeAsTag(trace, resolvedCall)
+        if(shouldBeTag) {
+            var walker: PsiElement? = call
+            while (walker != null) {
+                val parent = walker.parent
+                if(parent is KtTryExpression) {
+                    if(walker == parent.tryBlock)
+                        trace.reportFromPlugin(
+                            ComposeErrors.ILLEGAL_TRY_CATCH_AROUND_COMPOSABLE.on(parent.tryKeyword!!),
+                            ComposeDefaultErrorMessages
+                        )
+                }
+                walker = try { walker.parent } catch (e: Throwable) { null }
+            }
+        }
+    }
+
+}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeDefaultErrorMessages.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeDefaultErrorMessages.kt
index ced33ab..44a6471 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeDefaultErrorMessages.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeDefaultErrorMessages.kt
@@ -162,5 +162,9 @@
             "Children annotation must only occur on last parameter.  This annotation is deprecated (move children to " +
                     "be last parameter, make it @Composable, and remove the @Children annotation.)."
         )
+        MAP.put(
+            ComposeErrors.ILLEGAL_TRY_CATCH_AROUND_COMPOSABLE,
+            "Try catch is not supported around composable function invocations."
+        )
     }
 }
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeErrors.java b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeErrors.java
index a9b2802..810ce18 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeErrors.java
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeErrors.java
@@ -96,6 +96,8 @@
             ILLEGAL_ASSIGN_TO_UNIONTYPE = DiagnosticFactory2.create(ERROR);
     DiagnosticFactory0<KtElement>
             CHILDREN_MUST_BE_LAST = DiagnosticFactory0.create(ERROR);
+    DiagnosticFactory0<PsiElement>
+            ILLEGAL_TRY_CATCH_AROUND_COMPOSABLE = DiagnosticFactory0.create(ERROR);
 
     @SuppressWarnings("UnusedDeclaration")
     Object INITIALIZER = new Object() {
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/ComposeAttributeCompletionSession.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/ComposeAttributeCompletionSession.kt
index 857529a..51a5616 100644
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/ComposeAttributeCompletionSession.kt
+++ b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/ComposeAttributeCompletionSession.kt
@@ -122,9 +122,6 @@
             myTailText += " (from $klass)"
         }
 
-        if (isChildren) {
-            myTailText += " (@Children)"
-        }
         if (isRequired) {
             myTailText += " (required)"
         }
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/AnnotateTargetWithComposableQuickFix.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/AnnotateTargetWithComposableQuickFix.kt
index a343329..a1e390f 100644
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/AnnotateTargetWithComposableQuickFix.kt
+++ b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/AnnotateTargetWithComposableQuickFix.kt
@@ -37,7 +37,6 @@
 import androidx.compose.plugins.kotlin.ComposeFqNames
 import androidx.compose.plugins.kotlin.analysis.ComposeErrors
 
-// TODO(lmr): we should do the same with @Children
 class AnnotateTargetWithComposableQuickFix(
     private val expression: KtElement
 ) : KotlinQuickFixAction<KtElement>(expression) {
diff --git a/compose/compose-runtime/build.gradle b/compose/compose-runtime/build.gradle
index 52f9ae6..de2185c3 100644
--- a/compose/compose-runtime/build.gradle
+++ b/compose/compose-runtime/build.gradle
@@ -14,10 +14,6 @@
  * limitations under the License.
  */
 
-
-import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-
 import static androidx.build.dependencies.DependenciesKt.*
 import androidx.build.LibraryGroups
 import androidx.build.LibraryVersions
@@ -25,6 +21,7 @@
 
 plugins {
     id("AndroidXPlugin")
+    id("AndroidXUiPlugin")
     id("com.android.library")
     id("kotlin-multiplatform")
 }
@@ -34,31 +31,24 @@
 
     sourceSets {
         commonMain.dependencies {
-            implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$KOTLIN_VERSION"
-        }
-        commonTest.dependencies {
-            // TODO https://youtrack.jetbrains.com/issue/KT-29343
-            implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$KOTLIN_VERSION"
-            implementation(kotlin("test-annotations-common"))
-        }
-        androidMain.dependencies {
-            implementation "androidx.annotation:annotation:1.0.0"
             implementation(KOTLIN_COMPOSE_STDLIB)
             implementation(KOTLIN_COMPOSE_REFLECT)
         }
-        androidTest.dependencies {
+        commonTest.dependencies {
+            implementation kotlin("test-junit")
         }
-
+        androidMain.dependencies {
+            implementation "androidx.annotation:annotation:1.0.0"
+        }
+        androidAndroidTest.dependencies {
+            implementation(KOTLIN_COMPOSE_REFLECT)
+            implementation(ANDROIDX_TEST_EXT_JUNIT)
+            implementation(ANDROIDX_TEST_RULES)
+        }
     }
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 18
-    }
-    lintOptions {
-        disable("SyntheticAccessor")
-    }
     buildTypes {
         debug {
             testCoverageEnabled = false
@@ -67,11 +57,6 @@
             testCoverageEnabled = false
         }
     }
-    sourceSets {
-        main {
-            manifest.srcFile 'src/androidMain/AndroidManifest.xml'
-        }
-    }
 }
 
 androidx {
diff --git a/compose/compose-runtime/compose-runtime-benchmark/build.gradle b/compose/compose-runtime/compose-runtime-benchmark/build.gradle
index 22c1201..dcb32f6 100644
--- a/compose/compose-runtime/compose-runtime-benchmark/build.gradle
+++ b/compose/compose-runtime/compose-runtime-benchmark/build.gradle
@@ -30,10 +30,6 @@
 android {
     defaultConfig {
         minSdkVersion 21
-
-        // Work-around for setting the testBuildType to "release" for benchmark projects causes gradle import get
-        // confused.
-        testBuildType = "debug"
     }
     lintOptions {
         disable("SyntheticAccessor")
diff --git a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/realworld4/RealWorld4_Widgets.kt b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/realworld4/RealWorld4_Widgets.kt
index eda5f71..3cfbc1d 100644
--- a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/realworld4/RealWorld4_Widgets.kt
+++ b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/realworld4/RealWorld4_Widgets.kt
@@ -28,7 +28,7 @@
 import androidx.ui.foundation.ColoredRect
 import androidx.ui.core.dp
 import androidx.ui.core.toRect
-import androidx.ui.graphics.vectorgraphics.SolidColor
+import androidx.ui.graphics.SolidColor
 import androidx.ui.painting.Paint
 import androidx.ui.graphics.Color
 import androidx.ui.layout.FlexColumn
diff --git a/compose/compose-runtime/compose-runtime-benchmark/src/main/AndroidManifest.xml b/compose/compose-runtime/compose-runtime-benchmark/src/main/AndroidManifest.xml
index 93790c2..4979ece 100644
--- a/compose/compose-runtime/compose-runtime-benchmark/src/main/AndroidManifest.xml
+++ b/compose/compose-runtime/compose-runtime-benchmark/src/main/AndroidManifest.xml
@@ -13,5 +13,4 @@
   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.compose.benchmark"/>
\ No newline at end of file
+<manifest package="androidx.compose.benchmark"/>
\ No newline at end of file
diff --git a/compose/compose-runtime/integration-tests/android-tests/build.gradle b/compose/compose-runtime/integration-tests/android-tests/build.gradle
deleted file mode 100644
index e733507..0000000
--- a/compose/compose-runtime/integration-tests/android-tests/build.gradle
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2019 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 org.jetbrains.kotlin.codegen.ImplementationBodyCodegen
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-
-import static androidx.build.dependencies.DependenciesKt.*
-import androidx.build.LibraryGroups
-import androidx.build.LibraryVersions
-import androidx.build.Publish
-
-plugins {
-    id("AndroidXPlugin")
-    id("com.android.library")
-    id("kotlin-android")
-}
-
-dependencies {
-    androidTestImplementation(project(":compose:compose-runtime"))
-    androidTestImplementation(project(":compose:compose-runtime:integration-tests"))
-
-    androidTestImplementation(KOTLIN_COMPOSE_STDLIB)
-    androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
-    androidTestImplementation(ANDROIDX_TEST_RULES)
-}
-
-android {
-    defaultConfig {
-        minSdkVersion 18
-    }
-}
diff --git a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/AndroidManifest.xml b/compose/compose-runtime/integration-tests/android-tests/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index bb550d8..0000000
--- a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright 2019 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
-        package="androidx.compose.integrationtests.androidtests" xmlns:android="http://schemas.android.com/apk/res/android">
-    <application>
-        <activity
-            android:name="androidx.compose.TestActivity"/>
-        <activity
-            android:name="androidx.compose.ComposeIntoTestActivity"/>
-        <activity
-            android:name="androidx.compose.DisposeTests$DisposeTestActivity"/>
-    </application>
-</manifest>
diff --git a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ComposeIntoTests.kt b/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ComposeIntoTests.kt
deleted file mode 100644
index 00dc77a..0000000
--- a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ComposeIntoTests.kt
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2019 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
-
-import android.app.Activity
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import androidx.test.rule.ActivityTestRule
-import org.junit.Assert.assertEquals
-import org.junit.Ignore
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-class ComposeIntoTests {
-
-    @get:Rule
-    val activityRule = ActivityTestRule(ComposeIntoTestActivity::class.java)
-
-    @Test
-    @SmallTest
-    @Ignore("TODO(b/138720405): Investigate synchronisation issues in tests")
-    fun testMultipleSetContentCalls() {
-        val activity = activityRule.activity
-        activity.run()
-
-        assertEquals(1, activity.initializationCount)
-        assertEquals(1, activity.commitCount)
-        activity.run()
-
-        // if we call setContent multiple times, we want to ensure that it doesn't tear
-        // down the whole hierarchy, so onActive should only get called once.
-        assertEquals(1, activity.initializationCount)
-        assertEquals(2, activity.commitCount)
-    }
-}
-
-class ComposeIntoTestActivity : Activity() {
-    var initializationCount = 0
-    var commitCount = 0
-
-    fun run() {
-        setViewContent {
-            +onActive { initializationCount++ }
-            +onCommit { commitCount++ }
-        }
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ComposeModelTests.kt b/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ComposeModelTests.kt
deleted file mode 100644
index cfd4457..0000000
--- a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ComposeModelTests.kt
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Copyright 2019 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
-
-import android.app.Activity
-import android.view.ViewGroup
-import android.widget.TextView
-import androidx.compose.frames.AbstractRecord
-import androidx.compose.frames.Framed
-import androidx.compose.frames.Record
-import androidx.compose.frames._created
-import androidx.compose.frames._readable
-import androidx.compose.frames._writable
-import androidx.compose.frames.currentFrame
-import androidx.test.annotation.UiThreadTest
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import androidx.test.rule.ActivityTestRule
-import junit.framework.TestCase.assertEquals
-import junit.framework.TestCase.assertFalse
-import org.junit.Ignore
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-val PRESIDENT_NAME_1 = "George Washington"
-val PRESIDENT_AGE_1 = 57
-val PRESIDENT_NAME_16 = "Abraham Lincoln"
-val PRESIDENT_AGE_16 = 52
-
-class Person(name: String, age: Int) : Framed {
-    var name
-        get() = (_readable(_first, this) as CustomerRecord).name
-        set(value) {
-            (_writable(_first, this) as CustomerRecord).name = value
-        }
-
-    var age
-        get() = (_readable(_first, this) as CustomerRecord).age
-        set(value) {
-            (_writable(_first, this) as CustomerRecord).age = value
-        }
-
-    private var _first: Record = CustomerRecord().apply {
-        this.name = name
-        this.age = age
-        this.frameId = currentFrame().id
-        _created(this@Person)
-    }
-
-    override val firstFrameRecord: Record get() = _first
-
-    override fun prependFrameRecord(value: Record) {
-        value.next = _first
-        _first = value
-    }
-
-    class CustomerRecord : AbstractRecord() {
-        @JvmField
-        var name: String = ""
-        @JvmField
-        var age: Int = 0
-
-        override fun assign(value: Record) {
-            (value as? CustomerRecord)?.let {
-                this.name = it.name
-                this.age = it.age
-            }
-        }
-
-        override fun create() = CustomerRecord()
-    }
-}
-
-class TestState<T>(value: T) : Framed {
-    @Suppress("UNCHECKED_CAST")
-    var value: T
-        get() = (_readable(myFirst, this) as StateRecord<T>).value
-        set(value) {
-            (_writable(myFirst, this) as StateRecord<T>).value = value
-        }
-
-    private var myFirst: Record
-
-    init {
-        myFirst = StateRecord(value)
-    }
-
-    override val firstFrameRecord: Record
-        get() = myFirst
-
-    override fun prependFrameRecord(value: Record) {
-        value.next = myFirst
-        myFirst = value
-    }
-
-    private class StateRecord<T>(myValue: T) : AbstractRecord() {
-        override fun assign(value: Record) {
-            @Suppress("UNCHECKED_CAST")
-            this.value = (value as StateRecord<T>).value
-        }
-
-        override fun create(): Record = StateRecord(value)
-
-        var value: T = myValue
-    }
-}
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class ModelViewTests {
-
-    @get:Rule
-    val activityRule = ActivityTestRule(TestActivity::class.java)
-
-    @Test
-    @UiThreadTest
-    fun testModelView_Simple(): Unit = FrameManager.isolated {
-        val tvId = 67
-        compose {
-            emit(62, { context ->
-                TextView(context).apply {
-                    text = "Hello world!"; id = tvId
-                }
-            }) { }
-        }.then { activity ->
-            val tv = activity.root.findViewById(tvId) as TextView
-            assertEquals("Hello world!", tv.text)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testModelView_Simple_Recompose(): Unit = FrameManager.isolated {
-        val tvId = 71
-        compose {
-            emit(73, { context ->
-                TextView(context).apply {
-                    text = "Hello world!"; id = tvId
-                }
-            }) { }
-        }.then { activity ->
-            val tv = activity.root.findViewById(tvId) as TextView
-            assertEquals("Hello world!", tv.text)
-        }.then { activity ->
-            val tv = activity.root.findViewById(tvId) as TextView
-            assertEquals("Hello world!", tv.text)
-        }
-    }
-
-    @Test
-    @Ignore("TODO(b/138720405): Investigate synchronisation issues in tests")
-    @UiThreadTest
-    fun testModelView_PersonModel(): Unit = FrameManager.isolated {
-        val tvIdName = 90
-        val tvIdAge = 91
-        val president = Person(
-            PRESIDENT_NAME_1,
-            PRESIDENT_AGE_1
-        )
-        compose {
-            call(147, { true }) {
-                @Suppress("PLUGIN_ERROR")
-                (Observe {
-                    emit(93, { context -> TextView(context).apply { id = tvIdName } }) {
-                        set(president.name) { text = it }
-                    }
-                    emit(94, { context -> TextView(context).apply { id = tvIdAge } }) {
-                        set(president.age) { text = it.toString() }
-                    }
-                })
-            }
-        }.then {
-            val tvName = it.findViewById(tvIdName) as TextView
-            val tvAge = it.findViewById(tvIdAge) as TextView
-            assertEquals(PRESIDENT_NAME_1, tvName.text)
-            assertEquals(PRESIDENT_AGE_1.toString(), tvAge.text)
-
-            president.name = PRESIDENT_NAME_16
-            president.age = PRESIDENT_AGE_16
-        }.then {
-            val tvName = it.findViewById(tvIdName) as TextView
-            val tvAge = it.findViewById(tvIdAge) as TextView
-            assertEquals(PRESIDENT_NAME_16, tvName.text)
-            assertEquals(PRESIDENT_AGE_16.toString(), tvAge.text)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testModelView_RecomposeScopeCleanup(): Unit = FrameManager.isolated {
-        val washington = Person(
-            PRESIDENT_NAME_1,
-            PRESIDENT_AGE_1
-        )
-        val lincoln = Person(
-            PRESIDENT_NAME_16,
-            PRESIDENT_AGE_16
-        )
-        val displayLincoln = TestState(true)
-
-        fun ViewComposition.display(person: Person) {
-            call(167, { true }) {
-                @Suppress("PLUGIN_ERROR")
-                (Observe {
-                    emit(93, { context -> TextView(context) }) {
-                        set(person.name) { text = it }
-                    }
-                    emit(94, { context -> TextView(context) }) {
-                        set(person.age) { text = it.toString() }
-                    }
-                })
-            }
-        }
-
-        compose {
-            call(185, { true }) {
-                @Suppress("PLUGIN_ERROR")
-                (Observe {
-                    display(washington)
-                    if (displayLincoln.value)
-                        display(lincoln)
-                })
-            }
-        }.then {
-            displayLincoln.value = false
-        }.then {
-            assertFalse(displayLincoln.value)
-        }.then {
-            assertFalse(displayLincoln.value)
-        }
-    }
-
-    // b/122548164
-    @Test
-    @Ignore("TODO(b/138720405): Investigate synchronisation issues in tests")
-    fun testObserverEntering(): Unit = FrameManager.isolated {
-        val president = Person(
-            PRESIDENT_NAME_1,
-            PRESIDENT_AGE_1
-        )
-        val tvName = 204
-
-        fun ViewComposition.display(person: Person) {
-            call(167, { true }) {
-                @Suppress("PLUGIN_ERROR")
-                (Observe {
-                    emit(93, { context -> TextView(context).apply { id = tvName } }) {
-                        set(person.name) { text = it }
-                    }
-                    emit(94, { context -> TextView(context) }) {
-                        set(person.age) { text = it.toString() }
-                    }
-                })
-                if (person.name == PRESIDENT_NAME_16) {
-                    @Suppress("PLUGIN_ERROR")
-                    (Observe {
-                        emit(211, { context -> TextView(context) }) {
-                            set(person.name) { text = it }
-                        }
-                        emit(211, { context -> TextView(context) }) {
-                            set(person.age) { text = it.toString() }
-                        }
-                    })
-                }
-            }
-        }
-
-        compose {
-            call(219, { true }) {
-                @Suppress("PLUGIN_ERROR")
-                (Observe {
-                    display(president)
-                })
-            }
-        }.then { activity ->
-            assertEquals(PRESIDENT_NAME_1, (activity.findViewById(tvName) as TextView).text)
-            president.name = PRESIDENT_NAME_16
-        }.then { activity ->
-            assertEquals(PRESIDENT_NAME_16, (activity.findViewById(tvName) as TextView).text)
-        }
-    }
-
-    @Test
-    @Ignore("TODO(b/138720405): Investigate synchronisation issues in tests")
-    fun testModelUpdatesNextFrameVisibility(): Unit = FrameManager.isolated {
-        val president = Person(
-            PRESIDENT_NAME_1,
-            PRESIDENT_AGE_1
-        )
-        val tvName = 204
-
-        fun ViewComposition.display(person: Person) {
-            call(167, { true }) {
-                @Suppress("PLUGIN_ERROR")
-                (Observe {
-                    emit(93, { context -> TextView(context).apply { id = tvName } }) {
-                        set(person.name) { text = it }
-                    }
-                    emit(94, { context -> TextView(context) }) {
-                        set(person.age) {
-                            text = it.toString()
-                        }
-                    }
-                })
-                if (person.name == PRESIDENT_NAME_16) {
-                    @Suppress("PLUGIN_ERROR")
-                    (Observe {
-                        emit(211, { context -> TextView(context) }) {
-                            set(person.name) { text = it }
-                        }
-                        emit(211, { context -> TextView(context) }) {
-                            set(person.age) { text = it.toString() }
-                        }
-                    })
-                }
-            }
-        }
-
-        compose {
-            call(219, { true }) {
-                @Suppress("PLUGIN_ERROR")
-                (Observe {
-                    display(president)
-                })
-            }
-        }.then { activity ->
-            assertEquals(PRESIDENT_NAME_1, (activity.findViewById(tvName) as TextView).text)
-            // schedule commit and recompose by this change, all for next frame
-            president.name = PRESIDENT_NAME_16
-            // check that changes aren't there yet
-            assertEquals(PRESIDENT_NAME_1, (activity.findViewById(tvName) as TextView).text)
-            Choreographer.postFrameCallback {
-                // after one frame we should see changes
-                assertEquals(PRESIDENT_NAME_16, (activity.findViewById(tvName) as TextView).text)
-            }
-        }
-    }
-
-    private class Root(val block: ViewComposition.() -> Unit) : Component() {
-        override fun compose() {
-            ViewComposition(composer.composer).block()
-        }
-    }
-
-    fun compose(block: ViewComposition.() -> Unit) =
-        CompositionModelTest(block, activityRule.activity)
-
-    class CompositionModelTest(val composable: ViewComposition.() -> Unit, val activity: Activity) {
-        var savedContext: CompositionContext? = null
-        inner class ActiveTest(val activity: Activity) {
-            private var firstCompose = true
-            private fun compose() {
-                if (firstCompose) {
-                    val composer = composer.composer
-                    composer.startRoot()
-                    val instance = composer.remember {
-                        Root(
-                            composable
-                        )
-                    }
-                    composer.startGroup(invocation)
-                    instance()
-                    composer.endGroup()
-                    composer.endRoot()
-                    firstCompose = false
-                    composer.applyChanges()
-                }
-            }
-
-            fun then(block: (activity: Activity) -> Unit): ActiveTest {
-                compose()
-                block(activity)
-                return this
-            }
-        }
-
-        fun then(block: (activity: Activity) -> Unit): ActiveTest {
-            val cc = Compose.createCompositionContext(
-                activity,
-                activity.root,
-                Root(composable),
-                null
-            )
-
-            // Ensure the context is not collected until the test completes.
-            savedContext = cc
-
-            return cc.composer.runWithCurrent {
-                ActiveTest(activity).then(block)
-            }
-        }
-    }
-}
-
-private val Activity.root get() = findViewById(ComposerComposeTestCase.ROOT_ID) as ViewGroup
diff --git a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ComposerComposeTestCase.kt b/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ComposerComposeTestCase.kt
deleted file mode 100644
index 6339325..0000000
--- a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ComposerComposeTestCase.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2019 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
-
-import android.app.Activity
-import android.view.ViewGroup
-
-abstract class ComposerComposeTestCase {
-
-    fun compose(activity: Activity, composable: (ViewComposition) -> Unit) =
-        ComposeTest(
-            Root(composable),
-            activity
-        )
-
-    class ComposeTest(val component: Component, val activity: Activity) {
-
-        fun then(fn: (CompositionContext, Component, ViewGroup, Activity) -> Unit) {
-            val root = activity.findViewById(ROOT_ID) as ViewGroup
-            val cc = Compose.createCompositionContext(root.context, root, component, null)
-                cc.compose()
-                fn(cc, component, root, activity)
-        }
-    }
-
-    private class Root(var composable: (ViewComposition) -> Unit) : Component() {
-        override fun compose() = composable(composer)
-    }
-
-    companion object {
-        val ROOT_ID = 18284847
-    }
-}
-
-class Counter {
-    private var counts = mutableMapOf<String, Int>()
-    fun inc(key: String) = counts.getOrPut(key, { 0 }).let { counts[key] = it + 1 }
-    fun reset() {
-        counts = mutableMapOf()
-    }
-
-    operator fun get(key: String) = counts.getOrDefault(key, 0)
-}
diff --git a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ComposerExtensions.kt b/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ComposerExtensions.kt
deleted file mode 100644
index e7f819a..0000000
--- a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ComposerExtensions.kt
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright 2019 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
-
-import android.content.Context
-import android.view.View
-import android.view.ViewGroup
-
-inline fun ViewComposition.group(key: Int, block: () -> Unit) {
-    try {
-        composer.startGroup(key)
-        block()
-    } finally {
-        composer.endGroup()
-    }
-}
-
-inline fun <reified T : Component> ViewComposition.emitComponent(
-    loc: Int,
-    ctor: () -> T,
-    noinline block: ViewValidator.(f: T) -> Boolean
-): Unit = emitComponent(loc, null, ctor, block)
-
-inline fun <reified T : Component> ViewComposition.emitComponent(
-    loc: Int,
-    ctor: () -> T
-): Unit = emitComponent(loc, null, ctor, { true })
-
-inline fun <reified T : Component> ViewComposition.emitComponent(
-    loc: Int,
-    key: Int?,
-    ctor: () -> T
-): Unit = emitComponent(loc, key, ctor, { true })
-
-inline fun <reified T : Component> ViewComposition.emitComponent(
-    loc: Int,
-    key: Int?,
-    ctor: () -> T,
-    noinline block: ViewValidator.(f: T) -> Boolean
-): Unit = call(
-    joinKey(loc, key),
-    ctor,
-    block,
-    { f -> f() }
-)
-
-inline fun <reified T : View> ViewComposition.emitView(
-    loc: Int,
-    ctor: (context: Context) -> T,
-    noinline updater: ViewUpdater<T>.() -> Unit
-): Unit = emitView(loc, null, ctor, updater)
-
-inline fun <reified T : View> ViewComposition.emitView(
-    loc: Int,
-    ctor: (context: Context) -> T
-): Unit = emitView(loc, null, ctor, {})
-
-inline fun <reified T : View> ViewComposition.emitView(
-    loc: Int,
-    key: Int?,
-    ctor: (context: Context) -> T
-): Unit = emitView(loc, key, ctor, {})
-
-inline fun <reified T : View> ViewComposition.emitView(
-    loc: Int,
-    key: Int?,
-    ctor: (context: Context) -> T,
-    noinline updater: ViewUpdater<T>.() -> Unit
-): Unit = emit(
-    joinKey(loc, key),
-    ctor,
-    updater
-)
-
-inline fun <reified T : ViewGroup> ViewComposition.emitViewGroup(
-    loc: Int,
-    ctor: (context: Context) -> T,
-    noinline updater: ViewUpdater<T>.() -> Unit,
-    block: () -> Unit
-) = emitViewGroup(loc, null, ctor, updater, block)
-
-inline fun <reified T : ViewGroup> ViewComposition.emitViewGroup(
-    loc: Int,
-    key: Int?,
-    ctor: (context: Context) -> T,
-    noinline updater: ViewUpdater<T>.() -> Unit,
-    block: @Composable() () -> Unit
-) = emit(
-    joinKey(loc, key),
-    ctor,
-    updater,
-    block
-)
-
-inline fun <reified T : Emittable> ViewComposition.emitEmittable(
-    loc: Int,
-    ctor: () -> T,
-    noinline updater: ViewUpdater<T>.() -> Unit
-) = emitEmittable(loc, null, ctor, updater, {})
-
-inline fun <reified T : Emittable> ViewComposition.emitEmittable(
-    loc: Int,
-    ctor: () -> T,
-    noinline updater: ViewUpdater<T>.() -> Unit,
-    block: () -> Unit
-) = emitEmittable(loc, null, ctor, updater, block)
-
-inline fun <reified T : Emittable> ViewComposition.emitEmittable(
-    loc: Int,
-    key: Int?,
-    ctor: () -> T,
-    noinline updater: ViewUpdater<T>.() -> Unit,
-    block: () -> Unit
-) = emit(
-    joinKey(loc, key),
-    ctor,
-    updater,
-    block
-)
-
-inline fun <reified T> ViewComposition.provideAmbient(
-    key: Ambient<T>,
-    value: T,
-    noinline children: @Composable() () -> Unit
-) = call(
-    0,
-    { changed(key) + changed(value) + changed(children) },
-    { @Suppress("PLUGIN_ERROR") key.Provider(value, children) }
-)
\ No newline at end of file
diff --git a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/CompositionTests.kt b/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/CompositionTests.kt
deleted file mode 100644
index cd26098..0000000
--- a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/CompositionTests.kt
+++ /dev/null
@@ -1,1813 +0,0 @@
-/*
- * Copyright 2019 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
-
-import androidx.compose.mock.Compose
-import androidx.compose.mock.Contact
-import androidx.compose.mock.ContactModel
-import androidx.compose.mock.MockViewComposer
-import androidx.compose.mock.MockViewComposition
-import androidx.compose.mock.MockViewValidator
-import androidx.compose.mock.Point
-import androidx.compose.mock.Report
-import androidx.compose.mock.View
-import androidx.compose.mock.ViewComponent
-import androidx.compose.mock.call
-import androidx.compose.mock.contact
-import androidx.compose.mock.edit
-import androidx.compose.mock.join
-import androidx.compose.mock.linear
-import androidx.compose.mock.memoize
-import androidx.compose.mock.points
-import androidx.compose.mock.remember
-import androidx.compose.mock.repeat
-import androidx.compose.mock.reportsReport
-import androidx.compose.mock.reportsTo
-import androidx.compose.mock.selectContact
-import androidx.compose.mock.set
-import androidx.compose.mock.skip
-import androidx.compose.mock.text
-import androidx.compose.mock.update
-import androidx.compose.mock.validate
-import androidx.test.filters.SmallTest
-import junit.framework.TestCase
-import org.junit.Assert
-
-@SmallTest
-class CompositionTests : TestCase() {
-    fun testComposeAModel() {
-        val model = testModel()
-        val composer = compose(model)
-
-        validate(composer.root) {
-            linear {
-                linear {
-                    text("Filter:")
-                    edit("")
-                }
-                linear {
-                    text(value = "Contacts:")
-                    linear {
-                        contact(bob)
-                        contact(jon)
-                        contact(steve)
-                    }
-                }
-            }
-        }
-    }
-
-    fun testRecomposeWithoutChanges() {
-        val model = testModel()
-        val composer = compose(model)
-
-        compose(model, composer, expectChanges = false)
-
-        validate(composer.root) {
-            selectContact(model)
-        }
-    }
-
-    fun testInsertAContact() {
-        val model =
-            testModel(mutableListOf(bob, jon))
-        val composer = compose(model)
-
-        validate(composer.root) {
-            linear {
-                skip()
-                linear {
-                    skip()
-                    linear {
-                        contact(bob)
-                        contact(jon)
-                    }
-                }
-            }
-        }
-
-        model.add(steve, after = bob)
-        compose(model, composer)
-
-        validate(composer.root) {
-            linear {
-                skip()
-                linear {
-                    skip()
-                    linear {
-                        contact(bob)
-                        contact(steve)
-                        contact(jon)
-                    }
-                }
-            }
-        }
-    }
-
-    fun testMoveAContact() {
-        val model = testModel(
-            mutableListOf(
-                bob,
-                steve,
-                jon
-            )
-        )
-        val composer = compose(model)
-
-        model.move(steve, after = jon)
-        compose(model, composer)
-
-        validate(composer.root) {
-            linear {
-                skip()
-                linear {
-                    skip()
-                    linear {
-                        contact(bob)
-                        contact(jon)
-                        contact(steve)
-                    }
-                }
-            }
-        }
-    }
-
-    fun testChangeTheFilter() {
-        val model = testModel(
-            mutableListOf(
-                bob,
-                steve,
-                jon
-            )
-        )
-        val composer = compose(model)
-
-        model.filter = "Jon"
-        compose(model, composer)
-
-        validate(composer.root) {
-            linear {
-                skip()
-                linear {
-                    skip()
-                    linear {
-                        contact(jon)
-                    }
-                }
-            }
-        }
-    }
-
-    fun testComposeCompositionWithMultipleRoots() {
-        val reports = listOf(
-            jim_reports_to_sally,
-            rob_reports_to_alice,
-            clark_reports_to_lois
-        )
-
-        val composer = compose {
-            reportsReport(reports)
-        }
-
-        validate(composer.root) {
-            reportsReport(reports)
-        }
-    }
-
-    fun testMoveCompositionWithMultipleRoots() {
-        val reports = listOf(
-            jim_reports_to_sally,
-            rob_reports_to_alice,
-            clark_reports_to_lois
-        )
-        val composer = compose {
-            reportsReport(reports)
-        }
-
-        val newReports = listOf(
-            jim_reports_to_sally,
-            clark_reports_to_lois,
-            rob_reports_to_alice
-        )
-        compose(composer) {
-            reportsReport(newReports)
-        }
-
-        validate(composer.root) {
-            reportsReport(newReports)
-        }
-    }
-
-    fun testReplace() {
-        var includeA = true
-        fun MockViewComposition.composition() {
-            text("Before")
-            if (includeA) {
-                linear {
-                    text("A")
-                }
-            } else {
-                edit("B")
-            }
-            text("After")
-        }
-        fun MockViewValidator.composition() {
-            text("Before")
-            if (includeA) {
-                linear {
-                    text("A")
-                }
-            } else {
-                edit("B")
-            }
-            text("After")
-        }
-        val composer = compose {
-            composition()
-        }
-        validate(composer.root) {
-            composition()
-        }
-        includeA = false
-        compose(composer) {
-            composition()
-        }
-        validate(composer.root) {
-            composition()
-        }
-        includeA = true
-        compose(composer) {
-            composition()
-        }
-        validate(composer.root) {
-            composition()
-        }
-    }
-
-    fun testInsertWithMultipleRoots() {
-        val chars = listOf('a', 'b', 'c')
-
-        fun MockViewComposition.textOf(c: Char) {
-            text(c.toString())
-        }
-
-        fun MockViewValidator.textOf(c: Char) {
-            text(c.toString())
-        }
-
-        fun MockViewComposition.chars(chars: Iterable<Char>) {
-            repeat(of = chars) { c -> textOf(c) }
-        }
-
-        fun MockViewValidator.chars(chars: Iterable<Char>) {
-            repeat(of = chars) { c -> textOf(c) }
-        }
-
-        val composer = compose {
-            chars(chars)
-            chars(chars)
-            chars(chars)
-        }.apply { applyChanges() }
-
-        validate(composer.root) {
-            chars(chars)
-            chars(chars)
-            chars(chars)
-        }
-
-        val newChars = listOf('a', 'b', 'x', 'c')
-
-        compose(composer) {
-            chars(newChars)
-            chars(newChars)
-            chars(newChars)
-        }.apply { applyChanges() }
-
-        validate(composer.root) {
-            chars(newChars)
-            chars(newChars)
-            chars(newChars)
-        }
-    }
-
-    fun testSimpleMemoize() {
-        val points = listOf(Point(1, 2), Point(2, 3))
-        val composer = compose {
-            points(points)
-        }.apply { applyChanges() }
-
-        validate(composer.root) { points(points) }
-
-        compose(composer, expectChanges = false) {
-            points(points)
-        }
-    }
-
-    fun testMovingMemoization() {
-        val points = listOf(
-            Point(1, 2),
-            Point(2, 3),
-            Point(4, 5),
-            Point(6, 7)
-        )
-        val composer = compose {
-            points(points)
-        }
-
-        validate(composer.root) { points(points) }
-
-        val modifiedPoints = listOf(
-            Point(1, 2),
-            Point(4, 5),
-            Point(2, 3),
-            Point(6, 7)
-        )
-        compose(composer) {
-            points(modifiedPoints)
-        }
-
-        validate(composer.root) { points(modifiedPoints) }
-    }
-
-    fun testComponent() {
-        val slReportReports = object {}
-
-        class Reporter : ViewComponent() {
-            var report: Report? = null
-
-            override fun compose() {
-                val r = report
-                if (r != null) {
-                    text(r.from)
-                    text("reports to")
-                    text(r.to)
-                } else {
-                    text("no report to report")
-                }
-            }
-        }
-
-        fun MockViewComposition.reportsReport(reports: Iterable<Report>) {
-            linear {
-                repeat(of = reports) { report ->
-                    call(
-                        slReportReports,
-                        { Reporter() },
-                        { set(report) { this.report = it } },
-                        { it() }
-                    )
-                }
-            }
-        }
-
-        val reports = listOf(
-            jim_reports_to_sally,
-            rob_reports_to_alice,
-            clark_reports_to_lois
-        )
-        val composer = compose {
-            reportsReport(reports)
-        }
-
-        validate(composer.root) {
-            linear {
-                reportsTo(jim_reports_to_sally)
-                reportsTo(rob_reports_to_alice)
-                reportsTo(clark_reports_to_lois)
-            }
-        }
-
-        compose(composer, expectChanges = false) {
-            reportsReport(reports)
-        }
-    }
-
-    fun testComposeTwoAttributeComponent() {
-        class Two : ViewComponent() {
-            var first: Int = 1
-            var second: Int = 2
-
-            override fun compose() {
-                linear {
-                    text("$first $second")
-                }
-            }
-        }
-
-        fun MockViewValidator.two(first: Int, second: Int) {
-            linear {
-                text("$first $second")
-            }
-        }
-
-        val two = object {}
-        val composer = compose {
-            call(
-                two,
-                { Two() },
-                {
-                    set(41) { this.first = it }
-                    set(42) { this.second = it }
-                },
-                { it() }
-            )
-        }
-
-        validate(composer.root) {
-            two(41, 42)
-        }
-    }
-
-    fun testComposeThreeAttributeComponent() {
-        class Three : ViewComponent() {
-            var first: Int = 1
-            var second: Int = 2
-            var third: Int = 3
-
-            override fun compose() {
-                linear {
-                    text("$first $second $third")
-                }
-            }
-        }
-
-        fun MockViewValidator.three(first: Int, second: Int, third: Int) {
-            linear {
-                text("$first $second $third")
-            }
-        }
-
-        val three = object {}
-        val composer = compose {
-            call(
-                three,
-                { Three() },
-                {
-                    set(41) { this.first = it }
-                    set(42) { this.second = it }
-                    set(43) { this.third = it }
-                },
-                { it() }
-            )
-        }
-
-        validate(composer.root) {
-            three(41, 42, 43)
-        }
-    }
-
-    fun testComposeFourOrMoreAttributeComponent() {
-        class Four : ViewComponent() {
-            var first: Int = 1
-            var second: Int = 2
-            var third: Int = 3
-            var fourth: Int = 4
-
-            override fun compose() {
-                linear {
-                    text("$first $second $third $fourth")
-                }
-            }
-        }
-
-        fun MockViewValidator.four(first: Int, second: Int, third: Int, fourth: Int) {
-            linear {
-                text("$first $second $third $fourth")
-            }
-        }
-
-        val four = object {}
-        val composer = compose {
-            call(
-                four,
-                { Four() },
-                {
-                    set(41) { this.first = it }
-                    set(42) { this.second = it }
-                    set(43) { this.third = it }
-                    set(44) { this.fourth = it }
-                },
-                { it() }
-            )
-        }
-
-        validate(composer.root) {
-            four(41, 42, 43, 44)
-        }
-    }
-
-    fun testComponentWithVarCtorParameter() {
-        class One(var first: Int) : ViewComponent() {
-            override fun compose() {
-                text("$first")
-            }
-        }
-
-        fun MockViewValidator.one(first: Int) {
-            text("$first")
-        }
-
-        val key = object {}
-        fun MockViewComposition.callOne(value: Int) {
-            call(
-                key,
-                { One(first = value) },
-                {
-                    update(value) { this.first = it }
-                },
-                { it() }
-            )
-        }
-
-        var value = 42
-        val composer = compose {
-            callOne(value)
-        }
-
-        validate(composer.root) {
-            one(42)
-        }
-
-        value = 43
-
-        compose(composer) {
-            callOne(value)
-        }
-
-        validate(composer.root) {
-            one(43)
-        }
-    }
-
-    fun testComponentWithValCtorParameter() {
-        class One(val first: Int) : ViewComponent() {
-            override fun compose() {
-                text("$first")
-            }
-        }
-
-        fun MockViewValidator.one(first: Int) {
-            text("$first")
-        }
-
-        val key = object {}
-        fun MockViewComposition.callOne(value: Int) {
-            call(
-                cc.joinKey(key, value),
-                { One(first = value) },
-                { },
-                { it() }
-            )
-        }
-
-        var value = 42
-        val composer = compose {
-            callOne(value)
-        }
-
-        validate(composer.root) {
-            one(42)
-        }
-
-        value = 43
-
-        compose(composer) {
-            callOne(value)
-        }
-
-        validate(composer.root) {
-            one(43)
-        }
-
-        compose(composer, expectChanges = false) {
-            callOne(value)
-        }
-    }
-
-    fun testComposePartOfTree() {
-        val slReportReports = object {}
-        var recomposeLois: (() -> Unit)? = null
-
-        class Reporter : ViewComponent() {
-            var report: Report? = null
-
-            override fun compose() {
-                val r = report
-                if (r != null) {
-                    if (r.from == "Lois" || r.to == "Lois") recomposeLois = { recompose() }
-                    text(r.from)
-                    text("reports to")
-                    text(r.to)
-                } else {
-                    text("no report to report")
-                }
-            }
-        }
-
-        fun MockViewComposition.reportsReport(reports: Iterable<Report>) {
-            linear {
-                repeat(of = reports) { report ->
-                    call(
-                        slReportReports,
-                        { Reporter() },
-                        { set(report) { this.report = it } },
-                        { it() }
-                    )
-                }
-            }
-        }
-
-        val r = Report("Lois", "Perry")
-        val reports = listOf(
-            jim_reports_to_sally,
-            rob_reports_to_alice,
-            clark_reports_to_lois, r)
-        val composer = compose {
-            reportsReport(reports)
-        }.apply { applyChanges() }
-
-        validate(composer.root) {
-            linear {
-                reportsTo(jim_reports_to_sally)
-                reportsTo(rob_reports_to_alice)
-                reportsTo(clark_reports_to_lois)
-                reportsTo(r)
-            }
-        }
-
-        compose(composer, expectChanges = false) {
-            reportsReport(reports)
-        }
-
-        // Demote Perry
-        r.from = "Perry"
-        r.to = "Lois"
-
-        // Compose only the Lois report
-        recomposeLois?.let { it() }
-
-        composer.recompose()
-        composer.applyChanges()
-
-        validate(composer.root) {
-            linear {
-                reportsTo(jim_reports_to_sally)
-                reportsTo(rob_reports_to_alice)
-                reportsTo(clark_reports_to_lois)
-                reportsTo(r)
-            }
-        }
-    }
-
-    fun testRecomposeWithReplace() {
-        val slReportReports = object {}
-        var recomposeLois: (() -> Unit)? = null
-        var key = 0
-
-        class Reporter : ViewComponent() {
-            var report: Report? = null
-
-            override fun compose() {
-                val r = report
-                if (r != null) {
-                    if (r.from == "Lois" || r.to == "Lois") recomposeLois = { recompose() }
-                    cc.startGroup(key)
-                    text(r.from)
-                    text("reports to")
-                    text(r.to)
-                    cc.endGroup()
-                } else {
-                    text("no report to report")
-                }
-            }
-        }
-
-        fun MockViewComposition.reportsReport(reports: Iterable<Report>) {
-            linear {
-                repeat(of = reports) { report ->
-                    call(
-                        slReportReports,
-                        { Reporter() },
-                        { set(report) { this.report = it } },
-                        { it() }
-                    )
-                }
-            }
-        }
-
-        val r = Report("Lois", "Perry")
-        val reports = listOf(
-            jim_reports_to_sally,
-            rob_reports_to_alice,
-            clark_reports_to_lois, r)
-        val composer = compose {
-            reportsReport(reports)
-        }.apply { applyChanges() }
-
-        validate(composer.root) {
-            linear {
-                reportsTo(jim_reports_to_sally)
-                reportsTo(rob_reports_to_alice)
-                reportsTo(clark_reports_to_lois)
-                reportsTo(r)
-            }
-        }
-
-        compose(composer, expectChanges = false) {
-            reportsReport(reports)
-        }
-
-        // Demote Perry
-        r.from = "Perry"
-        r.to = "Lois"
-
-        // Cause a new group to be generated in the component
-        key = 2
-
-        // Compose only the Lois report
-        recomposeLois?.let { it() }
-
-        composer.recompose()
-        composer.applyChanges()
-
-        validate(composer.root) {
-            linear {
-                reportsTo(jim_reports_to_sally)
-                reportsTo(rob_reports_to_alice)
-                reportsTo(clark_reports_to_lois)
-                reportsTo(r)
-            }
-        }
-    }
-
-    fun testInvalidationAfterRemoval() {
-        val slReportReports = object {}
-        var recomposeLois: (() -> Unit)? = null
-        val key = 0
-
-        class Reporter : ViewComponent() {
-            var report: Report? = null
-
-            override fun compose() {
-                val r = report
-                if (r != null) {
-                    if (r.from == "Lois" || r.to == "Lois") recomposeLois = { recompose() }
-                    cc.startGroup(key)
-                    text(r.from)
-                    text("reports to")
-                    text(r.to)
-                    cc.endGroup()
-                } else {
-                    text("no report to report")
-                }
-            }
-        }
-
-        fun MockViewComposition.reportsReport(
-            reports: Iterable<Report>,
-            include: (report: Report) -> Boolean
-        ) {
-            linear {
-                repeat(of = reports) { report ->
-                    if (include(report)) {
-                        call(
-                            slReportReports,
-                            { Reporter() },
-                            { set(report) { this.report = it } },
-                            { it() }
-                        )
-                    }
-                }
-            }
-        }
-
-        val r = Report("Lois", "Perry")
-        val reports = listOf(
-            jim_reports_to_sally,
-            rob_reports_to_alice,
-            clark_reports_to_lois,
-            r
-        )
-        val all: (report: Report) -> Boolean = { true }
-        val notLois: (report: Report) -> Boolean = { it.from != "Lois" && it.to != "Lois" }
-        val composer = compose {
-            reportsReport(reports, all)
-        }.apply { applyChanges() }
-
-        validate(composer.root) {
-            linear {
-                reportsTo(jim_reports_to_sally)
-                reportsTo(rob_reports_to_alice)
-                reportsTo(clark_reports_to_lois)
-                reportsTo(r)
-            }
-        }
-
-        compose(composer, expectChanges = true) {
-            reportsReport(reports, notLois)
-        }
-
-        validate(composer.root) {
-            linear {
-                reportsTo(jim_reports_to_sally)
-                reportsTo(rob_reports_to_alice)
-            }
-        }
-
-        // Invalidate Lois which is now removed.
-        recomposeLois?.let { it() }
-
-        composer.recompose()
-        composer.applyChanges()
-
-        validate(composer.root) {
-            linear {
-                reportsTo(jim_reports_to_sally)
-                reportsTo(rob_reports_to_alice)
-            }
-        }
-    }
-
-    // remember()
-
-    fun testSimpleRemember() {
-        var count = 0
-
-        class Wrapper(val value: Int) {
-            init {
-                count++
-            }
-        }
-
-        fun MockViewComposition.test(value: Int) {
-            val w = remember { Wrapper(value) }
-            text("value = ${w.value}")
-        }
-
-        fun MockViewValidator.test(value: Int) {
-            text("value = $value")
-        }
-
-        val composer = compose {
-            test(1)
-        }
-
-        validate(composer.root) { test(1) }
-
-        assertEquals(1, count)
-
-        compose(composer, expectChanges = false) {
-            test(1)
-        }
-
-        // Expect the previous instance to be remembered
-        assertEquals(1, count)
-    }
-
-    fun testRememberOneParameter() {
-        var count = 0
-
-        class Wrapper(val value: Int) {
-            init {
-                count++
-            }
-        }
-
-        fun MockViewComposition.test(value: Int) {
-            val w = remember(value) { Wrapper(value) }
-            text("value = ${w.value}")
-        }
-
-        fun MockViewValidator.test(value: Int) {
-            text("value = $value")
-        }
-
-        val composer = compose {
-            test(1)
-        }
-
-        validate(composer.root) { test(1) }
-
-        compose(composer) {
-            test(2)
-        }
-
-        validate(composer.root) { test(2) }
-
-        compose(composer, expectChanges = false) {
-            test(2)
-        }
-
-        validate(composer.root) { test(2) }
-
-        assertEquals(2, count)
-    }
-
-    fun testRememberTwoParameters() {
-        var count = 0
-
-        class Wrapper(val a: Int, val b: Int) {
-            init {
-                count++
-            }
-        }
-
-        fun MockViewComposition.test(a: Int, b: Int) {
-            val w = remember(a, b) { Wrapper(a, b) }
-            text("a = ${w.a} b = ${w.b}")
-        }
-
-        fun MockViewValidator.test(a: Int, b: Int) {
-            text("a = $a b = $b")
-        }
-
-        val composer = compose {
-            test(1, 2)
-        }
-
-        validate(composer.root) { test(1, 2) }
-
-        compose(composer) {
-            test(2, 3)
-        }
-
-        validate(composer.root) { test(2, 3) }
-
-        compose(composer, expectChanges = false) {
-            test(2, 3)
-        }
-
-        validate(composer.root) { test(2, 3) }
-
-        assertEquals(2, count)
-    }
-
-    fun testRememberThreeParameters() {
-        var count = 0
-
-        class Wrapper(val a: Int, val b: Int, val c: Int) {
-            init {
-                count++
-            }
-        }
-
-        fun MockViewComposition.test(a: Int, b: Int, c: Int) {
-            val w = remember(a, b, c) { Wrapper(a, b, c) }
-            text("a = ${w.a} b = ${w.b} c = ${w.c}")
-        }
-
-        fun MockViewValidator.test(a: Int, b: Int, c: Int) {
-            text("a = $a b = $b c = $c")
-        }
-
-        val composer = compose {
-            test(1, 2, 3)
-        }
-
-        validate(composer.root) { test(1, 2, 3) }
-
-        compose(composer) {
-            test(1, 2, 4)
-        }
-
-        validate(composer.root) { test(1, 2, 4) }
-
-        compose(composer, expectChanges = false) {
-            test(1, 2, 4)
-        }
-
-        validate(composer.root) { test(1, 2, 4) }
-
-        assertEquals(2, count)
-    }
-
-    fun testRememberFourParameters() {
-        var count = 0
-
-        class Wrapper(val a: Int, val b: Int, val c: Int, val d: Int) {
-            init {
-                count++
-            }
-        }
-
-        fun MockViewComposition.test(a: Int, b: Int, c: Int, d: Int) {
-            val w = remember(a, b, c, d) { Wrapper(a, b, c, d) }
-            text("a = ${w.a} b = ${w.b} c = ${w.c} d = ${w.d}")
-        }
-
-        fun MockViewValidator.test(a: Int, b: Int, c: Int, d: Int) {
-            text("a = $a b = $b c = $c d = $d")
-        }
-
-        val composer = compose {
-            test(1, 2, 3, 4)
-        }
-
-        validate(composer.root) { test(1, 2, 3, 4) }
-
-        compose(composer) {
-            test(1, 2, 4, 5)
-        }
-
-        validate(composer.root) { test(1, 2, 4, 5) }
-
-        compose(composer, expectChanges = false) {
-            test(1, 2, 4, 5)
-        }
-
-        validate(composer.root) { test(1, 2, 4, 5) }
-
-        assertEquals(2, count)
-    }
-
-    fun testRememberFiveParameters() {
-        var count = 0
-
-        class Wrapper(val a: Int, val b: Int, val c: Int, val d: Int, val e: Int) {
-            init {
-                count++
-            }
-        }
-
-        fun MockViewComposition.test(a: Int, b: Int, c: Int, d: Int, e: Int) {
-            val w = remember(a, b, c, d, e) { Wrapper(a, b, c, d, e) }
-            text("a = ${w.a} b = ${w.b} c = ${w.c} d = ${w.d} e = ${w.e}")
-        }
-
-        fun MockViewValidator.test(a: Int, b: Int, c: Int, d: Int, e: Int) {
-            text("a = $a b = $b c = $c d = $d e = $e")
-        }
-
-        val composer = compose {
-            test(1, 2, 3, 4, 5)
-        }
-
-        validate(composer.root) { test(1, 2, 3, 4, 5) }
-
-        compose(composer) {
-            test(1, 2, 4, 5, 6)
-        }
-
-        validate(composer.root) { test(1, 2, 4, 5, 6) }
-
-        compose(composer, expectChanges = false) {
-            test(1, 2, 4, 5, 6)
-        }
-
-        validate(composer.root) { test(1, 2, 4, 5, 6) }
-
-        assertEquals(2, count)
-    }
-
-    fun testInsertGroupInContainer() {
-        val values = mutableListOf(0)
-
-        fun MockViewComposition.composition() {
-            linear {
-                for (value in values) {
-                    memoize(value, value) {
-                        text("$value")
-                    }
-                }
-            }
-        }
-
-        fun MockViewValidator.composition() {
-            linear {
-                for (value in values)
-                    text("$value")
-            }
-        }
-
-        val composer = compose { composition() }
-
-        validate(composer.root) { composition() }
-
-        for (i in 1..10) {
-            values.add(i)
-            compose(composer) { composition() }
-            validate(composer.root) { composition() }
-        }
-    }
-
-    fun testStartJoin() {
-        var text = "Starting"
-        var invalidate: (() -> Unit)? = null
-        fun MockViewComposition.composition() {
-            linear {
-                join(860) { myInvalidate ->
-                    invalidate = { myInvalidate(false) }
-                    text(text)
-                }
-            }
-        }
-
-        fun MockViewValidator.composition() {
-            linear {
-                text(text)
-            }
-        }
-
-        val composer = compose { composition() }
-
-        validate(composer.root) { composition() }
-
-        text = "Ending"
-        invalidate?.let { it() }
-
-        composer.recompose()
-        composer.applyChanges()
-
-        validate(composer.root) { composition() }
-    }
-
-    fun testInvalidateJoin_End() {
-        var text = "Starting"
-        var includeNested = true
-        var invalidate1: (() -> Unit)? = null
-        var invalidate2: (() -> Unit)? = null
-
-        fun MockViewComposition.composition() {
-            linear {
-                join(860) { myInvalidate ->
-                    invalidate1 = { myInvalidate(false) }
-                    text(text)
-                    if (includeNested) {
-                        join(899) { joinInvalidate ->
-                            invalidate2 = { joinInvalidate(false) }
-                            text("Nested in $text")
-                        }
-                    }
-                }
-            }
-        }
-
-        fun MockViewValidator.composition() {
-            linear {
-                text(text)
-                if (includeNested) {
-                    text("Nested in $text")
-                }
-            }
-        }
-
-        val composer = compose { composition() }
-
-        validate(composer.root) { composition() }
-
-        text = "Ending"
-        includeNested = false
-        invalidate1?.invoke()
-        invalidate2?.invoke()
-
-        composer.recompose()
-        composer.applyChanges()
-
-        validate(composer.root) { composition() }
-
-        composer.recompose()
-        composer.applyChanges()
-
-        validate(composer.root) { composition() }
-    }
-
-    fun testInvalidateJoin_Start() {
-        var text = "Starting"
-        var includeNested = true
-        var invalidate1: (() -> Unit)? = null
-        var invalidate2: (() -> Unit)? = null
-
-        fun MockViewComposition.composition() {
-            linear {
-                join(860) { myInvalidate ->
-                    invalidate1 = { myInvalidate(false) }
-                    if (includeNested) {
-                        join(899) { joinInvalidate ->
-                            invalidate2 = { joinInvalidate(false) }
-                            text("Nested in $text")
-                        }
-                    }
-                    text(text)
-                }
-            }
-        }
-
-        fun MockViewValidator.composition() {
-            linear {
-                if (includeNested) {
-                    text("Nested in $text")
-                }
-                text(text)
-            }
-        }
-
-        val composer = compose { composition() }
-
-        validate(composer.root) { composition() }
-
-        text = "Ending"
-        includeNested = false
-        invalidate1?.invoke()
-        invalidate2?.invoke()
-
-        composer.recompose()
-        composer.applyChanges()
-
-        validate(composer.root) { composition() }
-
-        composer.recompose()
-        composer.applyChanges()
-
-        validate(composer.root) { composition() }
-    }
-
-    // b/132638679
-    fun testJoinInvalidate() {
-        var texts = 5
-        var invalidateOuter: (() -> Unit)? = null
-        var invalidateInner: (() -> Unit)? = null
-
-        fun MockViewComposition.composition() {
-            linear {
-                join(1106) { outerInvalidate ->
-                    invalidateOuter = { outerInvalidate(false) }
-                    for (i in 1..texts) {
-                        text("Some text")
-                    }
-
-                    skip(1114) {
-                        join(1116) { innerInvalidate ->
-                            text("Some text")
-
-                            // Force the invalidation to survive the compose
-                            innerInvalidate(false)
-                            invalidateInner = { innerInvalidate(false) }
-                        }
-                    }
-                }
-            }
-        }
-
-        val composer = compose { composition() }
-
-        texts = 4
-        invalidateOuter?.invoke()
-        invalidateInner?.invoke()
-        composer.recompose()
-        composer.applyChanges()
-
-        texts = 3
-        invalidateOuter?.invoke()
-        composer.recompose()
-        composer.applyChanges()
-    }
-
-    fun testLifecycle_Enter_Simple() {
-        val lifecycleObject = object : CompositionLifecycleObserver {
-            var count = 0
-            override fun onEnter() {
-                count++
-            }
-
-            override fun onLeave() {
-                count--
-            }
-        }
-
-        fun MockViewComposition.composition() {
-            linear {
-                remember { lifecycleObject }
-                text("Some text")
-            }
-        }
-
-        fun MockViewValidator.composition() {
-            linear {
-                text("Some text")
-            }
-        }
-
-        val composer = compose { composition() }
-        validate(composer.root) { composition() }
-
-        assertEquals("object should have been notified of an enter", 1, lifecycleObject.count)
-
-        compose(composer, expectChanges = false) {
-            composition()
-        }
-        validate(composer.root) { composition() }
-
-        assertEquals("Object should have only been notified once", 1, lifecycleObject.count)
-    }
-
-    fun testLifecycle_Enter_SingleNotification() {
-        val lifecycleObject = object : CompositionLifecycleObserver {
-            var count = 0
-            override fun onEnter() {
-                count++
-            }
-
-            override fun onLeave() {
-                count--
-            }
-        }
-
-        fun MockViewComposition.composition() {
-            linear {
-                val l = remember { lifecycleObject }
-                assertEquals("Lifecycle object should be returned", lifecycleObject, l)
-                text("Some text")
-            }
-            linear {
-                val l = remember { lifecycleObject }
-                assertEquals("Lifecycle object should be returned", lifecycleObject, l)
-                text("Some other text")
-            }
-        }
-
-        fun MockViewValidator.composition() {
-            linear {
-                text("Some text")
-            }
-            linear {
-                text("Some other text")
-            }
-        }
-
-        val composer = compose { composition() }
-        validate(composer.root) { composition() }
-
-        assertEquals("object should have been notified of an enter", 1, lifecycleObject.count)
-
-        compose(composer, expectChanges = false) {
-            composition()
-        }
-        validate(composer.root) { composition() }
-
-        assertEquals("Object should have only been notified once", 1, lifecycleObject.count)
-    }
-
-    fun testLifecycle_Leave_Simple() {
-        val lifecycleObject = object : CompositionLifecycleObserver {
-            var count = 0
-            override fun onEnter() {
-                count++
-            }
-
-            override fun onLeave() {
-                count--
-            }
-        }
-
-        fun MockViewComposition.composition(includeLifecycleObject: Boolean) {
-            linear {
-                if (includeLifecycleObject) {
-                    linear {
-                        val l = remember { lifecycleObject }
-                        assertEquals("Lifecycle object should be returned", lifecycleObject, l)
-                        text("Some text")
-                    }
-                }
-            }
-        }
-
-        fun MockViewValidator.composition(includeLifecycleObject: Boolean) {
-            linear {
-                if (includeLifecycleObject) {
-                    linear {
-                        text("Some text")
-                    }
-                }
-            }
-        }
-
-        val composer = compose { composition(true) }
-        validate(composer.root) { composition(true) }
-
-        assertEquals("object should have been notified of an enter", 1, lifecycleObject.count)
-
-        compose(composer, expectChanges = false) {
-            composition(true)
-        }
-        validate(composer.root) { composition(true) }
-
-        assertEquals("Object should have only been notified once", 1, lifecycleObject.count)
-
-        compose(composer, expectChanges = true) {
-            composition(false)
-        }
-        validate(composer.root) { composition(false) }
-
-        assertEquals("Object should have been notified of a leave", 0, lifecycleObject.count)
-    }
-
-    fun testLifecycle_Leave_NoLeaveOnReenter() {
-        var expectedEnter = true
-        var expectedLeave = true
-        val lifecycleObject = object : CompositionLifecycleObserver {
-            var count = 0
-            override fun onEnter() {
-                count++
-                assertTrue("No enter expected", expectedEnter)
-            }
-
-            override fun onLeave() {
-                count--
-                assertTrue("No leave expected", expectedLeave)
-            }
-        }
-
-        fun MockViewComposition.composition(a: Boolean, b: Boolean, c: Boolean) {
-            linear {
-                if (a) {
-                    linear(1) {
-                        val l = remember { lifecycleObject }
-                        assertEquals("Lifecycle object should be returned", lifecycleObject, l)
-                        text("a")
-                    }
-                }
-                if (b) {
-                    linear(2) {
-                        val l = remember { lifecycleObject }
-                        assertEquals("Lifecycle object should be returned", lifecycleObject, l)
-                        text("b")
-                    }
-                }
-                if (c) {
-                    linear(3) {
-                        val l = remember { lifecycleObject }
-                        assertEquals("Lifecycle object should be returned", lifecycleObject, l)
-                        text("c")
-                    }
-                }
-            }
-        }
-
-        fun MockViewValidator.composition(a: Boolean, b: Boolean, c: Boolean) {
-            linear {
-                if (a) {
-                    linear {
-                        text("a")
-                    }
-                }
-                if (b) {
-                    linear {
-                        text("b")
-                    }
-                }
-                if (c) {
-                    linear {
-                        text("c")
-                    }
-                }
-            }
-        }
-
-        expectedEnter = true
-        expectedLeave = false
-        val composer = compose { composition(a = true, b = false, c = false) }
-        validate(composer.root) {
-            composition(
-                a = true,
-                b = false,
-                c = false
-            )
-        }
-
-        assertEquals(
-            "object should have been notified of an enter",
-            1,
-            lifecycleObject.count
-        )
-
-        expectedEnter = false
-        expectedLeave = false
-        compose(composer, expectChanges = false) {
-            composition(a = true, b = false, c = false)
-        }
-        validate(composer.root) {
-            composition(
-                a = true,
-                b = false,
-                c = false
-            )
-        }
-        assertEquals(
-            "Object should have only been notified once",
-            1,
-            lifecycleObject.count
-        )
-
-        expectedEnter = false
-        expectedLeave = false
-        compose(composer, expectChanges = true) {
-            composition(a = false, b = true, c = false)
-        }
-        validate(composer.root) {
-            composition(
-                a = false,
-                b = true,
-                c = false
-            )
-        }
-        assertEquals("No enter or leaves", 1, lifecycleObject.count)
-
-        expectedEnter = false
-        expectedLeave = false
-        compose(composer, expectChanges = true) {
-            composition(a = false, b = false, c = true)
-        }
-        validate(composer.root) {
-            composition(
-                a = false,
-                b = false,
-                c = true
-            )
-        }
-        assertEquals("No enter or leaves", 1, lifecycleObject.count)
-
-        expectedEnter = false
-        expectedLeave = false
-        compose(composer, expectChanges = true) {
-            composition(a = true, b = false, c = false)
-        }
-        validate(composer.root) {
-            composition(
-                a = true,
-                b = false,
-                c = false
-            )
-        }
-        assertEquals("No enter or leaves", 1, lifecycleObject.count)
-
-        expectedEnter = false
-        expectedLeave = true
-        compose(composer, expectChanges = true) {
-            composition(a = false, b = false, c = false)
-        }
-        validate(composer.root) {
-            composition(
-                a = false,
-                b = false,
-                c = false
-            )
-        }
-        assertEquals("A leave", 0, lifecycleObject.count)
-    }
-
-    fun testLifecycle_Leave_LeaveOnReplace() {
-        val lifecycleObject1 = object : CompositionLifecycleObserver {
-            var count = 0
-            override fun onEnter() {
-                count++
-            }
-
-            override fun onLeave() {
-                count--
-            }
-        }
-
-        val lifecycleObject2 = object : CompositionLifecycleObserver {
-            var count = 0
-            override fun onEnter() {
-                count++
-            }
-
-            override fun onLeave() {
-                count--
-            }
-        }
-
-        fun MockViewComposition.composition(obj: Any) {
-            linear {
-                linear(1) {
-                    remember(obj) { obj }
-                    text("Some value")
-                }
-            }
-        }
-
-        fun MockViewValidator.composition() {
-            linear {
-                linear {
-                    text("Some value")
-                }
-            }
-        }
-
-        val composer = compose { composition(obj = lifecycleObject1) }
-        validate(composer.root) { composition() }
-        assertEquals("first object should enter", 1, lifecycleObject1.count)
-        assertEquals("second object should not have entered", 0, lifecycleObject2.count)
-
-        compose(composer, expectChanges = true) {
-            composition(lifecycleObject2)
-        }
-        validate(composer.root) { composition() }
-        assertEquals("first object should have left", 0, lifecycleObject1.count)
-        assertEquals("second object should have entered", 1, lifecycleObject2.count)
-
-        compose(composer, expectChanges = true) {
-            composition(object {})
-        }
-        validate(composer.root) { composition() }
-        assertEquals("first object should have left", 0, lifecycleObject1.count)
-        assertEquals("second object should have left", 0, lifecycleObject2.count)
-    }
-
-    fun testLifecycle_EnterLeaveOrder() {
-        var order = 0
-        val objects = mutableListOf<Any>()
-        val newLifecycleObject = { name: String ->
-            object : CompositionLifecycleObserver, Counted,
-                Ordered, Named {
-                override var name = name
-                override var count = 0
-                override var enterOrder = -1
-                override var leaveOrder = -1
-                override fun onEnter() {
-                    assertEquals("Only one call to onEnter expected", -1, enterOrder)
-                    enterOrder = order++
-                    count++
-                }
-
-                override fun onLeave() {
-                    assertEquals("Only one call to onLeave expected", -1, leaveOrder)
-                    leaveOrder = order++
-                    count--
-                }
-            }.also { objects.add(it) }
-        }
-
-        fun MockViewComposition.lifecycleUser(name: String) {
-            linear {
-                remember(name) { newLifecycleObject(name) }
-                text(value = name)
-            }
-        }
-
-        /*
-        A
-        |- B
-        |  |- C
-        |  |- D
-        |- E
-        |- F
-        |  |- G
-        |  |- H
-        |     |-I
-        |- J
-
-        Should enter as: A, B, C, D, E, F, G, H, I, J
-        Should leave as: J, I, H, G, F, E, D, C, B, A
-        */
-
-        fun MockViewComposition.tree() {
-            linear {
-                lifecycleUser("A")
-                linear {
-                    lifecycleUser("B")
-                    linear {
-                        lifecycleUser("C")
-                        lifecycleUser("D")
-                    }
-                    lifecycleUser("E")
-                    lifecycleUser("F")
-                    linear {
-                        lifecycleUser("G")
-                        lifecycleUser("H")
-                        linear {
-                            lifecycleUser("I")
-                        }
-                    }
-                    lifecycleUser("J")
-                }
-            }
-        }
-
-        fun MockViewComposition.composition(includeTree: Boolean) {
-            linear {
-                if (includeTree) tree()
-            }
-        }
-
-        val composer = compose { composition(true) }
-
-        assertTrue(
-            "All object should have entered",
-            objects.mapNotNull { it as? Counted }.map { it.count == 1 }.all { it })
-
-        compose(composer) {
-            composition(false)
-        }
-
-        assertTrue(
-            "All object should have left",
-            objects.mapNotNull { it as? Counted }.map { it.count == 0 }.all { it })
-
-        assertArrayEquals(
-            "Expected enter order",
-            arrayOf("A", "B", "C", "D", "E", "F", "G", "H", "I", "J"),
-            objects.mapNotNull { it as? Ordered }.sortedBy { it.enterOrder }.map {
-                (it as Named).name
-            }.toTypedArray()
-        )
-
-        assertArrayEquals(
-            "Expected leave order",
-            arrayOf("J", "I", "H", "G", "F", "E", "D", "C", "B", "A"),
-            objects.mapNotNull { it as? Ordered }.sortedBy { it.leaveOrder }.map {
-                (it as Named).name
-            }.toTypedArray()
-        )
-    }
-}
-
-private fun <T> assertArrayEquals(message: String, expected: Array<T>, received: Array<T>) {
-    fun Array<T>.getString() = this.joinToString(", ") { it.toString() }
-    fun err(msg: String): Nothing = error("$message: $msg, expected: [${
-    expected.getString()}], received: [${received.getString()}]")
-    if (expected.size != received.size) err("sizes are different")
-    expected.indices.forEach { index ->
-        if (expected[index] != received[index])
-            err("item at index $index was different (expected [${
-            expected[index]}], received: [${received[index]}]")
-    }
-}
-
-private fun compose(
-    composer: MockViewComposer? = null,
-    expectChanges: Boolean = true,
-    block: Compose
-): MockViewComposer {
-    val myComposer = composer ?: run {
-        val root = View().apply { name = "root" }
-        MockViewComposer(root)
-    }
-
-    myComposer.compose {
-        block()
-    }
-    if (expectChanges) {
-        Assert.assertNotEquals("changes were expected", 0, myComposer.changeCount)
-        myComposer.applyChanges()
-    } else {
-        Assert.assertEquals("no changes were expected", 0, myComposer.changeCount)
-    }
-
-    return myComposer
-}
-
-private fun compose(
-    model: ContactModel,
-    composer: MockViewComposer? = null,
-    expectChanges: Boolean = true
-): MockViewComposer =
-    compose(composer = composer, expectChanges = expectChanges) {
-        selectContact(model)
-    }
-
-// Contact test data
-private val bob = Contact("Bob Smith", email = "bob@smith.com")
-private val jon = Contact(name = "Jon Alberton", email = "jon@alberton.com")
-private val steve = Contact("Steve Roberson", email = "steverob@somemail.com")
-
-private fun testModel(
-    contacts: MutableList<Contact> = mutableListOf(
-        bob,
-        jon,
-        steve
-    )
-) = ContactModel(filter = "", contacts = contacts)
-
-// Report test data
-private val jim_reports_to_sally = Report("Jim", "Sally")
-private val rob_reports_to_alice = Report("Rob", "Alice")
-private val clark_reports_to_lois = Report("Clark", "Lois")
-
-private interface Counted {
-    val count: Int
-}
-
-private interface Ordered {
-    val enterOrder: Int
-    val leaveOrder: Int
-}
-
-private interface Named {
-    val name: String
-}
diff --git a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/EffectsTests.kt b/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/EffectsTests.kt
deleted file mode 100644
index a8c89711..0000000
--- a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/EffectsTests.kt
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * Copyright 2019 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
-
-import android.app.Activity
-import android.view.ViewGroup
-import android.widget.Button
-import android.widget.TextView
-import androidx.test.annotation.UiThreadTest
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import androidx.test.rule.ActivityTestRule
-import junit.framework.TestCase.assertEquals
-import junit.framework.TestCase.assertFalse
-import junit.framework.TestCase.assertTrue
-import org.junit.Ignore
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class EffectsTests {
-
-    @get:Rule
-    val activityRule = ActivityTestRule(TestActivity::class.java)
-
-    @Test
-    @UiThreadTest
-    fun testMemoization1() {
-        var inc = 0
-
-        compose {
-            +memo { ++inc }
-        }.then { _ ->
-            assertEquals(1, inc)
-        }.then { _ ->
-            assertEquals(1, inc)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testMemoization2() {
-        var calculations = 0
-        var compositions = 0
-        var calculation = 0
-        var key = 0
-
-        compose {
-            compositions++
-            calculation = +memo(key) { 100 * ++calculations }
-        }.then { _ ->
-            assertEquals(1, calculations)
-            assertEquals(100, calculation)
-            assertEquals(1, compositions)
-        }.then { _ ->
-            assertEquals(1, calculations)
-            assertEquals(100, calculation)
-            assertEquals(2, compositions)
-            key++
-        }.then { _ ->
-            assertEquals(2, calculations)
-            assertEquals(200, calculation)
-            assertEquals(3, compositions)
-        }.then { _ ->
-            assertEquals(2, calculations)
-            assertEquals(200, calculation)
-            assertEquals(4, compositions)
-            key++
-        }.then { _ ->
-            assertEquals(3, calculations)
-            assertEquals(300, calculation)
-            assertEquals(5, compositions)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testState1() {
-        val tv1Id = 100
-        var inc = 0
-        var local = State("invalid")
-
-        compose {
-            local = +state { "Hello world! ${inc++}" }
-            composer.emit(
-                168,
-                { context -> TextView(context).apply { id = tv1Id } },
-                { set(local.value) { text = it } }
-            )
-        }.then { activity ->
-            val helloText = activity.findViewById(tv1Id) as TextView
-            assertEquals("Hello world! 0", helloText.text)
-            assertEquals(local.value, helloText.text)
-        }.then { activity ->
-            val helloText = activity.findViewById(tv1Id) as TextView
-            assertEquals("Hello world! 0", helloText.text)
-            assertEquals(local.value, helloText.text)
-
-            local.value = "New string"
-        }.then { activity ->
-            val helloText = activity.findViewById(tv1Id) as TextView
-            assertEquals("New string", helloText.text)
-            assertEquals(local.value, helloText.text)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testState2() {
-        val tv1Id = 100
-        val tv2Id = 200
-        var local1 = State("invalid")
-        var local2 = State("invalid")
-
-        compose {
-            local1 = +state { "First" }
-            local2 = +state { "Second" }
-            composer.emit(
-                168,
-                { context -> TextView(context).apply { id = tv1Id } },
-                { set(local1.value) { text = it } }
-            )
-            composer.emit(
-                169,
-                { context -> TextView(context).apply { id = tv2Id } },
-                { set(local2.value) { text = it } }
-            )
-        }.then { activity ->
-            val tv1 = activity.findViewById(tv1Id) as TextView
-            val tv2 = activity.findViewById(tv2Id) as TextView
-            assertEquals("First", tv1.text)
-            assertEquals("Second", tv2.text)
-            assertEquals(local1.value, tv1.text)
-            assertEquals(local2.value, tv2.text)
-        }.then { activity ->
-            val tv1 = activity.findViewById(tv1Id) as TextView
-            val tv2 = activity.findViewById(tv2Id) as TextView
-            assertEquals("First", tv1.text)
-            assertEquals("Second", tv2.text)
-            assertEquals(local1.value, tv1.text)
-            assertEquals(local2.value, tv2.text)
-
-            local1.value = "New First"
-        }.then { activity ->
-            val tv1 = activity.findViewById(tv1Id) as TextView
-            val tv2 = activity.findViewById(tv2Id) as TextView
-            assertEquals("New First", tv1.text)
-            assertEquals("Second", tv2.text)
-            assertEquals(local1.value, tv1.text)
-            assertEquals(local2.value, tv2.text)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testPreCommit1() {
-        var mount = true
-
-        val logHistory = mutableListOf<String>()
-        fun log(x: String) = logHistory.add(x)
-
-        @Composable
-        fun Unmountable() {
-            log("Unmountable:start")
-            +onPreCommit {
-                log("onPreCommit")
-                onDispose {
-                    log("onDispose")
-                }
-            }
-            log("Unmountable:end")
-        }
-
-        compose {
-            with(composer) {
-                log("compose:start")
-                if (mount) {
-                    call(
-                        168,
-                        { true },
-                        { @Suppress("PLUGIN_ERROR") Unmountable() }
-                    )
-                }
-                log("compose:end")
-            }
-        }.then { _ ->
-            assertArrayEquals(
-                listOf(
-                    "compose:start",
-                    "Unmountable:start",
-                    "Unmountable:end",
-                    "compose:end",
-                    "onPreCommit"
-                ),
-                logHistory
-            )
-            mount = false
-        }.then { _ ->
-            assertArrayEquals(
-                listOf(
-                    "compose:start",
-                    "Unmountable:start",
-                    "Unmountable:end",
-                    "compose:end",
-                    "onPreCommit",
-                    "compose:start",
-                    "compose:end",
-                    "onDispose"
-                ),
-                logHistory
-            )
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testPreCommit2() {
-        var mount = true
-
-        val logHistory = mutableListOf<String>()
-        fun log(x: String) = logHistory.add(x)
-
-        @Composable
-        fun Unmountable() {
-            +onPreCommit {
-                log("onPreCommit:a2")
-                onDispose {
-                    log("onDispose:a2")
-                }
-            }
-            +onPreCommit {
-                log("onPreCommit:b2")
-                onDispose {
-                    log("onDispose:b2")
-                }
-            }
-        }
-
-        compose {
-            +onPreCommit {
-                log("onPreCommit:a1")
-                onDispose {
-                    log("onDispose:a1")
-                }
-            }
-            if (mount) {
-                composer.call(
-                    168,
-                    { true },
-                    { @Suppress("PLUGIN_ERROR") Unmountable() }
-                )
-            }
-            +onPreCommit {
-                log("onPreCommit:b1")
-                onDispose {
-                    log("onDispose:b1")
-                }
-            }
-        }.then { _ ->
-            assertArrayEquals(
-                listOf(
-                    "onPreCommit:a1",
-                    "onPreCommit:a2",
-                    "onPreCommit:b2",
-                    "onPreCommit:b1"
-                ),
-                logHistory
-            )
-            mount = false
-            log("recompose")
-        }.then { _ ->
-            assertArrayEquals(
-                listOf(
-                    "onPreCommit:a1",
-                    "onPreCommit:a2",
-                    "onPreCommit:b2",
-                    "onPreCommit:b1",
-                    "recompose",
-                    "onDispose:b2",
-                    "onDispose:a2",
-                    "onDispose:b1",
-                    "onDispose:a1",
-                    "onPreCommit:a1",
-                    "onPreCommit:b1"
-                ),
-                logHistory
-            )
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testPreCommit3() {
-        var x = 0
-
-        val logHistory = mutableListOf<String>()
-        fun log(x: String) = logHistory.add(x)
-
-        compose {
-            +onPreCommit {
-                val y = x++
-                log("onPreCommit:$y")
-                onDispose {
-                    log("dispose:$y")
-                }
-            }
-        }.then { _ ->
-            log("recompose")
-        }.then { _ ->
-            assertArrayEquals(
-                listOf(
-                    "onPreCommit:0",
-                    "recompose",
-                    "dispose:0",
-                    "onPreCommit:1"
-                ),
-                logHistory
-            )
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testPreCommit31() {
-        var a = 0
-        var b = 0
-
-        val logHistory = mutableListOf<String>()
-        fun log(x: String) = logHistory.add(x)
-
-        compose {
-            +onPreCommit {
-                val y = a++
-                log("onPreCommit a:$y")
-                onDispose {
-                    log("dispose a:$y")
-                }
-            }
-            +onPreCommit {
-                val y = b++
-                log("onPreCommit b:$y")
-                onDispose {
-                    log("dispose b:$y")
-                }
-            }
-        }.then { _ ->
-            log("recompose")
-        }.then { _ ->
-            assertArrayEquals(
-                listOf(
-                    "onPreCommit a:0",
-                    "onPreCommit b:0",
-                    "recompose",
-                    "dispose b:0",
-                    "dispose a:0",
-                    "onPreCommit a:1",
-                    "onPreCommit b:1"
-                ),
-                logHistory
-            )
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testPreCommit4() {
-        var x = 0
-        var key = 123
-
-        val logHistory = mutableListOf<String>()
-        fun log(x: String) = logHistory.add(x)
-
-        compose {
-            +onPreCommit(key) {
-                val y = x++
-                log("onPreCommit:$y")
-                onDispose {
-                    log("dispose:$y")
-                }
-            }
-        }.then { _ ->
-            log("recompose")
-        }.then { _ ->
-            assertArrayEquals(
-                listOf(
-                    "onPreCommit:0",
-                    "recompose"
-                ),
-                logHistory
-            )
-            log("recompose (key -> 345)")
-            key = 345
-        }.then { _ ->
-            assertArrayEquals(
-                listOf(
-                    "onPreCommit:0",
-                    "recompose",
-                    "recompose (key -> 345)",
-                    "dispose:0",
-                    "onPreCommit:1"
-                ),
-                logHistory
-            )
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testPreCommit5() {
-        var a = 0
-        var b = 0
-        var c = 0
-
-        val logHistory = mutableListOf<String>()
-        fun log(x: String) = logHistory.add(x)
-
-        @Composable
-        fun Sub() {
-            +onPreCommit {
-                val y = c++
-                log("onPreCommit c:$y")
-                onDispose {
-                    log("dispose c:$y")
-                }
-            }
-        }
-
-        compose {
-            +onPreCommit {
-                val y = a++
-                log("onPreCommit a:$y")
-                onDispose {
-                    log("dispose a:$y")
-                }
-            }
-
-            +onPreCommit {
-                val y = b++
-                log("onPreCommit b:$y")
-                onDispose {
-                    log("dispose b:$y")
-                }
-            }
-
-            composer.call(
-                1234,
-                { true },
-                { @Suppress("PLUGIN_ERROR") Sub() }
-            )
-        }.then { _ ->
-            log("recompose")
-        }.then { _ ->
-            assertArrayEquals(
-                listOf(
-                    "onPreCommit a:0",
-                    "onPreCommit b:0",
-                    "onPreCommit c:0",
-                    "recompose",
-                    "dispose c:0",
-                    "dispose b:0",
-                    "dispose a:0",
-                    "onPreCommit a:1",
-                    "onPreCommit b:1",
-                    "onPreCommit c:1"
-                ),
-                logHistory
-            )
-        }
-    }
-
-    @Test
-    @Ignore("TODO(b/138720405): Investigate synchronisation issues in tests")
-    fun testOnCommit1() {
-        var mount = true
-
-        val logHistory = mutableListOf<String>()
-        fun log(x: String) = logHistory.add(x)
-
-        @Composable
-        fun Unmountable() {
-            log("Unmountable:start")
-            +onCommit {
-                log("onCommit 1")
-                onDispose {
-                    log("onDispose 1")
-                }
-            }
-            +onPreCommit {
-                log("onPreCommit 2")
-                onDispose {
-                    log("onDispose 2")
-                }
-            }
-            +onCommit {
-                log("onCommit 3")
-                onDispose {
-                    log("onDispose 3")
-                }
-            }
-            log("Unmountable:end")
-        }
-
-        compose {
-            with(composer) {
-                log("compose:start")
-                if (mount) {
-                    call(
-                        168,
-                        { true },
-                        { @Suppress("PLUGIN_ERROR") Unmountable() }
-                    )
-                }
-                log("compose:end")
-            }
-        }.then { _ ->
-            assertArrayEquals(
-                listOf(
-                    "compose:start",
-                    "Unmountable:start",
-                    "Unmountable:end",
-                    "compose:end",
-                    "onPreCommit 2",
-                    "onCommit 1",
-                    "onCommit 3"
-                ),
-                logHistory
-            )
-            mount = false
-        }.then { _ ->
-            assertArrayEquals(
-                listOf(
-                    "compose:start",
-                    "Unmountable:start",
-                    "Unmountable:end",
-                    "compose:end",
-                    "onPreCommit 2",
-                    "onCommit 1",
-                    "onCommit 3",
-                    "compose:start",
-                    "compose:end",
-                    "onDispose 3",
-                    "onDispose 2",
-                    "onDispose 1"
-                ),
-                logHistory
-            )
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testAmbient1() {
-        val tv1Id = 100
-
-        val Foo = Ambient.of<String>()
-        var current = "Hello World"
-
-        @Composable
-        fun Bar() {
-            composer.call(
-                21323,
-                { true },
-                {
-                    @Suppress("PLUGIN_ERROR")
-                    (Observe {
-                        val foo = +ambient(Foo)
-                        composer.emit(
-                            168,
-                            { context -> TextView(context).apply { id = tv1Id } },
-                            { set(foo) { text = it } }
-                        )
-                    })
-                }
-            )
-        }
-
-        compose {
-            with(composer) {
-                provideAmbient(Foo, current) {
-                    call(
-                        123,
-                        { false },
-                        { @Suppress("PLUGIN_ERROR") Bar() }
-                    )
-                }
-            }
-        }.then { activity ->
-            val helloText = activity.findViewById(tv1Id) as TextView
-            assertEquals(current, helloText.text)
-            current = "abcd"
-        }.then { activity ->
-            val helloText = activity.findViewById(tv1Id) as TextView
-            assertEquals(current, helloText.text)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testAmbient2() {
-
-        val MyAmbient = Ambient.of<Double>("Hello") { throw Exception("not set") }
-
-        var requestRecompose: (() -> Unit)? = null
-        var buttonCreated = false
-
-        fun SimpleComposable2() {
-            Observe {
-                with(composer) {
-                    val value = +ambient(MyAmbient)
-                    emit(534, { context -> TextView(context) }, {
-                        set("$value") { text = it }
-                    })
-                }
-            }
-        }
-
-        fun SimpleComposable() {
-            composer.call(531, { true }) {
-                Recompose(
-                    body = { recompose ->
-                        requestRecompose = recompose
-                        composer.provideAmbient(MyAmbient, Math.random()) {
-                            composer.call(523, { false }) { SimpleComposable2() }
-                            composer.emitView(525, { context ->
-                                Button(context).also {
-                                    buttonCreated = true
-                                }
-                            })
-                        }
-                    }
-                )
-            }
-        }
-
-        fun Root() {
-            with(composer) {
-                call(547, { false }) {
-                    SimpleComposable()
-                }
-            }
-        }
-
-        compose {
-            with(composer) {
-                call(556, { false }) {
-                    Root()
-                }
-            }
-        }.then {
-            assertTrue("Expected button to be created", buttonCreated)
-            buttonCreated = false
-            requestRecompose?.invoke()
-        }.then {
-            assertFalse("Expected button to not be recreated", buttonCreated)
-            requestRecompose?.invoke()
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testUpdatedComposition() {
-        val tv1Id = 100
-        var inc = 0
-
-        compose {
-            val local = +state { "Hello world! ${inc++}" }
-            composer.emit(
-                168,
-                { context -> TextView(context).apply { id = tv1Id } },
-                { set(local.value) { text = it } }
-            )
-        }.then { activity ->
-            val helloText = activity.findViewById(tv1Id) as TextView
-            assertEquals("Hello world! 0", helloText.text)
-        }.then { activity ->
-            val helloText = activity.findViewById(tv1Id) as TextView
-            assertEquals("Hello world! 0", helloText.text)
-        }
-    }
-
-    class CompositionTest(val composable: () -> Unit, val activity: Activity) {
-
-        inner class ActiveTest(
-            val activity: Activity,
-            val cc: CompositionContext,
-            val component: Component
-        ) {
-
-            fun then(block: (activity: Activity) -> Unit): ActiveTest {
-                cc.composer.runWithCurrent {
-                    cc.compose()
-                }
-                block(activity)
-                return this
-            }
-        }
-
-        private class Root(var composable: () -> Unit) : Component() {
-            override fun compose() = composable()
-        }
-
-        fun then(block: (activity: Activity) -> Unit): ActiveTest {
-            val root = activity.root
-            val component = Root(composable)
-            val cc = Compose.createCompositionContext(root.context, root, component, null)
-            return ActiveTest(activity, cc, component).then(block)
-        }
-    }
-
-    fun compose(composable: () -> Unit) = CompositionTest(composable, activityRule.activity)
-}
-
-private val Activity.root get() = findViewById(ComposerComposeTestCase.ROOT_ID) as ViewGroup
-
-fun <T> assertArrayEquals(
-    expected: Collection<T>,
-    actual: Collection<T>,
-    transform: (T) -> String = { "$it" }
-) {
-    assertEquals(
-        expected.joinToString("\n", transform = transform),
-        actual.joinToString("\n", transform = transform)
-    )
-}
\ No newline at end of file
diff --git a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ObserverMapTests.kt b/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ObserverMapTests.kt
deleted file mode 100644
index 7c6cf81..0000000
--- a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ObserverMapTests.kt
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright 2019 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
-
-import androidx.test.filters.SmallTest
-import org.junit.Assert.assertEquals
-import org.junit.Before
-import org.junit.Test
-
-@SmallTest
-class ObserverMapTests {
-
-    private val node1 = 1
-    private val node2 = 2
-    private lateinit var map: ObserverMap<TestModel, Int>
-
-    @Before
-    fun setup() {
-        map = ObserverMap()
-    }
-
-    @Test
-    fun testMapContainsPreviouslyAddedModel() {
-        val model = TestModel()
-        map.add(model, node1)
-
-        map.assertNodes(model, node1)
-    }
-
-    @Test
-    fun testMapAssociateBothNodesWithTheModel() {
-        val model = TestModel()
-        map.add(model, node1)
-        map.add(model, node2)
-
-        map.assertNodes(model, node1, node2)
-    }
-
-    @Test
-    fun testMapContainsModelWithChangedHashCode() {
-        val model = TestModel("Original")
-        map.add(model, node1)
-        model.content = "Changed"
-
-        map.assertNodes(model, node1)
-    }
-
-    @Test
-    fun testMapRemovesTheModel() {
-        val model = TestModel()
-        map.add(model, node1)
-        map.add(model, node2)
-
-        map.remove(model)
-
-        map.assertNodes(model)
-    }
-
-    @Test
-    fun testMapRemovesTheNode() {
-        val model = TestModel()
-        map.add(model, node1)
-        map.add(model, node2)
-
-        map.remove(model, node1)
-
-        map.assertNodes(model, node2)
-    }
-
-    @Test
-    fun testMapClearsAllTheModels() {
-        val model1 = TestModel("Test1")
-        val model2 = TestModel("Test2")
-        map.add(model1, node1)
-        map.add(model2, node2)
-
-        map.clear()
-
-        map.assertNodes(model1)
-        map.assertNodes(model2)
-    }
-
-    @Test
-    fun testMapClearsTheValuesByPredicate() {
-        val model1 = TestModel("Test1")
-        val model2 = TestModel("Test2")
-        val node3 = 3
-        map.add(model1, node1)
-        map.add(model2, node2)
-        map.add(model2, node3)
-
-        map.clearValues { it == node1 || it == node3 }
-
-        map.assertNodes(model1)
-        map.assertNodes(model2, node2)
-    }
-
-    @Test
-    fun testGetForMultipleModels() {
-        val model1 = TestModel("Test1")
-        val model2 = TestModel("Test2")
-        val model3 = TestModel("Test2")
-        val node3 = 3
-        val node4 = 4
-        map.add(model1, node1)
-        map.add(model1, node2)
-        map.add(model2, node3)
-        map.add(model3, node4)
-
-        map.assertNodes(listOf(model1, model2, model3), node1, node2, node3, node4)
-    }
-
-    @Test
-    fun testGetFiltersDuplicates() {
-        val model1 = TestModel("Test1")
-        val model2 = TestModel("Test2")
-        map.add(model1, node1)
-        map.add(model2, node1)
-
-        map.assertNodes(listOf(model1, model2), node1)
-    }
-
-    private data class TestModel(var content: String = "Test")
-
-    private fun ObserverMap<TestModel, Int>.assertNodes(
-        model: TestModel,
-        vararg nodes: Int
-    ) {
-        assertNodes(listOf(model), *nodes)
-    }
-
-    private fun ObserverMap<TestModel, Int>.assertNodes(
-        models: List<TestModel>,
-        vararg nodes: Int
-    ) {
-        val expected = nodes.toList().sorted()
-        val actual = get(models).sorted()
-        assertEquals(expected, actual)
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/RecomposerTests.kt b/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/RecomposerTests.kt
deleted file mode 100644
index b19ebed..0000000
--- a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/RecomposerTests.kt
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- * Copyright 2019 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
-
-import android.view.View
-import android.view.ViewGroup
-import android.widget.LinearLayout
-import android.widget.TextView
-import androidx.compose.frames.currentFrame
-import androidx.test.annotation.UiThreadTest
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.MediumTest
-import androidx.test.filters.SmallTest
-import androidx.test.rule.ActivityTestRule
-import junit.framework.TestCase
-import junit.framework.TestCase.assertEquals
-import junit.framework.TestCase.assertFalse
-import junit.framework.TestCase.assertNotSame
-import junit.framework.TestCase.assertTrue
-import org.junit.Ignore
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-class ComposerCompositionContextTests : ComposerComposeTestCase() {
-
-    @get:Rule
-    val activityRule = ActivityTestRule(TestActivity::class.java)
-
-    private fun compose(composable: (ViewComposition) -> Unit) =
-        compose(activityRule.activity, composable)
-
-    @Test
-    @SmallTest
-    @UiThreadTest
-    fun testNativeViewWithAttributes() = compose {
-        with(it) {
-            // <TextView id={456} text="some text" />
-            emitView(123, ::TextView) {
-                set(456) { id = it }
-                set("some text") { text = it }
-            }
-        }
-    }.then { _, _, root, activity ->
-        assertEquals(1, root.childCount)
-
-        val tv = activity.findViewById(456) as TextView
-        assertEquals("some text", tv.text)
-
-        assertEquals(tv, root.getChildAt(0))
-    }
-
-    @Test
-    @SmallTest
-    @Ignore("TODO(b/138720405): Investigate synchronisation issues in tests")
-    fun testSlotKeyChangeCausesRecreate() {
-        var i = 1
-
-        compose {
-            // this should cause the textview to get recreated on every compose
-            i++
-
-            with(it) {
-                // <TextView id={456} text="some text" />
-                emitView(i, ::TextView) {
-                    set(456) { id = it }
-                    set("some text") { text = it }
-                }
-            }
-        }.then { _, component, root, activity ->
-            val tv1 = activity.findViewById(456) as TextView
-
-            component.recomposeCallback?.invoke(false)
-
-            assertEquals("Compose got called twice", 3, i)
-
-            val tv2 = activity.findViewById(456) as TextView
-
-            assertFalse(
-                "The text views should be different instances",
-                tv1 === tv2
-            )
-
-            assertEquals(
-                "The unused child got removed from the view hierarchy",
-                1,
-                root.childCount
-            )
-        }
-    }
-
-    @Test
-    @SmallTest
-    @UiThreadTest
-    fun testViewWithViewChildren() {
-        compose {
-            // <LinearLayout id={345}>
-            with(it) {
-                emitViewGroup(100, ::LinearLayout, {
-                    set(345) { id = it }
-                }) {
-                    // <TextView id={456} text="some text" />
-                    emitView(101, ::TextView) {
-                        set(456) { id = it }
-                        set("some text") { text = it }
-                    }
-                    // <TextView id={567} text="some text" />
-                    emitView(102, ::TextView) {
-                        set(567) { id = it }
-                        set("some text") { text = it }
-                    }
-                }
-            }
-        }.then { _, _, root, activity ->
-            val ll = activity.findViewById(345) as LinearLayout
-            val tv1 = activity.findViewById(456) as TextView
-            val tv2 = activity.findViewById(567) as TextView
-
-            assertEquals("The linear layout should be the only child of root", 1, root.childCount)
-            assertEquals("Both children should have gotten added", 2, ll.childCount)
-            assertTrue(
-                "Should be the expected TextView (1)",
-                ll.getChildAt(0) === tv1
-            )
-            assertTrue(
-                "Should be the expected TextView (2)",
-                ll.getChildAt(1) === tv2
-            )
-        }
-    }
-
-    @Test
-    @SmallTest
-    @UiThreadTest
-    fun testForLoop() {
-        val items = listOf(1, 2, 3, 4, 5, 6)
-        compose {
-            // this should cause the textview to get recreated on every compose
-            with(it) {
-                emitViewGroup(100, ::LinearLayout, {
-                    set(345) { id = it }
-                }) {
-                    for (i in items) {
-                        // <TextView id={456} text="some text" />
-                        emitView(101, ::TextView) {
-                            set(456) { id = it }
-                            set("some text $i") { text = it }
-                        }
-                    }
-                }
-            }
-        }.then { _, _, root, activity ->
-            val ll = activity.findViewById(345) as LinearLayout
-
-            assertEquals("The linear layout should be the only child of root", 1, root.childCount)
-            assertEquals("Each item in the for loop should be a child", items.size, ll.childCount)
-            items.forEachIndexed { index, i ->
-                assertEquals(
-                    "Should be the correct child", "some text $i",
-                    (ll.getChildAt(index) as TextView).text
-                )
-            }
-        }
-    }
-
-    @Test
-    @SmallTest
-    @UiThreadTest
-    @Ignore("TODO(b/138720405): Investigate synchronisation issues in tests")
-    fun testRecompose() {
-        val counter = Counter()
-
-        compose {
-            // <A />
-            it.emitComponent(123) {
-                RecomposeTestComponents.A(
-                    counter,
-                    RecomposeTestComponents.ClickAction.Recompose
-                )
-            }
-        }.then { _, _, _, activity ->
-            // everything got rendered once
-            assertEquals(1, counter["A"])
-            assertEquals(1, counter["100"])
-            assertEquals(1, counter["101"])
-            assertEquals(1, counter["102"])
-
-            (activity.findViewById(100) as TextView).performClick()
-            (activity.findViewById(102) as TextView).performClick()
-
-            // nothing should happen synchronously
-            assertEquals(1, counter["A"])
-            assertEquals(1, counter["100"])
-            assertEquals(1, counter["101"])
-            assertEquals(1, counter["102"])
-
-            // only the clicked view got rerendered
-            assertEquals(1, counter["A"])
-            assertEquals(2, counter["100"])
-            assertEquals(1, counter["101"])
-            assertEquals(2, counter["102"])
-
-            // recompose() both the parent and the child... and show that the child only
-            // recomposes once as a result
-            (activity.findViewById(99) as LinearLayout).performClick()
-            (activity.findViewById(102) as TextView).performClick()
-
-            assertEquals(2, counter["A"])
-            assertEquals(2, counter["100"])
-            assertEquals(1, counter["101"])
-            assertEquals(3, counter["102"])
-        }
-    }
-
-    @Test
-    @SmallTest
-    @UiThreadTest
-    fun testRecomposeSync() {
-        val counter = Counter()
-
-        compose {
-            // <A />
-            it.emitComponent(123) {
-                RecomposeTestComponents.A(
-                    counter,
-                    RecomposeTestComponents.ClickAction.RecomposeSync
-                )
-            }
-        }.then { _, _, _, activity ->
-            // everything got rendered once
-            assertEquals(1, counter["A"])
-            assertEquals(1, counter["100"])
-            assertEquals(1, counter["101"])
-            assertEquals(1, counter["102"])
-
-            (activity.findViewById(100) as TextView).performClick()
-
-            // only the clicked view got rerendered
-            assertEquals(1, counter["A"])
-            assertEquals(2, counter["100"])
-            assertEquals(1, counter["101"])
-            assertEquals(1, counter["102"])
-
-            assertEquals(1, counter["A"])
-            assertEquals(2, counter["100"])
-            assertEquals(1, counter["101"])
-            assertEquals(1, counter["102"])
-
-            // try to recompose the parent, but ensure that even if we tap textView several times,
-            // it's all got recomposed once
-            (activity.findViewById(99) as LinearLayout).performClick()
-            (activity.findViewById(100) as TextView).performClick()
-            (activity.findViewById(100) as TextView).performClick()
-            (activity.findViewById(100) as TextView).performClick()
-
-            // only the twice clicked view got rerendered twice
-            assertEquals(2, counter["A"])
-            // this should be 5, as it gets recomposed synchronously 3 times due to TV taps
-            assertEquals(5, counter["100"])
-            assertEquals(1, counter["101"])
-            assertEquals(1, counter["102"])
-        }
-    }
-
-    @Test
-    @SmallTest
-    @UiThreadTest
-    @Ignore("TODO(b/138720405): Investigate synchronisation issues in tests")
-    fun testRootRecompose() {
-        val counter = Counter()
-
-        val listener =
-            RecomposeTestComponents.ClickAction.PerformOnView {
-                Compose.findRoot(it)?.let {
-                    it.recomposeCallback?.invoke(false)
-                }
-            }
-
-        compose {
-            // <A />
-            it.emitComponent(123) {
-                RecomposeTestComponents.A(
-                    counter,
-                    listener
-                )
-            }
-        }.then { _, _, _, activity ->
-            // everything got rendered once
-            assertEquals(1, counter["A"])
-            assertEquals(1, counter["100"])
-            assertEquals(1, counter["101"])
-            assertEquals(1, counter["102"])
-
-            (activity.findViewById(100) as TextView).performClick()
-            (activity.findViewById(102) as TextView).performClick()
-
-            // nothing should happen synchronously
-            assertEquals(1, counter["A"])
-            assertEquals(1, counter["100"])
-            assertEquals(1, counter["101"])
-            assertEquals(1, counter["102"])
-
-            // as we recompose ROOT on every tap, only root(and LinearLayout) counter should we
-            // increased once, because two clicks layed to one frame
-            assertEquals(2, counter["A"])
-            assertEquals(1, counter["100"])
-            assertEquals(1, counter["101"])
-            assertEquals(1, counter["102"])
-
-            (activity.findViewById(99) as LinearLayout).performClick()
-            (activity.findViewById(102) as TextView).performClick()
-
-            // again, no matter what we tappes, we want to recompose root, so LinearLayout's counter
-            // got increased
-            assertEquals(3, counter["A"])
-            assertEquals(1, counter["100"])
-            assertEquals(1, counter["101"])
-            assertEquals(1, counter["102"])
-        }
-    }
-
-    @Test
-    @SmallTest
-    @UiThreadTest
-    fun testRootRecomposeSync() {
-        val counter = Counter()
-
-        val listener =
-            RecomposeTestComponents.ClickAction.PerformOnView {
-                Compose.findRoot(it)?.let {
-                    it.recomposeCallback?.invoke(true)
-                }
-            }
-        compose {
-            // <A />
-            it.emitComponent(123) {
-                RecomposeTestComponents.A(
-                    counter,
-                    listener
-                )
-            }
-        }.then { _, _, _, activity ->
-            // everything got rendered once
-            assertEquals(1, counter["A"])
-            assertEquals(1, counter["100"])
-            assertEquals(1, counter["101"])
-            assertEquals(1, counter["102"])
-
-            (activity.findViewById(100) as TextView).performClick()
-
-            // important! as we recompose Root every time
-            // no matter what we clicked, root (and LinearLayout) gets rerendered
-            assertEquals(2, counter["A"])
-            assertEquals(1, counter["100"])
-            assertEquals(1, counter["101"])
-            assertEquals(1, counter["102"])
-
-            (activity.findViewById(99) as LinearLayout).performClick()
-
-            assertEquals(3, counter["A"])
-            assertEquals(1, counter["100"])
-            assertEquals(1, counter["101"])
-            assertEquals(1, counter["102"])
-
-            // make sure nothing has been scheduled inside recomposeSync()
-            assertEquals(3, counter["A"])
-            assertEquals(1, counter["100"])
-            assertEquals(1, counter["101"])
-            assertEquals(1, counter["102"])
-        }
-    }
-
-    // components for testing recompose behavior above
-    private object RecomposeTestComponents {
-        sealed class ClickAction {
-            object Recompose : ClickAction()
-            object RecomposeSync : ClickAction()
-            class PerformOnView(val action: (View) -> Unit) : ClickAction()
-        }
-
-        class B(val counter: Counter, val listener: ClickAction) : Component() {
-            var id: Int = 0
-            override fun compose() {
-                counter.inc("$id")
-
-                with(composer) {
-                    // <TextView id={id} onClickListener={{ clickAction() }} />
-                    emitView(24, ::TextView) {
-                        set(id) { id = it }
-                        set(View.OnClickListener {
-                            @Suppress("DEPRECATION")
-                            when (listener) {
-                                is ClickAction.Recompose -> recompose()
-                                is ClickAction.RecomposeSync -> recomposeSync()
-                                is ClickAction.PerformOnView -> listener.action.invoke(it)
-                            }
-                        }) { setOnClickListener(it) }
-                    }
-                }
-            }
-        }
-
-        class A(val counter: Counter, val listener: ClickAction) : Component() {
-            override fun compose() {
-                counter.inc("A")
-                // <LinearLayout onClickListener={{ clickAction() }} id={99}>
-                //     <B id={100} />
-                //     <B id={101} />
-                //     <B id={102} />
-                // </LinearLayout>
-
-                with(composer) {
-
-                    // <LinearLayout id={99} onClickListener={{ clickAction() }}/>
-                    emitViewGroup(897, ::LinearLayout, {
-                        set(99) { id = it }
-                        set(View.OnClickListener {
-                            @Suppress("DEPRECATION")
-                            when (listener) {
-                                is ClickAction.Recompose -> recompose()
-                                is ClickAction.RecomposeSync -> recomposeSync()
-                                is ClickAction.PerformOnView -> listener.action.invoke(it)
-                            }
-                        }) { setOnClickListener(it) }
-                    }) {
-                        for (id in 100..102) {
-                            // <B key={id} id={id} />
-                            emitComponent(878983, id, {
-                                B(
-                                    counter,
-                                    listener
-                                )
-                            }) { f ->
-                                set(id) { f.id = it }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    @Test
-    @SmallTest
-    @UiThreadTest
-    fun testCorrectViewTree() = compose {
-        // <LinearLayout>
-        //   <LinearLayout />
-        //   <LinearLayout />
-        // </LinearLayout>
-        // <LinearLayout />
-
-        with(it) {
-            emitViewGroup(123, ::LinearLayout, {}) {
-                emitView(123, ::LinearLayout)
-                emitView(123, ::LinearLayout)
-            }
-            emitView(123, ::LinearLayout)
-        }
-    }.then { _, _, root, _ ->
-        assertChildHierarchy(root) {
-            """
-                <LinearLayout>
-                    <LinearLayout />
-                    <LinearLayout />
-                </LinearLayout>
-                <LinearLayout />
-            """
-        }
-    }
-
-    @Test
-    @SmallTest
-    @UiThreadTest
-    fun testCorrectViewTreeWithComponents() {
-
-        class B : Component() {
-            override fun compose() {
-                with(composer) {
-                    // <TextView />
-                    emitView(123, ::TextView)
-                }
-            }
-        }
-
-        compose {
-            // <LinearLayout>
-            //   <LinearLayout>
-            //     <B />
-            //   </LinearLayout>
-            //   <LinearLayout>
-            //     <B />
-            //   </LinearLayout>
-            // </LinearLayout>
-
-            with(it) {
-                emitViewGroup(123, ::LinearLayout, {}) {
-                    emitViewGroup(123, ::LinearLayout, {}) {
-                        emitComponent(123, ::B)
-                    }
-                    emitViewGroup(123, ::LinearLayout, {}) {
-                        emitComponent(123, ::B)
-                    }
-                }
-            }
-        }.then { _, _, root, _ ->
-
-            assertChildHierarchy(root) {
-                """
-                <LinearLayout>
-                    <LinearLayout>
-                        <TextView />
-                    </LinearLayout>
-                    <LinearLayout>
-                        <TextView />
-                    </LinearLayout>
-                </LinearLayout>
-                """
-            }
-        }
-    }
-
-    @Test
-    @MediumTest
-    @UiThreadTest
-    fun testCorrectViewTreeWithComponentWithMultipleRoots() {
-
-        class B : Component() {
-            override fun compose() {
-                with(composer) {
-                    // <TextView />
-                    emitView(123, ::TextView)
-                    emitView(124, ::TextView)
-                }
-            }
-        }
-
-        compose {
-            // <LinearLayout>
-            //   <LinearLayout>
-            //     <B />
-            //   </LinearLayout>
-            //   <LinearLayout>
-            //     <B />
-            //   </LinearLayout>
-            // </LinearLayout>
-
-            with(it) {
-                emitViewGroup(123, ::LinearLayout, {}) {
-                    emitViewGroup(123, ::LinearLayout, {}) {
-                        emitComponent(123, ::B)
-                    }
-                    emitViewGroup(123, ::LinearLayout, {}) {
-                        emitComponent(123, ::B)
-                    }
-                }
-            }
-        }.then { _, _, root, _ ->
-
-            assertChildHierarchy(root) {
-                """
-                <LinearLayout>
-                    <LinearLayout>
-                        <TextView />
-                        <TextView />
-                    </LinearLayout>
-                    <LinearLayout>
-                        <TextView />
-                        <TextView />
-                    </LinearLayout>
-                </LinearLayout>
-                """
-            }
-        }
-    }
-
-    @Test
-    @SmallTest
-    @UiThreadTest
-    fun testFrameTransition() {
-        var frameId: Int? = null
-        compose {
-            frameId = currentFrame().id
-        }.then { _, _, _, _ ->
-            assertNotSame(frameId, currentFrame().id)
-        }
-    }
-}
-
-fun assertChildHierarchy(root: ViewGroup, getHierarchy: () -> String) {
-    val realHierarchy = printChildHierarchy(root)
-
-    TestCase.assertEquals(
-        normalizeString(getHierarchy()),
-        realHierarchy.trim()
-    )
-}
-
-fun normalizeString(str: String): String {
-    val lines = str.split('\n').dropWhile { it.isBlank() }.dropLastWhile {
-        it.isBlank()
-    }
-    if (lines.isEmpty()) return ""
-    val toRemove = lines.first().takeWhile { it == ' ' }.length
-    return lines.joinToString("\n") { it.substring(Math.min(toRemove, it.length)) }
-}
-
-fun printChildHierarchy(root: ViewGroup): String {
-    val sb = StringBuilder()
-    for (i in 0 until root.childCount) {
-        printView(root.getChildAt(i), 0, sb)
-    }
-    return sb.toString()
-}
-
-fun printView(view: View, indent: Int, sb: StringBuilder) {
-    val whitespace = " ".repeat(indent)
-    val name = view.javaClass.simpleName
-    val attributes = printAttributes(view)
-    if (view is ViewGroup && view.childCount > 0) {
-        sb.appendln("$whitespace<$name$attributes>")
-        for (i in 0 until view.childCount) {
-            printView(view.getChildAt(i), indent + 4, sb)
-        }
-        sb.appendln("$whitespace</$name>")
-    } else {
-        sb.appendln("$whitespace<$name$attributes />")
-    }
-}
-
-fun printAttributes(view: View): String {
-    val attrs = mutableListOf<String>()
-
-    // NOTE: right now we only look for id and text as attributes to print out... but we are
-    // free to add more if it makes sense
-    if (view.id != -1) {
-        attrs.add("id=${view.id}")
-    }
-
-    if (view is TextView && view.text.length > 0) {
-        attrs.add("text='${view.text}'")
-    }
-
-    val result = attrs.joinToString(" ", prefix = " ")
-    if (result.length == 1) {
-        return ""
-    }
-    return result
-}
diff --git a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ReconciliationInternalTests.kt b/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ReconciliationInternalTests.kt
deleted file mode 100644
index 5d9ab70..0000000
--- a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ReconciliationInternalTests.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright 2019 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
diff --git a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/SlotTableTests.kt b/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/SlotTableTests.kt
deleted file mode 100644
index 8d4f8ac..0000000
--- a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/SlotTableTests.kt
+++ /dev/null
@@ -1,1085 +0,0 @@
-/*
- * Copyright 2019 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
-
-import androidx.test.filters.SmallTest
-import junit.framework.TestCase
-import org.junit.Assert
-
-@SmallTest
-class SlotTableTests : TestCase() {
-    fun testCanCreate() {
-        SlotTable()
-    }
-
-    // Raw slot tests (testing the buffer gap)
-
-    fun testCanInsert() {
-        val slots = SlotTable()
-        slots.write { writer ->
-            writer.beginInsert()
-            writer.startGroup()
-            writer.skip()
-            writer.endGroup()
-            writer.endInsert()
-        }
-    }
-
-    fun testValidateSlots() {
-        val slots = testSlotsNumbered()
-        slots.read { reader ->
-            for (i in 0 until 100) {
-                assertEquals(i, reader.next())
-            }
-        }
-    }
-
-    fun testPrevious() {
-        val slots = testSlotsNumbered()
-        slots.read { reader ->
-            for (i in 0 until 100) {
-                assertEquals(i, reader.next())
-                reader.previous()
-                assertEquals(i, reader.next())
-            }
-            for (i in 99 downTo 0) {
-                reader.previous()
-                assertEquals(i, reader.next())
-                reader.previous()
-            }
-        }
-    }
-
-    fun testInsertAtTheStart() {
-        val slots = testSlotsNumbered()
-        slots.write { writer ->
-            writer.beginInsert()
-            writer.skip()
-            writer.set(-1)
-            writer.endInsert()
-        }
-        slots.read { reader ->
-            assertEquals(-1, reader.next())
-            for (i in 0 until 100) {
-                assertEquals(i, reader.next())
-            }
-        }
-    }
-
-    fun testInsertAtTheEnd() {
-        val slots = testSlotsNumbered()
-
-        val current = slots.read { reader ->
-            for (i in 0 until 100) {
-                assertEquals(i, reader.next())
-            }
-            reader.current
-        }
-
-        slots.write { writer ->
-            writer.current = current
-            writer.beginInsert()
-            writer.skip()
-            writer.set(-1)
-            writer.endInsert()
-        }
-
-        slots.read { reader ->
-            for (i in 0 until 100) {
-                assertEquals(i, reader.next())
-            }
-            assertEquals(-1, reader.next())
-        }
-    }
-
-    fun testInsertInTheMiddle() {
-        val slots = testSlotsNumbered()
-        val current = slots.read { reader ->
-            for (i in 0 until 50) {
-                assertEquals(i, reader.next())
-            }
-            reader.current
-        }
-        slots.write { writer ->
-            writer.current = current
-            writer.beginInsert()
-            writer.skip()
-            writer.set(-1)
-            writer.endInsert()
-        }
-        slots.read { reader ->
-            for (i in 0 until 100) {
-                if (i == 50) assertEquals(-1, reader.next())
-                assertEquals(i, reader.next())
-            }
-        }
-    }
-
-    fun testRemoveAtTheStart() {
-        val slots = testSlotsNumbered()
-        slots.write { writer ->
-            writer.remove(0, 50)
-        }
-        slots.read { reader ->
-            for (i in 50 until 100)
-                assertEquals(i, reader.next())
-        }
-    }
-
-    fun testRemoveAtTheEnd() {
-        val slots = testSlotsNumbered()
-        slots.write { writer ->
-            writer.remove(50, 50)
-        }
-        slots.read { reader ->
-            for (i in 0 until 50)
-                assertEquals(i, reader.next())
-        }
-    }
-
-    fun testRemoveInTheMiddle() {
-        val slots = testSlotsNumbered()
-        slots.write { writer ->
-            writer.remove(25, 50)
-        }
-        slots.read { reader ->
-            for (i in 0 until 25)
-                assertEquals(i, reader.next())
-            for (i in 75 until 100)
-                assertEquals(i, reader.next())
-        }
-    }
-
-    fun testRemoveTwoSlicesBackToFront() {
-        val slots = testSlotsNumbered()
-        slots.write { writer ->
-            writer.remove(70, 10)
-            writer.remove(40, 10)
-        }
-        slots.read { reader ->
-            for (i in 0 until 40)
-                assertEquals(i, reader.next())
-            for (i in 50 until 70)
-                assertEquals(i, reader.next())
-            for (i in 80 until 100)
-                assertEquals(i, reader.next())
-        }
-    }
-
-    fun testRemoveTwoSlicesFrontToBack() {
-        val slots = testSlotsNumbered()
-        slots.write { writer ->
-            writer.remove(40, 10)
-            writer.remove(60, 10) // Actually deletes the 70s as they have slid down 10
-        }
-        slots.read { reader ->
-            for (i in 0 until 40)
-                assertEquals(i, reader.next())
-            for (i in 50 until 70)
-                assertEquals(i, reader.next())
-            for (i in 80 until 100)
-                assertEquals(i, reader.next())
-        }
-    }
-
-    // Anchor tests
-
-    fun testAllocateAnchors() {
-        val slots = testSlotsNumbered()
-        val anchors = slots.write { writer -> (1..7).map { writer.anchor(it * 10) } }
-        slots.read { reader ->
-            for (index in 1..7) {
-                val anchor = anchors[index - 1]
-                assertEquals(index * 10, reader.get(anchor))
-            }
-        }
-    }
-
-    fun testAnchorsTrackInserts() {
-        val slots = testSlotsNumbered()
-        val anchors = slots.write { writer -> (1..7).map { writer.anchor(it * 10) } }
-        slots.write { writer ->
-            writer.current = 40
-            writer.beginInsert()
-            repeat(50) { writer.skip() }
-            writer.endInsert()
-        }
-        slots.read { reader ->
-            for (index in 1..7) {
-                val anchor = anchors[index - 1]
-                assertEquals(index * 10, reader.get(anchor))
-            }
-        }
-    }
-
-    fun testAnchorTracksExactRemovesUpwards() {
-        val slots = testSlotsNumbered()
-        val anchors = slots.write { writer -> (1..7).map { writer.anchor(it * 10) } }
-        slots.write { writer ->
-            for (index in 1..7) {
-                writer.remove(index * 10 - (index - 1), 1)
-                assertEquals(-1, anchors[index - 1].location(slots))
-            }
-        }
-    }
-
-    fun testAnchorTracksExactRemovesDownwards() {
-        val slots = testSlotsNumbered()
-        val anchors = slots.write { writer -> (1..7).map { writer.anchor(it * 10) } }
-        slots.write { writer ->
-            for (index in 7 downTo 1) {
-                writer.remove(index * 10, 1)
-                assertEquals(-1, anchors[index - 1].location(slots))
-            }
-        }
-    }
-
-    fun testAnchorTracksExtactRemovesInnerOuter() {
-        val slots = testSlotsNumbered()
-        val expectedLocations = (1..7).map { it * 10 }.toMutableList()
-        val anchors = slots.write { writer -> expectedLocations.map { writer.anchor(it) } }
-        slots.write { writer ->
-            for (index in listOf(4, 5, 3, 6, 2, 7, 1)) {
-                val location = expectedLocations[index - 1]
-                writer.remove(location, 1)
-                assertEquals(-1, anchors[index - 1].location(slots))
-                for (i in expectedLocations.indices) {
-                    if (expectedLocations[i] > location) expectedLocations[i]--
-                }
-            }
-        }
-    }
-
-    fun testAnchorTracksExactRemovesOuterInner() {
-        val slots = testSlotsNumbered()
-        val expectedLocations = (1..7).map { it * 10 }.toMutableList()
-        val anchors = slots.write { writer -> expectedLocations.map { writer.anchor(it) } }
-        slots.write { writer ->
-            for (index in listOf(1, 7, 2, 6, 3, 5, 4)) {
-                val location = expectedLocations[index - 1]
-                writer.remove(location, 1)
-                assertEquals(-1, anchors[index - 1].location(slots))
-                for (i in expectedLocations.indices) {
-                    if (expectedLocations[i] > location) expectedLocations[i]--
-                }
-            }
-        }
-    }
-
-    fun testAnchorTrackRemoves() {
-        val slots = testSlotsNumbered()
-        val anchors = slots.write { writer -> (1..7).map { writer.anchor(it * 10) } }
-        slots.write { writer ->
-            writer.remove(40, 20)
-        }
-        slots.read { reader ->
-            for (index in 1..7) {
-                val anchor = anchors[index - 1]
-                val expected = (index * 10).let { if (it in 40 until 60) SlotTable.EMPTY else it }
-                assertEquals(expected, reader.get(anchor))
-            }
-        }
-    }
-
-    fun testAnchorMoves() {
-        val slots = SlotTable()
-
-        fun buildSlots(range: List<Int>): Map<Anchor, Any?> {
-            val anchors = mutableListOf<Pair<Anchor, Any?>>()
-            slots.write { writer ->
-                fun item(value: Any?, block: () -> Unit) {
-                    writer.startItem(value)
-                    block()
-                    writer.endItem()
-                }
-
-                fun value(value: Any?) {
-                    writer.update(value)
-                }
-
-                writer.beginInsert()
-                for (i in range) {
-                    item(i) {
-                        value(i * 100)
-                        anchors.add(slots.anchor(writer.current - 1) to i * 100)
-                    }
-                }
-                writer.endInsert()
-            }
-            return anchors.toMap()
-        }
-
-        fun validate(anchors: Map<Anchor, Any?>) {
-            slots.read { reader ->
-                for (anchor in anchors) {
-                    assertEquals(anchor.value, reader.get(slots.anchorLocation(anchor.key)))
-                }
-            }
-        }
-
-        fun moveItems() {
-            slots.write { writer ->
-                writer.skipItem()
-                writer.moveItem(4)
-                writer.skipItem()
-                writer.skipItem()
-                writer.moveItem(1)
-                writer.skipItem()
-                writer.skipItem()
-                writer.moveItem(1)
-            }
-        }
-
-        val expected = listOf(1, 2, 3, 4, 5, 6, 7)
-        val anchors = buildSlots(expected)
-        validate(anchors)
-        moveItems()
-        validate(anchors)
-    }
-
-    fun testRemovingDuplicateAnchorsMidRange() {
-        val slots = testSlotsNumbered()
-
-        val anchors = slots.write { writer -> (0 until 10).map { writer.anchor(30) } }
-        slots.write { it.remove(20, 20) }
-        for (anchor in anchors) {
-            assertEquals(-1, anchor.location(slots))
-        }
-    }
-
-    fun testRemovingDuplicateAnchorsStartRange() {
-        val slots = testSlotsNumbered()
-        val anchors = slots.write { writer -> (0 until 10).map { writer.anchor(30) } }
-        slots.write { it.remove(30, 20) }
-        for (anchor in anchors) {
-            assertEquals(-1, anchor.location(slots))
-        }
-    }
-
-    fun testRemovingDuplicateAnchorsEndRange() {
-        val slots = testSlotsNumbered()
-        val anchors = slots.write { writer -> (0 until 10).map { writer.anchor(30) } }
-        slots.write { it.remove(20, 11) }
-        for (anchor in anchors) {
-            assertEquals(-1, anchor.location(slots))
-        }
-    }
-
-    fun testDuplicateAnchorIdentity() {
-        val slots = testSlotsNumbered()
-        val anchors = slots.write { writer -> (0 until 10).map { writer.anchor(it * 5) } }
-        slots.write { writer ->
-            anchors.forEachIndexed { index, anchor ->
-                assertTrue(anchor === writer.anchor(index * 5))
-            }
-        }
-    }
-
-    // Semantic tests (testing groups and nodes)
-
-    fun testExtractKeys() {
-        val slots = testItems()
-        slots.read { reader ->
-            reader.startGroup()
-            val keys = reader.extractItemKeys()
-            assertEquals(10, keys.size)
-            keys.forEachIndexed { i, keyAndLocation ->
-                assertEquals(i, keyAndLocation.key)
-            }
-        }
-    }
-
-    fun testMoveAnItem() {
-        val slots = testItems()
-        slots.write { writer ->
-            writer.startGroup()
-            writer.moveItem(5)
-        }
-        slots.read { reader ->
-            reader.startGroup()
-            reader.expectItem(5)
-            for (i in 0 until 5) {
-                reader.expectItem(i)
-            }
-            for (i in 6 until 10) {
-                reader.expectItem(i)
-            }
-            reader.endGroup()
-        }
-    }
-
-    fun testRemoveAnItem() {
-        val slots = testItems()
-        slots.write { writer ->
-            writer.startGroup()
-            for (i in 0 until 5) {
-                writer.skipItem()
-            }
-            writer.removeItem()
-            for (i in 6 until 10) {
-                writer.skipItem()
-            }
-            writer.endGroup()
-        }
-
-        slots.read { reader ->
-            reader.startGroup()
-            for (i in 0 until 5) {
-                reader.expectItem(i)
-            }
-            for (i in 6 until 10) {
-                reader.expectItem(i)
-            }
-            reader.endGroup()
-        }
-    }
-
-    fun testCountNodes() {
-        val slots = testItems()
-        slots.read { reader ->
-            reader.startGroup()
-            for (i in 0 until 10) {
-                val count = reader.expectItem(i)
-                assertEquals(i + 1, count)
-            }
-            reader.endGroup()
-        }
-    }
-
-    fun testCountNestedNodes() {
-        val slots = SlotTable()
-        slots.write { writer ->
-            writer.beginInsert()
-            writer.startGroup()
-            writer.startItem(null)
-            repeat(10) {
-                writer.startItem(null)
-                repeat(3) {
-                    writer.startNode()
-                    writer.endNode()
-                }
-                assertEquals(3, writer.endItem())
-            }
-            assertEquals(30, writer.endItem())
-            writer.endGroup()
-            writer.endInsert()
-        }
-
-        slots.read { reader ->
-            reader.startGroup()
-            assertEquals(30, reader.expectItem(null))
-            reader.endGroup()
-        }
-    }
-
-    fun testUpdateNestedNodeCountOnInsert() {
-        val slots = SlotTable()
-        slots.write { writer ->
-            writer.beginInsert()
-            writer.startGroup()
-            writer.startItem(null)
-            repeat(10) {
-                writer.startItem(null)
-                repeat(3) {
-                    writer.startItem(null)
-                    writer.startNode()
-                    writer.endNode()
-                    assertEquals(1, writer.endItem())
-                }
-                assertEquals(3, writer.endItem())
-            }
-            assertEquals(30, writer.endItem())
-            writer.endGroup()
-            writer.endInsert()
-        }
-
-        slots.write { writer ->
-            writer.startGroup()
-            writer.startItem(null)
-
-            repeat(3) {
-                assertEquals(3, writer.skipItem())
-            }
-
-            writer.startItem(null)
-            writer.beginInsert()
-            repeat(2) {
-                writer.startItem(null)
-                writer.startNode()
-                writer.endNode()
-                assertEquals(1, writer.endItem())
-            }
-            writer.endInsert()
-            repeat(3) { writer.skipItem() }
-            assertEquals(5, writer.endItem())
-
-            repeat(6) {
-                assertEquals(3, writer.skipItem())
-            }
-
-            assertEquals(32, writer.endItem())
-            writer.endGroup()
-        }
-    }
-
-    fun testUpdateNestedNodeCountOnRemove() {
-        val slots = SlotTable()
-        slots.write { writer ->
-            writer.beginInsert()
-            writer.startGroup()
-            writer.startItem(null)
-            repeat(10) {
-                writer.startItem(null)
-                repeat(3) {
-                    writer.startItem(null)
-                    writer.startNode()
-                    writer.endNode()
-                    assertEquals(1, writer.endItem())
-                }
-                assertEquals(3, writer.endItem())
-            }
-            assertEquals(30, writer.endItem())
-            writer.endGroup()
-            writer.endInsert()
-        }
-
-        slots.write { writer ->
-            writer.startGroup()
-            writer.startItem(null)
-
-            repeat(3) {
-                assertEquals(3, writer.skipItem())
-            }
-
-            writer.startItem(null)
-
-            repeat(2) { writer.removeItem() }
-            repeat(1) { writer.skipItem() }
-            assertEquals(1, writer.endItem())
-
-            repeat(6) {
-                assertEquals(3, writer.skipItem())
-            }
-
-            assertEquals(28, writer.endItem())
-
-            writer.endGroup()
-        }
-    }
-
-    fun testNodesResetNodeCount() {
-        val slots = SlotTable()
-        slots.write { writer ->
-            writer.beginInsert()
-            writer.startGroup()
-            writer.startItem(null)
-            writer.startNode()
-            repeat(10) {
-                writer.startNode()
-                writer.startItem(null)
-                repeat(3) {
-                    writer.startNode()
-                    writer.endNode()
-                }
-                assertEquals(3, writer.endItem())
-                writer.endNode()
-            }
-            writer.endNode()
-            assertEquals(1, writer.endItem())
-            writer.endGroup()
-            writer.endInsert()
-        }
-    }
-
-    fun testSkipANode() {
-        val slots = SlotTable()
-        slots.write { writer ->
-            writer.beginInsert()
-            writer.startGroup()
-            writer.startItem(null)
-            writer.startNode()
-            repeat(10) {
-                writer.startNode()
-                writer.startItem(null)
-                repeat(3) {
-                    writer.startNode()
-                    writer.endNode()
-                }
-                assertEquals(3, writer.endItem())
-                writer.endNode()
-            }
-            writer.endNode()
-            assertEquals(1, writer.endItem())
-            writer.endGroup()
-            writer.endInsert()
-        }
-
-        slots.read { reader ->
-            reader.startGroup()
-            reader.startItem(null)
-            assertEquals(1, reader.skipNode())
-            reader.endItem()
-            reader.endGroup()
-        }
-    }
-
-    fun testStartEmpty() {
-        val slots = SlotTable()
-        slots.read { reader ->
-            reader.beginEmpty()
-            reader.startGroup()
-            assertEquals(true, reader.inEmpty)
-            assertEquals(SlotTable.EMPTY, reader.next())
-            reader.endGroup()
-            reader.endEmpty()
-        }
-    }
-
-    fun testReportGroupSize() {
-        val slots = SlotTable()
-        slots.write { writer ->
-            writer.beginInsert()
-            writer.startGroup()
-            writer.startItem(null)
-            repeat(10) {
-                writer.startNode()
-                writer.endNode()
-            }
-            writer.endItem()
-            writer.update(42)
-            writer.endGroup()
-            writer.endInsert()
-        }
-
-        slots.read { reader ->
-            reader.startGroup()
-            reader.next()
-            assertEquals(true, reader.isGroup)
-            val size = reader.groupSize
-            val savedCurrent = reader.current
-            reader.skipGroup()
-            assertEquals(size, reader.current - savedCurrent - 1)
-            assertEquals(42, reader.next())
-            assertEquals(true, reader.isGroupEnd)
-            reader.endGroup()
-        }
-    }
-
-    fun testIsGroups() {
-        val slots = SlotTable()
-        slots.write { writer ->
-            writer.beginInsert()
-            writer.startGroup()
-            writer.startGroup()
-            writer.endGroup()
-            writer.startNode()
-            writer.endNode()
-            writer.endGroup()
-            writer.endInsert()
-        }
-
-        slots.read { reader ->
-            reader.startGroup()
-            assertEquals(true, reader.isGroup)
-            reader.startGroup()
-            assertEquals(false, reader.isGroup)
-            assertEquals(true, reader.isGroupEnd)
-            reader.endGroup()
-            assertEquals(true, reader.isNode)
-            assertEquals(false, reader.isGroupEnd)
-            reader.startNode()
-            assertEquals(false, reader.isNode)
-            assertEquals(true, reader.isGroupEnd)
-            reader.endNode()
-            reader.endGroup()
-        }
-
-        slots.write { writer ->
-            writer.startGroup()
-            assertEquals(true, writer.isGroup)
-            writer.startGroup()
-            assertEquals(false, writer.isGroup)
-            writer.endGroup()
-            assertEquals(true, writer.isNode)
-            writer.startNode()
-            assertEquals(false, writer.isNode)
-            writer.endNode()
-            writer.endGroup()
-        }
-    }
-
-    fun testReportUncertainNodeCount() {
-        val slots = SlotTable()
-        slots.read { reader -> reader.reportUncertainNodeCount() }
-    }
-
-    fun testMoveGroup() {
-        val slots = SlotTable()
-
-        val anchors = mutableListOf<Anchor>()
-
-        fun buildSlots() {
-            slots.write { writer ->
-                fun group(block: () -> Unit) {
-                    writer.startGroup()
-                    block()
-                    writer.endGroup()
-                }
-
-                fun item(key: Any?, block: () -> Unit) {
-                    writer.startItem(key)
-                    block()
-                    writer.endItem()
-                }
-
-                fun element(key: Any?, block: () -> Unit) {
-                    writer.update(key)
-                    writer.startNode()
-                    block()
-                    writer.endNode()
-                }
-
-                fun value(value: Any) {
-                    writer.update(value)
-                }
-
-                fun innerItem(i: Any) {
-                    item(i) {
-                        value(i)
-                        value(25)
-                        item(26) {
-                            item(28) {
-                                value(30)
-                                item(31) {
-                                    item(33) {
-                                        group {
-                                            value(36)
-                                            item(37) {
-                                                value(39)
-                                                element(40) {
-                                                    value(42)
-                                                    value(43)
-                                                    element(44) {
-                                                        value(46)
-                                                        value(47)
-                                                    }
-                                                    element(48) {
-                                                        value(50)
-                                                        value(51)
-                                                        value(52)
-                                                        value(53)
-                                                    }
-                                                    element(54) {
-                                                        value(56)
-                                                        value(57)
-                                                        value(58)
-                                                        value(59)
-                                                    }
-                                                    element(60) {
-                                                        value(62)
-                                                        anchors.add(
-                                                            slots.anchor(writer.current - 1)
-                                                        )
-                                                        value(63)
-                                                        value(64)
-                                                        value(65)
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-
-                // Build a slot table to that duplicates the structure of the slot table produced
-                // in the code generation test testMovement()
-                writer.beginInsert()
-                item(0) {
-                    item(2) {
-                        item(4) {
-                            item(6) {
-                                value(8)
-                                item(9) {
-                                    item(11) {
-                                        group {
-                                            value(14)
-                                            item(15) {
-                                                value(17)
-                                                element(18) {
-                                                    value(20)
-                                                    value(21)
-                                                    for (i in 1..5) {
-                                                        innerItem(i)
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-                writer.endInsert()
-            }
-        }
-
-        fun validateSlots(range: List<Int>) {
-            slots.read { reader ->
-                fun group(block: () -> Unit) {
-                    reader.startGroup()
-                    block()
-                    reader.endGroup()
-                }
-
-                fun value(value: Any?) {
-                    Assert.assertEquals(value, reader.next())
-                }
-
-                fun item(key: Any?, block: () -> Unit) {
-                    reader.startItem(key)
-                    block()
-                    reader.endItem()
-                }
-
-                fun element(key: Any?, block: () -> Unit) {
-                    value(key)
-                    reader.startNode()
-                    block()
-                    reader.endNode()
-                }
-
-                fun innerBlock(i: Any) {
-                    item(i) {
-                        value(i)
-                        value(25)
-                        item(26) {
-                            item(28) {
-                                value(30)
-                                item(31) {
-                                    item(33) {
-                                        group {
-                                            value(36)
-                                            item(37) {
-                                                value(39)
-                                                element(40) {
-                                                    value(42)
-                                                    value(43)
-                                                    element(44) {
-                                                        value(46)
-                                                        value(47)
-                                                    }
-                                                    element(48) {
-                                                        value(50)
-                                                        value(51)
-                                                        value(52)
-                                                        value(53)
-                                                    }
-                                                    element(54) {
-                                                        value(56)
-                                                        value(57)
-                                                        value(58)
-                                                        value(59)
-                                                    }
-                                                    element(60) {
-                                                        value(62)
-                                                        value(63)
-                                                        value(64)
-                                                        value(65)
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-
-                item(0) {
-                    item(2) {
-                        item(4) {
-                            item(6) {
-                                value(8)
-                                item(9) {
-                                    item(11) {
-                                        group {
-                                            value(14)
-                                            item(15) {
-                                                value(17)
-                                                element(18) {
-                                                    value(20)
-                                                    value(21)
-                                                    for (i in range) {
-                                                        innerBlock(i)
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        fun moveItem5Up() {
-            slots.write { writer ->
-                fun group(block: () -> Unit) {
-                    writer.startGroup()
-                    block()
-                    writer.endGroup()
-                }
-
-                fun item(key: Any?, block: () -> Unit) {
-                    writer.startItem(key)
-                    block()
-                    writer.endItem()
-                }
-
-                fun element(key: Any?, block: () -> Unit) {
-                    writer.update(key)
-                    writer.startNode()
-                    block()
-                    writer.endNode()
-                }
-
-                fun value(value: Any) {
-                    writer.update(value)
-                }
-                item(0) {
-                    item(2) {
-                        item(4) {
-                            item(6) {
-                                value(8)
-                                item(9) {
-                                    item(11) {
-                                        group {
-                                            value(14)
-                                            item(15) {
-                                                value(17)
-                                                element(18) {
-                                                    value(20)
-                                                    value(21)
-
-                                                    // Skip three items
-                                                    writer.skipItem()
-                                                    writer.skipItem()
-                                                    writer.skipItem()
-
-                                                    // Move one item up
-                                                    writer.moveItem(1)
-
-                                                    // Skip them
-                                                    writer.skipItem()
-                                                    writer.skipItem()
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        buildSlots()
-        validateSlots((1..5).toList())
-        moveItem5Up()
-        validateSlots(listOf(1, 2, 3, 5, 4))
-
-        // Validate that all the anchors still refer to a slot with value 62
-        slots.read { reader ->
-            for (anchor in anchors) {
-                Assert.assertEquals(62, reader.get(slots.anchorLocation(anchor)))
-            }
-        }
-    }
-}
-
-fun testSlotsNumbered(): SlotTable {
-    val items = arrayOfNulls<Any?>(100)
-    repeat(100) {
-        items[it] = it
-    }
-    return SlotTable(items)
-}
-
-private val elementKey = object {}
-// Creates 0 until 10 items each with 10 elements numbered 0...n with 0..n slots
-fun testItems(): SlotTable {
-    val slots = SlotTable()
-    slots.write { writer ->
-        writer.beginInsert()
-        writer.startGroup()
-
-        fun item(key: Any?, block: () -> Unit) {
-            writer.startItem(key)
-            block()
-            writer.endItem()
-        }
-
-        fun element(key: Any?, block: () -> Unit) {
-            item(key) {
-                writer.startNode()
-                block()
-                writer.endNode()
-            }
-        }
-
-        for (key in 0 until 10) {
-            item(key) {
-                for (item in 0..key) {
-                    element(elementKey) {
-                        for (element in 0..key)
-                            writer.update(element)
-                    }
-                }
-            }
-        }
-
-        writer.endGroup()
-        writer.endInsert()
-    }
-
-    return slots
-}
-
-fun SlotReader.startItem(key: Any?) {
-    org.junit.Assert.assertEquals(key, next())
-    startGroup()
-}
-fun SlotReader.endItem(): Int = endGroup()
-
-fun SlotReader.expectItem(key: Any?): Int {
-    org.junit.Assert.assertEquals(key, next())
-    return skipGroup()
-}
-
-fun SlotWriter.startItem(key: Any?) {
-    update(key)
-    startGroup()
-}
-fun SlotWriter.endItem(): Int = endGroup()
diff --git a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ViewComposerTests.kt b/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ViewComposerTests.kt
deleted file mode 100644
index 08a097b..0000000
--- a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/ViewComposerTests.kt
+++ /dev/null
@@ -1,1013 +0,0 @@
-/*
- * Copyright 2019 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
-
-import android.app.Activity
-import android.content.Context
-import android.os.Bundle
-import android.view.View
-import android.view.ViewGroup
-import android.widget.FrameLayout
-import android.widget.LinearLayout
-import android.widget.TextView
-import androidx.test.annotation.UiThreadTest
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import androidx.test.rule.ActivityTestRule
-import junit.framework.TestCase.assertEquals
-import org.junit.Ignore
-import org.junit.Rule
-import org.junit.runner.RunWith
-import org.junit.Test
-
-class TestActivity : Activity() {
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-        setContentView(LinearLayout(this).apply {
-            id =
-                ComposerComposeTestCase.ROOT_ID
-        })
-    }
-}
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class NewCodeGenTests {
-
-    @get:Rule
-    val activityRule = ActivityTestRule(TestActivity::class.java)
-
-    @Test
-    @UiThreadTest
-    fun testStaticComposition() {
-        val tv1Id = 100
-        val tv2Id = 200
-
-        compose {
-            emit(168, { context ->
-                TextView(context).apply {
-                    text = "Hello world!"; id = tv1Id
-                }
-            }) { }
-
-            emit(170, { context ->
-                LinearLayout(context).apply {
-                    orientation = LinearLayout.HORIZONTAL
-                }
-            }, { }) {
-                emit(171, { context ->
-                    TextView(context).apply {
-                        text = "Yellow world"; id = tv2Id
-                    }
-                }) { }
-            }
-        }.then { activity ->
-            val helloText = activity.findViewById(tv1Id) as TextView
-            assertEquals("Hello world!", helloText.text)
-            val yellowText = activity.findViewById(tv2Id) as TextView
-            assertEquals("Yellow world", yellowText.text)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testUpdatedComposition() {
-        val tv1Id = 100
-        val tv2Id = 200
-
-        var text1 = "Hello world!"
-        var text2 = "Yellow world"
-
-        compose {
-            emit(168, { context -> TextView(context).apply { id = tv1Id } }) {
-                set(text1) { text = it }
-            }
-            emit(170, { context ->
-                LinearLayout(context).apply {
-                    orientation = LinearLayout.HORIZONTAL
-                }
-            }, { }) {
-                emit(171, { context -> TextView(context).apply { id = tv2Id } }) {
-                    set(text2) { text = it }
-                }
-            }
-        }.then { activity ->
-            val helloText = activity.findViewById(tv1Id) as TextView
-            assertEquals(text1, helloText.text)
-            val yellowText = activity.findViewById(tv2Id) as TextView
-            assertEquals(text2, yellowText.text)
-
-            // Modify the composed state
-            text1 += " (changed)"
-            text2 += " (changed)"
-        }.then { activity ->
-            val helloText = activity.findViewById(tv1Id) as TextView
-            assertEquals(text1, helloText.text)
-            val yellowText = activity.findViewById(tv2Id) as TextView
-            assertEquals(text2, yellowText.text)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testSingleView() {
-        val tvId = 237
-        var text = "Hello world"
-
-        compose {
-            // <TextView text id=tvId />
-            emit(242, { context -> TextView(context).apply { id = tvId } }) {
-                set(text) { this.text = it }
-            }
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("Hello world", tv.text)
-
-            text = "Salutations!"
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("Salutations!", tv.text)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testViewGroup() {
-        val tvId = 258
-        val llId = 260
-        var text = "Hello world"
-        var orientation = LinearLayout.HORIZONTAL
-
-        compose {
-            // <LinearLayout>
-            //  <TextView text />
-            // </LinearLayout
-            emit(264, { context: Context -> LinearLayout(context).apply { id = llId } }, {
-                set(orientation) { this.orientation = it }
-            }) {
-                emit(265, { context -> TextView(context).apply { id = tvId } }) {
-                    set(text) { this.text = it }
-                }
-            }
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("Hello world", tv.text)
-
-            text = "Salutations!"
-            orientation = LinearLayout.VERTICAL
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("Salutations!", tv.text)
-
-            val ll = activity.findViewById(llId) as LinearLayout
-            assertEquals(LinearLayout.VERTICAL, ll.orientation)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testComposableFunctionInvocationOneParameter() {
-        data class Phone(val area: String, val prefix: String, val number: String)
-
-        var phone = Phone("123", "456", "7890")
-        var phoneCalled = 0
-        compose {
-
-            // Composition function
-            //  @Composable
-            //  fun PhoneView(phone: Phone) {
-            //    phoneCalled++
-            //   TextView(text="...")
-            //  }
-            fun PhoneView(phone: Phone) {
-                phoneCalled++
-                emit(225, { context -> TextView(context) }) {
-                    set(
-                        "${if (phone.area.isBlank()) ""
-                        else "(${phone.area}) "}${phone.prefix}-${phone.number}"
-                    ) { text = it }
-                }
-            }
-
-            // <PhoneView phone />
-            call(453, { changed(phone) }) {
-                PhoneView(phone)
-            }
-        }.then { _ ->
-            assertEquals(1, phoneCalled)
-        }.then { _ ->
-            assertEquals(1, phoneCalled)
-
-            phone = Phone("124", "456", "7890")
-        }.then { _ ->
-            assertEquals(2, phoneCalled)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testComposableFunctionInvocationTwoParameters() {
-        val tvId = 279
-        var left = 0
-        var right = 1
-        var addCalled = 0
-        compose {
-
-            // Composition function
-            //  @Composable
-            //  fun AddView(left: Int, right: Int) {
-            //    addCalled++
-            //   <TextView text="$left + $right = ${left + right}" />
-            //  }
-            fun AddView(left: Int, right: Int) {
-                addCalled++
-                emit(292, { context -> TextView(context).apply { id = tvId } }) {
-                    set("$left + $right = ${left + right}") { text = it }
-                }
-            }
-
-            // <AddView left right />
-            call(491, { changed(left) + changed(right) }) {
-                AddView(left, right)
-            }
-        }.then { activity ->
-            assertEquals(1, addCalled)
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-        }.then { activity ->
-            assertEquals(1, addCalled)
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-
-            left = 1
-        }.then { activity ->
-            assertEquals(2, addCalled)
-
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-        }.then { activity ->
-            assertEquals(2, addCalled)
-
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-
-            right = 41
-        }.then { activity ->
-            assertEquals(3, addCalled)
-
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testStatelessComposableClassInvocationProperties() {
-        val tvId = 338
-        var addCalled = 0
-
-        var left = 0
-        var right = 0
-        compose {
-            // TODO: The composition field is a work-around for an IR bug. The IR doesn't support a
-            // local class capturing a variable so this make the capture explicit
-            class AddView(val composition: ViewComposition) {
-                var left = 0
-                var right = 0
-
-                operator fun invoke() {
-                    with(composition) {
-                        // <TextView "$left + $right = ${left + right}" />
-                        emit(350, { context -> TextView(context).apply { id = tvId } }) {
-                            addCalled++
-                            set(
-                                "${this@AddView.left} + ${this@AddView.right} = ${
-                                this@AddView.left + this@AddView.right}"
-                            ) { text = it }
-                        }
-                    }
-                }
-            }
-
-            // <AddView left right />
-            call(358,
-                { AddView(this@compose) },
-                { f -> set(left) { f.left = it } + set(right) { f.right = it } }) { f ->
-                f()
-            }
-        }.then { activity ->
-            assertEquals(1, addCalled)
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-        }.then { activity ->
-            assertEquals(1, addCalled)
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-
-            left = 1
-        }.then { activity ->
-            assertEquals(2, addCalled)
-
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-        }.then { activity ->
-            assertEquals(2, addCalled)
-
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-
-            right = 41
-        }.then { activity ->
-            assertEquals(3, addCalled)
-
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testStatelessComposableClassInvocationParameters() {
-        val tvId = 338
-        var addCalled = 0
-
-        var left = 0
-        var right = 0
-
-        compose {
-            // TODO: The composition field is a work-around for an IR bug. The IR doesn't support a
-            // local class capturing a variable so this make the capture explicit
-            class AddView(val composition: ViewComposition) {
-
-                operator fun invoke(left: Int, right: Int) {
-                    with(composition) {
-                        // <TextView "$left + $right = ${left + right}" />
-                        emit(350, { context -> TextView(context).apply { id = tvId } }) {
-                            addCalled++
-                            set("$left + $right = ${left + right}") { text = it }
-                        }
-                    }
-                }
-            }
-
-            // <AddView left right />
-            call(612, { changed(left) + changed(right) }) {
-                AddView(this@compose)(left, right)
-            }
-        }.then { activity ->
-            assertEquals(1, addCalled)
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-        }.then { activity ->
-            assertEquals(1, addCalled)
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-
-            left = 1
-        }.then { activity ->
-            assertEquals(2, addCalled)
-
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-        }.then { activity ->
-            assertEquals(2, addCalled)
-
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-
-            right = 41
-        }.then { activity ->
-            assertEquals(3, addCalled)
-
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testStatefulComposableClassInvocation() {
-        val tvId = 470
-        val tvPrivateValue = 471
-        var addCalled = 0
-
-        var left = 0
-        var right = 0
-
-        lateinit var updatePrivate: (value: String) -> Unit
-
-        compose {
-            // TODO: The composition field is a work-around for an IR bug. The IR doesn't support a
-            // local class capturing a variable so this make the capture explicit
-            class AddView(val composition: ViewComposition) {
-
-                var left = 0
-                var right = 0
-
-                private var privateValue = "Unmodified"
-
-                operator fun invoke() {
-                    with(composition) {
-                        addCalled++
-
-                        // <TextView "$left + $right = ${left + right}" />
-                        emit(491, { context -> TextView(context).apply { id = tvId } }) {
-                            set(
-                                "${this@AddView.left} + ${this@AddView.right} = ${
-                                this@AddView.left + this@AddView.right}"
-                            ) { text = it }
-                        }
-
-                        emit(496, { context ->
-                            TextView(context).apply {
-                                id = tvPrivateValue
-                            }
-                        }) {
-                            set(privateValue) { text = it }
-                        }
-
-                        updatePrivate = {
-                            privateValue = it
-                            // TODO: This actually requires recompose(). Update when that is
-                            // available recompose()
-                        }
-                    }
-                }
-            }
-
-            // <AddView left right />
-            // TODO: remove the + true when recompose() is available.
-            call(690,
-                { AddView(this@compose) },
-                { f -> set(left) { f.left = it } + set(right) { f.right = it } + true }) { f ->
-                f()
-            }
-        }.then { activity ->
-            assertEquals(1, addCalled)
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-
-            left = 1
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-
-            right = 41
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-
-            val privateTv = activity.findViewById(tvPrivateValue) as TextView
-            assertEquals("Unmodified", privateTv.text)
-
-            updatePrivate("Modified value")
-        }.then { activity ->
-            val privateTv = activity.findViewById(tvPrivateValue) as TextView
-            assertEquals("Modified value", privateTv.text)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testStatefulComposableClassWithCtorParametersInvocation() {
-        val tvId = 604
-        val tvOffsetId = 605
-
-        var offset = 0
-        var left = 0
-        var right = 0
-        compose {
-            // TODO: The composition field is a work-around for an IR bug. The IR doesn't support a
-            // local class capturing a variable so this make the capture explicit
-            class OffsetAddView(
-                val composition: ViewComposition,
-                var offset: Int
-            ) {
-
-                var left = 0
-                var right = 0
-
-                operator fun invoke() {
-                    with(composition) {
-
-                        // <TextView "$left + $right = ${left + right}" />
-                        emit(619, { context -> TextView(context).apply { id = tvId } }) {
-                            set(
-                                "${this@OffsetAddView.left} + ${this@OffsetAddView.right} = ${
-                                this@OffsetAddView.left + this@OffsetAddView.right}"
-                            ) {
-                                text = it
-                            }
-                        }
-
-                        // <TextView text="$offset" />
-                        emit(623, { context -> TextView(context).apply { id = tvOffsetId } }) {
-                            set("$offset") { this.text = it }
-                        }
-                    }
-                }
-            }
-
-            // <OffsetAddView offset left right />
-            call(768,
-                { OffsetAddView(this@compose, offset) },
-                { f ->
-                    update(offset) { f.offset = it } + set(left) { f.left = it } + set(right) {
-                        f.right = it
-                    }
-                }
-            ) { f ->
-                f()
-            }
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-
-            val offsetTv = activity.findViewById(tvOffsetId) as TextView
-            assertEquals("$offset", offsetTv.text)
-
-            offset = 30
-        }.then { activity ->
-            val offsetTv = activity.findViewById(tvOffsetId) as TextView
-            assertEquals("$offset", offsetTv.text)
-
-            left = 20
-            right = 21
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testStatefulComposableClassWithPivotalProperty() {
-        val tvId = 604
-        val tvOffsetId = 605
-
-        var offset = 0
-        var left = 0
-        var right = 0
-        compose {
-            // TODO: The composition field is a work-around for an IR bug. The IR doesn't support a
-            // local class capturing a variable so this make the capture explicit
-            class OffsetAddView(
-                val composition: ViewComposition,
-                val offset: Int
-            ) {
-
-                var left = 0
-                var right = 0
-
-                operator fun invoke() {
-                    with(composition) {
-
-                        // <TextView "$left + $right = ${left + right}" />
-                        emit(709, { context -> TextView(context).apply { id = tvId } }) {
-                            set(
-                                "${this@OffsetAddView.left} + ${this@OffsetAddView.right} = ${
-                                this@OffsetAddView.left + this@OffsetAddView.right}"
-                            ) {
-                                text = it
-                            }
-                        }
-
-                        // <TextView text="$offset" />
-                        emit(714, { context ->
-                            TextView(context).apply {
-                                id = tvOffsetId
-                            }
-                        }) {
-                            set("${this@OffsetAddView.offset}") { this.text = it }
-                        }
-                    }
-                }
-            }
-
-            // <OffsetAddView offset left right />
-            call(joinKey(831, offset),
-                { OffsetAddView(this@compose, offset) },
-                { f -> set(left) { f.left = it } + set(right) { f.right = it } }) { f ->
-                f()
-            }
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-
-            val offsetTv = activity.findViewById(tvOffsetId) as TextView
-            assertEquals("$offset", offsetTv.text)
-
-            offset = 30
-        }.then { activity ->
-            val offsetTv = activity.findViewById(tvOffsetId) as TextView
-            assertEquals("$offset", offsetTv.text)
-
-            left = 20
-            right = 21
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("$left + $right = ${left + right}", tv.text)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testMoveComponents() {
-        val data = mutableListOf(1, 2, 3, 4, 5)
-        compose {
-            for (item in data) {
-                emit(joinKey(560, item), { context ->
-                    TextView(context).apply { text = "$item View" }
-                }) { }
-            }
-        }.then {
-            data.add(data.removeAt(0))
-        }.then { activity ->
-            val root = activity.root
-            for (index in 0 until data.size) {
-                val textView = root.getChildAt(index) as TextView
-                assertEquals("${data[index]} View", textView.text)
-            }
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testViewClassWithCtorParametersInvocation() {
-        val tvId = 749
-
-        class MyTextView(context: Context) : TextView(context) {
-            constructor(context: Context, someText: String) : this(context) {
-                text = someText
-            }
-        }
-
-        var hello = "Hello world!"
-        compose {
-            // <MyTextView someText=hello />
-            emit(joinKey(760, hello), { context ->
-                MyTextView(context, hello).apply { id = tvId }
-            }) { }
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("Hello world!", tv.text)
-
-            hello = "Salutations!"
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("Salutations!", tv.text)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testViewClassWithMutableCtorParameter() {
-        val tvId = 749
-
-        class MyTextView(context: Context, var someValue: String) : TextView(context)
-
-        var hello = "Hello world!"
-        var value = "Unmodified"
-        compose {
-            // <MyTextView someText=hello />
-            emit(760, { context -> MyTextView(context, value).apply { id = tvId } }) {
-                update(value) { someValue = it }
-                set(hello) { this.text = it }
-            }
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as MyTextView
-            assertEquals("Hello world!", tv.text)
-            assertEquals("Unmodified", tv.someValue)
-
-            hello = "Salutations!"
-            value = "Modified"
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as MyTextView
-            assertEquals("Salutations!", tv.text)
-            assertEquals("Modified", tv.someValue)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testEmittingAnEmittable() {
-
-        class MyEmittable : MockEmittable() {
-            var message: String = ""
-        }
-
-        compose {
-            adaptable {
-                emit(615, { context -> LinearLayout(context) }, {}) {
-                    emit(616, { -> MyEmittable() }, { set("Message") { message = it } }) {
-                        emit(617, { context -> TextView(context) }, {
-                            set("SomeValue") { text = it }
-                        })
-                        emit(620, { -> MyEmittable() }, { set("Message2") { message = it } })
-                    }
-                }
-            }
-        }.then { activity ->
-            val root = activity.root.getChildAt(0) as LinearLayout
-            val firstChild = root.getChildAt(0) as ViewEmitWrapper
-            val emitted = firstChild.emittable as MockEmittable
-            val firstEmitChild = emitted.children[0] as EmitViewWrapper
-            firstEmitChild.view as TextView
-            val secondEmit = emitted.children[1] as MyEmittable
-            assertEquals(0, secondEmit.children.size)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testCGEmittingAnEmittable() {
-
-        class MyEmittable : MockEmittable() {
-            var message: String = ""
-        }
-
-        composeCG {
-            adaptable {
-                val cc = composer
-                cc.emitViewGroup(615, { context -> LinearLayout(context) }, {}) {
-                    cc.emitEmittable(616, { -> MyEmittable() }, {
-                        set("Message") { message = it }
-                    }) {
-                        cc.emit(617, { context -> TextView(context) }, {
-                            set("SomeValue") { text = it }
-                        })
-                        cc.emitEmittable(620, { -> MyEmittable() }, {
-                            set("Message2") { message = it }
-                        })
-                    }
-                }
-            }
-        }.then { activity ->
-            val root = activity.root.getChildAt(0) as LinearLayout
-            val firstChild = root.getChildAt(0) as ViewEmitWrapper
-            val emitted = firstChild.emittable as MockEmittable
-            val firstEmitChild = emitted.children[0] as EmitViewWrapper
-            firstEmitChild.view as TextView
-            val secondEmit = emitted.children[1] as MyEmittable
-            assertEquals(0, secondEmit.children.size)
-        }.then { activity ->
-            val root = activity.root.getChildAt(0) as LinearLayout
-            val firstChild = root.getChildAt(0) as ViewEmitWrapper
-            val emitted = firstChild.emittable as MockEmittable
-            val firstEmitChild = emitted.children[0] as EmitViewWrapper
-            firstEmitChild.view as TextView
-            val secondEmit = emitted.children[1] as MyEmittable
-            assertEquals(0, secondEmit.children.size)
-        }
-    }
-
-    @Test
-    @UiThreadTest
-    fun testCGEmittableAsRoot() {
-        class MyEmittable : MockEmittable() {
-            var message: String = ""
-        }
-
-        val root = MyEmittable()
-
-        var first = "Hi"
-        var second = "there"
-        composeCG { activity ->
-            adaptable {
-                Compose.composeInto(root, activity) {
-                    val cc = composer
-                    cc.emitEmittable(686, { MyEmittable() }, { set(first) { message = it } }) {
-                        cc.emitEmittable(687, { MyEmittable() }, {
-                            set(second) { message = it }
-                        })
-                    }
-                }
-            }
-        }.then {
-            assertEquals(first, (root.children.first() as MyEmittable).message)
-            assertEquals(
-                second,
-                ((root.children.first() as MyEmittable).children.first() as MyEmittable).message
-            )
-
-            first = "hello"
-            second = "dolly"
-        }.then {
-            assertEquals(first, (root.children.first() as MyEmittable).message)
-            assertEquals(
-                second,
-                ((root.children.first() as MyEmittable).children.first() as MyEmittable).message
-            )
-        }
-    }
-
-    open class MockEmittable : Emittable {
-        val children = mutableListOf<Emittable>()
-        override fun emitInsertAt(index: Int, instance: Emittable) {
-            children.add(index, instance)
-        }
-
-        override fun emitRemoveAt(index: Int, count: Int) {
-            children.subList(index, count).clear()
-        }
-
-        override fun emitMove(from: Int, to: Int, count: Int) {
-            val range = children.subList(from, count)
-            val moved = range.map { it }
-            range.clear()
-            children.addAll(if (to > from) to - count else to, moved)
-        }
-    }
-
-    class ViewEmitWrapper(context: Context) : View(context) {
-        var emittable: Emittable? = null
-    }
-
-    class EmitViewWrapper : MockEmittable() {
-        var view: View? = null
-    }
-
-    fun ViewComposition.adaptable(block: ViewComposition.() -> Unit) {
-        composer.adapters?.register { parent, child ->
-            when (parent) {
-                is ViewGroup -> when (child) {
-                    is View -> child
-                    is Emittable -> ViewEmitWrapper(composer.context).apply { emittable = child }
-                    else -> null
-                }
-                is Emittable -> when (child) {
-                    is View -> EmitViewWrapper().apply { view = child }
-                    is Emittable -> child
-                    else -> null
-                }
-                else -> null
-            }
-        }
-        block()
-    }
-
-    fun compose(block: ViewComposition.() -> Unit) =
-        CompositionTest(activityRule.activity, block)
-
-    class CompositionTest(val activity: Activity, val composable: ViewComposition.() -> Unit) {
-
-        inner class ActiveTest(val composition: ViewComposition, val activity: Activity) {
-            private fun compose() {
-                composition.composer.startRoot()
-                composition.composable()
-                composition.composer.endRoot()
-                composition.composer.applyChanges()
-            }
-
-            fun then(block: (activity: Activity) -> Unit): ActiveTest {
-                compose()
-                block(activity)
-                return this
-            }
-        }
-
-        fun then(block: (activity: Activity) -> Unit): ActiveTest {
-            val composition = ViewComposition(
-                ViewComposer(activity.root, activity, object : Recomposer() {
-                    override fun scheduleChangesDispatch() {}
-
-                    override fun hasPendingChanges(): Boolean = false
-                })
-            )
-            return ActiveTest(composition, activity).then(block)
-        }
-    }
-
-    class TestContext(val cc: CompositionContext) {
-        fun adaptable(block: TestContext.() -> Unit) {
-            composer.registerAdapter { parent, child ->
-                when (parent) {
-                    is ViewGroup -> when (child) {
-                        is View -> child
-                        is Emittable -> ViewEmitWrapper(parent.context).apply { emittable = child }
-                        else -> null
-                    }
-                    is Emittable -> when (child) {
-                        is View -> EmitViewWrapper().apply { view = child }
-                        is Emittable -> child
-                        else -> null
-                    }
-                    else -> null
-                }
-            }
-            block()
-        }
-    }
-
-    fun composeCG(block: TestContext.(activity: Activity) -> Unit) =
-        CompositionCodeGenTest(activityRule.activity, block)
-
-    private class Root : Component() {
-        override fun compose() {}
-    }
-
-    class CompositionCodeGenTest(
-        val activity: Activity,
-        val composable: TestContext.(activity: Activity) -> Unit
-    ) {
-        inner class ActiveTest(
-            val activity: Activity,
-            val context: TestContext,
-            val component: Component
-        ) {
-
-            fun then(block: TestContext.(activity: Activity) -> Unit): ActiveTest {
-                val composer = context.cc.composer
-                composer.runWithCurrent {
-                    composer.startRoot()
-                    context.composable(activity)
-                    composer.endRoot()
-                    composer.applyChanges()
-                    context.block(activity)
-                }
-                return this
-            }
-        }
-
-        fun then(block: TestContext.(activity: Activity) -> Unit): ActiveTest {
-            val root = activity.root
-            val component = Root()
-            val cc = Compose.createCompositionContext(root.context, root, component, null)
-            return ActiveTest(activity, TestContext(cc), component).then(block)
-        }
-    }
-}
-
-@RunWith(AndroidJUnit4::class)
-class DisposeTests {
-
-    @get:Rule
-    val disposeActivityRule = ActivityTestRule(DisposeTestActivity::class.java)
-
-    class DisposeTestActivity : Activity() {
-        override fun onCreate(savedInstanceState: Bundle?) {
-            super.onCreate(savedInstanceState)
-            val root = FrameLayout(this)
-            val log = mutableListOf<String>()
-            val composable = @Composable {
-                +onPreCommit {
-                    log.add("onPreCommit")
-                    onDispose {
-                        log.add("onPreCommitDispose")
-                    }
-                }
-                +onActive {
-                    log.add("onActive")
-                    onDispose {
-                        log.add("onActiveDispose")
-                    }
-                }
-            }
-
-            log.clear()
-            Compose.composeInto(container = root, composable = composable)
-            assertEquals("onPreCommit, onActive", log.joinToString())
-
-            log.clear()
-            Compose.composeInto(container = root, composable = composable)
-            assertEquals("onPreCommitDispose, onPreCommit", log.joinToString())
-
-            log.clear()
-            Compose.disposeComposition(container = root)
-            assertEquals("onActiveDispose, onPreCommitDispose", log.joinToString())
-
-            log.clear()
-            Compose.composeInto(container = root, composable = composable)
-            assertEquals("onPreCommit, onActive", log.joinToString())
-        }
-    }
-
-    @Test
-    @SmallTest
-    @Ignore("TODO(b/138720405): Investigate synchronisation issues in tests")
-    fun testDisposeComposition() {
-        disposeActivityRule.activity
-    }
-}
-
-private val Activity.root get() = findViewById(ComposerComposeTestCase.ROOT_ID) as ViewGroup
diff --git a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/frames/FramesTests.kt b/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/frames/FramesTests.kt
deleted file mode 100644
index 7c2e9c4..0000000
--- a/compose/compose-runtime/integration-tests/android-tests/src/androidTest/java/androidx/compose/frames/FramesTests.kt
+++ /dev/null
@@ -1,1166 +0,0 @@
-/*
- * Copyright 2019 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.frames
-
-import androidx.test.filters.SmallTest
-import junit.framework.TestCase
-import org.junit.Assert
-import java.util.ArrayDeque
-import kotlin.reflect.KClass
-
-const val OLD_STREET = "123 Any Street"
-const val OLD_CITY = "AnyTown"
-const val NEW_STREET = "456 New Street"
-const val NEW_CITY = "AnyCity"
-
-@SmallTest
-class FrameTest : TestCase() {
-
-    fun testCreatingAddress() {
-        val address = frame {
-            val address = Address(
-                OLD_STREET,
-                OLD_CITY
-            )
-            Assert.assertEquals(OLD_STREET, address.street)
-            Assert.assertEquals(OLD_CITY, address.city)
-            address
-        }
-        frame {
-            Assert.assertEquals(OLD_STREET, address.street)
-            Assert.assertEquals(OLD_CITY, address.city)
-        }
-    }
-
-    fun testModifyingAddress() {
-        val address = frame {
-            Address(
-                OLD_STREET,
-                OLD_CITY
-            )
-        }
-        frame {
-            address.street = NEW_STREET
-        }
-        frame {
-            Assert.assertEquals(NEW_STREET, address.street)
-            Assert.assertEquals(OLD_CITY, address.city)
-        }
-    }
-
-    fun testIsolation() {
-        val address = frame {
-            Address(
-                OLD_STREET,
-                OLD_CITY
-            )
-        }
-        val f = suspended {
-            address.street = NEW_STREET
-        }
-        frame {
-            Assert.assertEquals(OLD_STREET, address.street)
-        }
-        restored(f) {
-            Assert.assertEquals(NEW_STREET, address.street)
-        }
-        frame {
-            Assert.assertEquals(NEW_STREET, address.street)
-        }
-    }
-
-    fun testRecordReuse() {
-        val address = frame {
-            Address(
-                OLD_STREET,
-                OLD_CITY
-            )
-        }
-        Assert.assertEquals(1, address.firstFrameRecord.length)
-        frame { address.street = NEW_STREET }
-        Assert.assertEquals(2, address.firstFrameRecord.length)
-        frame { address.street = "other street" }
-        Assert.assertEquals(2, address.firstFrameRecord.length)
-    }
-
-    fun testAborted() {
-        val address = frame {
-            Address(
-                OLD_STREET,
-                OLD_CITY
-            )
-        }
-        aborted {
-            address.street = NEW_STREET
-            Assert.assertEquals(NEW_STREET, address.street)
-        }
-        frame {
-            Assert.assertEquals(OLD_STREET, address.street)
-        }
-    }
-
-    fun testReuseAborted() {
-        val address = frame {
-            Address(
-                OLD_STREET,
-                OLD_CITY
-            )
-        }
-        Assert.assertEquals(1, address.firstFrameRecord.length)
-        aborted { address.street = NEW_STREET }
-        Assert.assertEquals(2, address.firstFrameRecord.length)
-        frame { address.street = "other street" }
-        Assert.assertEquals(2, address.firstFrameRecord.length)
-    }
-
-    fun testSpeculation() {
-        val address = frame {
-            Address(
-                OLD_STREET,
-                OLD_CITY
-            )
-        }
-        speculation {
-            address.street = NEW_STREET
-            Assert.assertEquals(NEW_STREET, address.street)
-        }
-        frame {
-            Assert.assertEquals(OLD_STREET, address.street)
-        }
-    }
-
-    fun testSpeculationIsolation() {
-        val address = frame {
-            Address(
-                OLD_STREET,
-                OLD_CITY
-            )
-        }
-        speculate()
-        address.street = NEW_STREET
-        val speculation = suspend()
-        frame {
-            Assert.assertEquals(OLD_STREET, address.street)
-        }
-        restore(speculation)
-        Assert.assertEquals(NEW_STREET, address.street)
-        abortHandler()
-        frame {
-            Assert.assertEquals(OLD_STREET, address.street)
-        }
-    }
-
-    fun testReuseSpeculation() {
-        val address = frame {
-            Address(
-                OLD_STREET,
-                OLD_CITY
-            )
-        }
-        Assert.assertEquals(1, address.firstFrameRecord.length)
-        speculation { address.street = NEW_STREET }
-        Assert.assertEquals(2, address.firstFrameRecord.length)
-        frame { address.street = "other street" }
-        Assert.assertEquals(2, address.firstFrameRecord.length)
-    }
-
-    fun testCommitAbortInteraction() {
-        val address = frame {
-            Address(
-                OLD_STREET,
-                OLD_CITY
-            )
-        }
-        val frame1 = suspended {
-            address.street = "From frame1"
-        }
-        val frame2 = suspended {
-            address.street = "From frame2"
-        }
-
-        // New frames should see the old value
-        frame {
-            Assert.assertEquals(
-                OLD_STREET,
-                address.street
-            )
-        }
-
-        // Aborting frame2 and committing frame1 should result in frame1
-        abortHandler(frame2)
-
-        // New frames should still see the old value
-        frame {
-            Assert.assertEquals(
-                OLD_STREET,
-                address.street
-            )
-        }
-
-        // Commit frame1, new frames should see frame1's value
-        commit(frame1)
-        frame { Assert.assertEquals("From frame1", address.street) }
-    }
-
-    fun testCollisionAB() {
-        val address = frame {
-            Address(
-                OLD_STREET,
-                OLD_CITY
-            )
-        }
-        expectThrow(FrameAborted::class) {
-            val frame1 = suspended {
-                address.street = "From frame1"
-            }
-            val frame2 = suspended {
-                address.street = "From frame2"
-            }
-
-            commit(frame1)
-
-            // This should throw
-            commit(frame2)
-        }
-
-        // New frames should see the value from the committed frame1
-        frame {
-            Assert.assertEquals("From frame1", address.street)
-        }
-    }
-
-    fun testCollisionBA() {
-        val address = frame {
-            Address(
-                OLD_STREET,
-                OLD_CITY
-            )
-        }
-        expectThrow(FrameAborted::class) {
-            val frame1 = suspended {
-                address.street = "From frame1"
-            }
-            val frame2 = suspended {
-                address.street = "From frame2"
-            }
-
-            commit(frame2)
-
-            // This should throw
-            commit(frame1)
-        }
-
-        // New frames should see the value from the committed frame2
-        frame {
-            Assert.assertEquals("From frame2", address.street)
-        }
-    }
-
-    fun testManyChangesInASingleFrame() {
-        val changeCount = 1000
-        val addresses = frame {
-            (0..changeCount).map {
-                Address(
-                    OLD_STREET,
-                    OLD_CITY
-                )
-            }
-        }
-        val frame1 = suspended {
-            for (i in 0..changeCount) {
-                addresses[i].street = "From index $i"
-            }
-            for (i in 0..changeCount) {
-                Assert.assertEquals("From index $i", addresses[i].street)
-            }
-        }
-        frame {
-            for (i in 0..changeCount) {
-                Assert.assertEquals(OLD_STREET, addresses[i].street)
-            }
-        }
-        commit(frame1)
-        frame {
-            for (i in 0..changeCount) {
-                Assert.assertEquals("From index $i", addresses[i].street)
-            }
-        }
-    }
-
-    fun testManySimultaneousFrames() {
-        val frameCount = 1000
-        val frames = ArrayDeque<Frame>()
-        val addresses = frame {
-            (0..frameCount).map {
-                Address(
-                    OLD_STREET,
-                    OLD_CITY
-                )
-            }
-        }
-        for (i in 0..frameCount) {
-            frames.push(suspended { addresses[i].street = "From index $i" })
-        }
-        for (i in 0..frameCount) {
-            commit(frames.remove())
-        }
-        for (i in 0..frameCount) {
-            frame {
-                Assert.assertEquals(
-                    "From index $i",
-                    addresses[i].street
-                )
-            }
-        }
-    }
-
-    fun testRaw() {
-        val count = 1000
-        val addresses = (0..count).map { AddressRaw(OLD_STREET) }
-        for (i in 0..count) {
-            addresses[i].street = "From index $i"
-            Assert.assertEquals("From index $i", addresses[i].street)
-        }
-        for (i in 0..count) {
-            Assert.assertEquals("From index $i", addresses[i].street)
-        }
-    }
-
-    fun testProp() {
-        val count = 10000
-        val addresses = (0..count).map { AddressProp(OLD_STREET) }
-        for (i in 0..count) {
-            addresses[i].street = "From index $i"
-            Assert.assertEquals("From index $i", addresses[i].street)
-        }
-        for (i in 0..count) {
-            Assert.assertEquals("From index $i", addresses[i].street)
-        }
-    }
-
-    fun testFrameObserver_ObserveRead_Single() {
-        val address = frame {
-            Address(
-                OLD_STREET,
-                OLD_CITY
-            )
-        }
-        var read: Address? = null
-        observeFrame({ obj ->
-            read = obj as Address
-        }) {
-            Assert.assertEquals(OLD_STREET, address.street)
-        }
-        Assert.assertEquals(address, read)
-    }
-
-    fun testFrameObserver_addReadObserver_Single() {
-        val address = frame {
-            Address(
-                OLD_STREET,
-                OLD_CITY
-            )
-        }
-        var read: Address? = null
-        var otherRead: Address? = null
-        val frame = open({ obj -> read = obj as Address })
-        try {
-            frame.observeReads({ obj -> otherRead = obj as Address }) {
-                Assert.assertEquals(OLD_STREET, address.street)
-            }
-            Assert.assertEquals(1, frame.readObservers.size)
-        } finally {
-            commitHandler()
-        }
-        Assert.assertEquals(address, read)
-        Assert.assertEquals(address, otherRead)
-    }
-
-    fun testFrameObserver_ObserveCommit_Single() {
-        val address = frame {
-            Address(
-                OLD_STREET,
-                OLD_CITY
-            )
-        }
-        var committed: Set<Any>? = null
-        observeCommit({ framed: Set<Any> -> committed = framed }) {
-            frame {
-                address.street = NEW_STREET
-            }
-        }
-        Assert.assertTrue(committed?.contains(address) ?: false)
-    }
-
-    fun testFrameObserver_OberveRead_Multiple() {
-        val addressToRead = frame {
-            List(100) {
-                Address(
-                    OLD_STREET,
-                    OLD_CITY
-                )
-            }
-        }
-        val addressToIgnore = frame {
-            List(100) {
-                Address(
-                    OLD_STREET,
-                    OLD_CITY
-                )
-            }
-        }
-        val readAddresses = HashSet<Address>()
-        observeFrame({ obj -> readAddresses.add(obj as Address) }) {
-            for (address in addressToRead) {
-                Assert.assertEquals(OLD_STREET, address.street)
-            }
-        }
-        for (address in addressToRead) {
-            Assert.assertTrue(
-                "Ensure a read callback was called for the address",
-                readAddresses.contains(address)
-            )
-        }
-        for (address in addressToIgnore) {
-            Assert.assertFalse(
-                "Ensure a read callback was not called for the address",
-                readAddresses.contains(address)
-            )
-        }
-    }
-
-    fun testFrameObserver_ObserveCommit_Multiple() {
-        val addressToWrite = frame {
-            List(100) {
-                Address(
-                    OLD_STREET,
-                    OLD_CITY
-                )
-            }
-        }
-        val addressToIgnore = frame {
-            List(100) {
-                Address(
-                    OLD_STREET,
-                    OLD_CITY
-                )
-            }
-        }
-        var committedAddresses = null as Set<Any>?
-        observeCommit({ framed -> committedAddresses = framed }) {
-            frame {
-                for (address in addressToWrite) {
-                    address.street = NEW_STREET
-                }
-            }
-        }
-        for (address in addressToWrite) {
-            Assert.assertTrue(
-                "Ensure written address is in the set of committed objects",
-                committedAddresses?.contains(address) ?: false
-            )
-        }
-        for (address in addressToIgnore) {
-            Assert.assertFalse(
-                "Ensure ignored addresses are not in the set of committed objects",
-                committedAddresses?.contains(address) ?: false
-            )
-        }
-    }
-
-    fun testModelList_Isolated() {
-        val addresses = frame {
-            modelListOf(*(Array(100) {
-                Address(
-                    OLD_STREET,
-                    OLD_CITY
-                )
-            }))
-        }
-
-        fun validateOriginal() {
-            assertFalse(wasModified(addresses))
-            assertEquals(100, addresses.size)
-
-            // Iterate list
-            for (address in addresses) {
-                Assert.assertEquals(OLD_STREET, address.street)
-            }
-            assertFalse(wasModified(addresses))
-        }
-
-        fun validateNew() {
-            assertEquals(101, addresses.size)
-
-            // Iterate list
-            for (i in 0 until 100) {
-                Assert.assertEquals(OLD_STREET, addresses[i].street)
-            }
-
-            Assert.assertEquals(NEW_STREET, addresses[100].street)
-        }
-
-        frame { validateOriginal() }
-
-        val frame1 = suspended {
-            // Insert into the list
-            addresses.add(
-                Address(
-                    NEW_STREET,
-                    NEW_CITY
-                )
-            )
-
-            validateNew()
-        }
-
-        frame { validateOriginal() }
-
-        restored(frame1) {
-            validateNew()
-        }
-    }
-
-    fun testModelList_ReadDoesNotModify() {
-        val count = 10
-        val addresses = frame {
-            modelListOf(*(Array(count) {
-                Address(
-                    OLD_STREET,
-                    OLD_CITY
-                )
-            }))
-        }
-
-        // size should not modify
-        frame {
-            assertEquals(count, addresses.size)
-            assertFalse(wasModified(addresses))
-        }
-
-        // get should not modify
-        frame {
-            val address = addresses[0]
-            assertEquals(OLD_STREET, address.street)
-            assertFalse(wasModified(addresses))
-            assertFalse(wasModified(address))
-        }
-
-        // Iteration should not modify
-        frame {
-            for (address in addresses) {
-                assertEquals(OLD_STREET, address.street)
-                assertFalse(wasModified(address))
-            }
-            assertFalse(wasModified(addresses))
-        }
-
-        // contains should not modify
-        frame {
-            val address = addresses[1]
-            assertTrue(addresses.contains(address))
-            assertFalse(wasModified(addresses))
-        }
-
-        // containsAll should not modify
-        frame {
-            val sublist = listOf(addresses[1], addresses[2])
-            assertTrue(addresses.containsAll(sublist))
-            assertFalse(wasModified(addresses))
-        }
-
-        // indexOf of should not modify
-        frame {
-            val address = addresses[5]
-            assertEquals(5, addresses.indexOf(address))
-            assertFalse(wasModified(addresses))
-        }
-
-        // IsEmpty should not modify
-        frame {
-            assertFalse(addresses.isEmpty())
-            assertTrue(addresses.isNotEmpty())
-            assertFalse(wasModified(addresses))
-        }
-
-        // lastIndexOf should not modify
-        frame {
-            val address = addresses[5]
-            assertEquals(5, addresses.lastIndexOf(address))
-            assertFalse(wasModified(addresses))
-        }
-
-        // listIterator should not modify
-        frame {
-            for (address in addresses.listIterator()) {
-                assertEquals(OLD_STREET, address.street)
-            }
-            assertFalse(wasModified(addresses))
-            for (address in addresses.listIterator(5)) {
-                assertEquals(OLD_STREET, address.street)
-            }
-            assertFalse(wasModified(addresses))
-        }
-    }
-
-    fun testModelList_MutateThrows() {
-        val count = 10
-        val addresses = frame {
-            modelListOf(*(Array(count) {
-                Address(
-                    OLD_STREET,
-                    OLD_CITY
-                )
-            }))
-        }
-
-        // Expect iterator.remove to throw
-        frame {
-            val iterator = addresses.iterator()
-            assertTrue(iterator.hasNext())
-            iterator.next()
-            expectError {
-                iterator.remove()
-            }
-            assertFalse(wasModified(addresses))
-        }
-
-        // Expect listIterator.remove to throw
-        frame {
-            val iterator = addresses.listIterator()
-            assertTrue(iterator.hasNext())
-            iterator.next()
-            expectError {
-                iterator.remove()
-            }
-            assertFalse(wasModified(addresses))
-        }
-
-        // Expect listIterator.set to throw
-        frame {
-            val iterator = addresses.listIterator()
-            assertTrue(iterator.hasNext())
-            iterator.next()
-            expectError {
-                iterator.set(
-                    Address(
-                        NEW_STREET,
-                        NEW_CITY
-                    )
-                )
-            }
-            assertFalse(wasModified(addresses))
-        }
-
-        // Expect listIterator.add to throw
-        frame {
-            val iterator = addresses.listIterator()
-            assertTrue(iterator.hasNext())
-            iterator.next()
-            expectError {
-                iterator.add(
-                    Address(
-                        NEW_STREET,
-                        NEW_CITY
-                    )
-                )
-            }
-            assertFalse(wasModified(addresses))
-        }
-    }
-
-    fun testModelList_MutatingModifies() {
-        val count = 10
-        val addresses = frame {
-            modelListOf(*(Array(count) {
-                Address(
-                    OLD_STREET,
-                    OLD_CITY
-                )
-            }))
-        }
-
-        fun validate(block: () -> Unit) {
-            aborted {
-                assertFalse(wasModified(addresses))
-                block()
-                assertTrue(wasModified(addresses))
-            }
-            frame {
-                assertEquals(addresses.size, count)
-                for (address in addresses) {
-                    assertEquals(address.street, OLD_STREET)
-                    assertEquals(address.city, OLD_CITY)
-                }
-            }
-        }
-
-        // Expect add to modify
-        validate { addresses.add(
-            Address(
-                NEW_STREET,
-                OLD_CITY
-            )
-        ) }
-        validate { addresses.add(5,
-            Address(
-                NEW_STREET,
-                OLD_CITY
-            )
-        ) }
-
-        // Expect addAll to modify
-        validate {
-            addresses.addAll(listOf(
-                Address(
-                    NEW_STREET,
-                    NEW_CITY
-                ),
-                Address(
-                    NEW_STREET,
-                    NEW_CITY
-                )
-            ))
-        }
-        validate {
-            addresses.addAll(
-                5,
-                listOf(
-                    Address(
-                        NEW_STREET,
-                        NEW_CITY
-                    ),
-                    Address(
-                        NEW_STREET,
-                        NEW_CITY
-                    )
-                )
-            )
-        }
-
-        // Expect clear to modify
-        validate { addresses.clear() }
-
-        // Expect remove to modify
-        validate {
-            val address = addresses[5]
-            addresses.remove(address)
-        }
-
-        // Expect removeAll to modify
-        validate { addresses.removeAll(listOf(addresses[5], addresses[6])) }
-
-        // Expect removeAt to modify
-        validate { addresses.removeAt(5) }
-
-        // Expect retainAll to modify
-        validate { addresses.retainAll(listOf(addresses[5], addresses[6])) }
-
-        // Expect set to modify
-        validate { addresses[5] = Address(
-            NEW_STREET,
-            NEW_CITY
-        )
-        }
-
-        // Expect subList to modify
-        validate { addresses.subList(5, 6) }
-
-        // Expecte asMutable to modify
-        validate { addresses.asMutable() }
-    }
-
-    fun testModelMap_Isolated() {
-        val map = frame {
-            modelMapOf(
-                1 to "a",
-                2 to "b",
-                3 to "c",
-                4 to "d"
-            )
-        }
-
-        fun validateOld() {
-            assertEquals(4, map.size)
-            assertTrue(map.contains(1))
-            assertTrue(map.contains(2))
-            assertTrue(map.contains(3))
-            assertTrue(map.contains(4))
-            assertEquals(map[1], "a")
-            assertEquals(map[2], "b")
-            assertEquals(map[3], "c")
-            assertEquals(map[4], "d")
-        }
-
-        fun validateNew() {
-            assertEquals(5, map.size)
-            assertTrue(map.contains(1))
-            assertTrue(map.contains(2))
-            assertTrue(map.contains(3))
-            assertTrue(map.contains(4))
-            assertTrue(map.contains(5))
-            assertEquals(map[1], "a")
-            assertEquals(map[2], "b")
-            assertEquals(map[3], "c")
-            assertEquals(map[4], "d")
-            assertEquals(map[5], "e")
-        }
-
-        frame { validateOld() }
-
-        val frame1 = suspended {
-            validateOld()
-
-            map[5] = "e"
-
-            validateNew()
-        }
-
-        frame { validateOld() }
-        restored(frame1) { validateNew() }
-        frame { validateNew() }
-    }
-
-    @Suppress("USELESS_IS_CHECK")
-    fun testModelMap_ReadingDoesntModify() {
-        val map = frame {
-            modelMapOf(
-                1 to "a",
-                2 to "b",
-                3 to "c",
-                4 to "d"
-            )
-        }
-
-        fun validateOld() {
-            assertEquals(4, map.size)
-            assertTrue(map.contains(1))
-            assertTrue(map.contains(2))
-            assertTrue(map.contains(3))
-            assertTrue(map.contains(4))
-            assertEquals(map[1], "a")
-            assertEquals(map[2], "b")
-            assertEquals(map[3], "c")
-            assertEquals(map[4], "d")
-        }
-
-        fun validate(block: () -> Unit) {
-            frame {
-                validateOld()
-                block()
-                assertFalse(wasModified(map))
-                validateOld()
-            }
-        }
-
-        // size should not modify
-        validate { assertEquals(4, map.size) }
-
-        // contains should not modify
-        validate { assertTrue(map.contains(1)) }
-
-        // containsKey should not modify
-        validate { assertTrue(map.containsKey(1)) }
-
-        // containsValue should not modify
-        validate { assertTrue(map.containsValue("a")) }
-
-        // get should not modify
-        validate { assertEquals("a", map[1]) }
-
-        // isEmpty should not modify
-        validate { assertFalse(map.isEmpty()) }
-        validate { assertTrue(map.isNotEmpty()) }
-
-        // iterating entries should not modify
-        validate {
-            for (entry in map) {
-                assertTrue(entry.value is String)
-                assertTrue(entry.key is Int)
-            }
-            for (entry in map.entries) {
-                assertTrue(entry.value is String)
-                assertTrue(entry.key is Int)
-            }
-        }
-
-        // iterating keys should not modify
-        validate {
-            for (key in map.keys) {
-                assertTrue(key is Int)
-            }
-        }
-
-        // iterating values should not modify
-        validate {
-            for (value in map.values) {
-                assertTrue(value is String)
-            }
-        }
-    }
-
-    fun testModelMap_Mutation() {
-        val map = frame {
-            modelMapOf(
-                1 to "a",
-                2 to "b",
-                3 to "c",
-                4 to "d"
-            )
-        }
-
-        fun validateOld() {
-            assertEquals(4, map.size)
-            assertTrue(map.contains(1))
-            assertTrue(map.contains(2))
-            assertTrue(map.contains(3))
-            assertTrue(map.contains(4))
-            assertEquals(map[1], "a")
-            assertEquals(map[2], "b")
-            assertEquals(map[3], "c")
-            assertEquals(map[4], "d")
-        }
-
-        fun validate(block: () -> Unit) {
-            aborted {
-                assertFalse(wasModified(map))
-                validateOld()
-                block()
-                assertTrue(wasModified(map))
-            }
-        }
-
-        // clear should modify
-        validate { map.clear() }
-
-        // put should modify
-        validate { map[5] = "e" }
-
-        // putAll should modify
-        validate { map.putAll(mapOf(5 to "e", 6 to "f")) }
-
-        // remove should modify
-        validate { map.remove(3) }
-    }
-
-    fun testModelMap_MutateThrows() {
-        val map = frame {
-            modelMapOf(
-                1 to "a",
-                2 to "b",
-                3 to "c",
-                4 to "d"
-            )
-        }
-
-        fun validateOld() {
-            assertEquals(4, map.size)
-            assertTrue(map.contains(1))
-            assertTrue(map.contains(2))
-            assertTrue(map.contains(3))
-            assertTrue(map.contains(4))
-            assertEquals(map[1], "a")
-            assertEquals(map[2], "b")
-            assertEquals(map[3], "c")
-            assertEquals(map[4], "d")
-        }
-
-        fun validate(block: () -> Unit) {
-            frame {
-                assertFalse(wasModified(map))
-                validateOld()
-                expectError {
-                    block()
-                }
-                assertFalse(wasModified(map))
-            }
-        }
-
-        // Expect mutating through entries to throw
-        validate { map.entries.add(map.entries.first()) }
-        validate {
-            map.entries.addAll(listOf(map.entries.first(), map.entries.drop(1).first()))
-        }
-        validate { map.entries.clear() }
-        validate { map.entries.remove(map.entries.first()) }
-        validate {
-            map.entries.removeAll(listOf(map.entries.first(), map.entries.drop(1).first()))
-        }
-        validate {
-            map.entries.retainAll(listOf(map.entries.first(), map.entries.drop(1).first()))
-        }
-        validate {
-            val iterator = map.entries.iterator()
-            iterator.next()
-            iterator.remove()
-        }
-
-        // Expect mutating through keys to throw
-        validate { map.keys.add(map.keys.first()) }
-        validate { map.keys.addAll(listOf(map.keys.first(), map.keys.drop(1).first())) }
-        validate { map.keys.clear() }
-        validate { map.keys.remove(map.keys.first()) }
-        validate { map.keys.removeAll(listOf(map.keys.first(), map.keys.drop(1).first())) }
-        validate { map.keys.retainAll(listOf(map.keys.first(), map.keys.drop(1).first())) }
-        validate {
-            val iterator = map.keys.iterator()
-            iterator.next()
-            iterator.remove()
-        }
-
-        // Expect mutating through values to throw
-        validate { map.values.add(map.values.first()) }
-        validate { map.values.addAll(listOf(map.values.first(), map.values.drop(1).first())) }
-        validate { map.values.clear() }
-        validate { map.values.remove(map.values.first()) }
-        validate {
-            map.values.removeAll(listOf(map.values.first(), map.values.drop(1).first()))
-        }
-        validate {
-            map.values.retainAll(listOf(map.values.first(), map.values.drop(1).first()))
-        }
-        validate {
-            val iterator = map.values.iterator()
-            iterator.next()
-            iterator.remove()
-        }
-    }
-}
-
-fun expectError(block: () -> Unit) {
-    var thrown = false
-    try {
-        block()
-    } catch (e: IllegalStateException) {
-        thrown = true
-    }
-    Assert.assertTrue(thrown)
-}
-
-// Helpers for the above tests
-
-inline fun <T> frame(crossinline block: () -> T): T {
-    open(false)
-    try {
-        return block()
-    } catch (e: Exception) {
-        abortHandler()
-        throw e
-    } finally {
-        commitHandler()
-    }
-}
-
-inline fun <T> observeFrame(noinline observer: FrameReadObserver, crossinline block: () -> T): T {
-    open(observer)
-    try {
-        return block()
-    } catch (e: Exception) {
-        abortHandler()
-        throw e
-    } finally {
-        commitHandler()
-    }
-}
-
-inline fun <T> observeCommit(
-    noinline observer: FrameCommitObserver,
-    crossinline block: () -> T
-): T {
-    val unregister = registerCommitObserver(observer)
-    try {
-        return block()
-    } finally {
-        unregister()
-    }
-}
-
-inline fun suspended(crossinline block: () -> Unit): Frame {
-    open(false)
-    try {
-        block()
-        return suspend()
-    } catch (e: Exception) {
-        abortHandler()
-        throw e
-    }
-}
-
-inline fun <T> restored(frame: Frame, crossinline block: () -> T): T {
-    restore(frame)
-    try {
-        return block()
-    } catch (e: Exception) {
-        abortHandler()
-        throw e
-    } finally {
-        commitHandler()
-    }
-}
-
-inline fun aborted(crossinline block: () -> Unit) {
-    open(false)
-    try {
-        block()
-    } finally {
-        abortHandler()
-    }
-}
-
-inline fun speculation(crossinline block: () -> Unit) {
-    speculate()
-    try {
-        block()
-    } finally {
-        abortHandler()
-    }
-}
-
-inline fun <reified T : Throwable> expectThrow(
-    @Suppress("UNUSED_PARAMETER") e: KClass<T>,
-    crossinline block: () -> Unit
-) {
-    var thrown = false
-    try {
-        block()
-    } catch (e: Throwable) {
-        Assert.assertTrue(e is T)
-        thrown = true
-    }
-    Assert.assertTrue(thrown)
-}
-
-val Record.length: Int
-    get() {
-        var current: Record? = this
-        var len = 0
-        while (current != null) {
-            len++
-            current = current.next
-        }
-        return len
-    }
-
-class AddressRaw(var street: String)
-
-class AddressProp(streetValue: String) {
-    var _street = streetValue
-
-    var street: String
-        get() = _street
-        set(value) { _street = value }
-}
diff --git a/compose/compose-runtime/integration-tests/android-tests/src/main/AndroidManifest.xml b/compose/compose-runtime/integration-tests/android-tests/src/main/AndroidManifest.xml
deleted file mode 100644
index 50d6c6b3..0000000
--- a/compose/compose-runtime/integration-tests/android-tests/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright 2019 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
-        package="androidx.compose.integrationtests.androidtests" xmlns:android="http://schemas.android.com/apk/res/android">
-    <application/>
-</manifest>
diff --git a/compose/compose-runtime/integration-tests/build.gradle b/compose/compose-runtime/integration-tests/build.gradle
deleted file mode 100644
index 122416d..0000000
--- a/compose/compose-runtime/integration-tests/build.gradle
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2019 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 org.jetbrains.kotlin.codegen.ImplementationBodyCodegen
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-
-import static androidx.build.dependencies.DependenciesKt.*
-import androidx.build.LibraryGroups
-import androidx.build.LibraryVersions
-import androidx.build.Publish
-
-plugins {
-    id("AndroidXPlugin")
-    id("com.android.library")
-    id("kotlin-android")
-}
-
-dependencies {
-    implementation(project(":compose:compose-runtime"))
-    implementation(KOTLIN_COMPOSE_STDLIB)
-
-    implementation(JUNIT)
-}
-
-android {
-    defaultConfig {
-        minSdkVersion 18
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-runtime/integration-tests/src/main/AndroidManifest.xml b/compose/compose-runtime/integration-tests/src/main/AndroidManifest.xml
deleted file mode 100644
index 50d6c6b3..0000000
--- a/compose/compose-runtime/integration-tests/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright 2019 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
-        package="androidx.compose.integrationtests.androidtests" xmlns:android="http://schemas.android.com/apk/res/android">
-    <application/>
-</manifest>
diff --git a/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/frames/Address.kt b/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/frames/Address.kt
deleted file mode 100644
index 630c157..0000000
--- a/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/frames/Address.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package androidx.compose.frames
-
-class Address(street: String, city: String) : Framed {
-    var street: String
-        get() = next.readable(this).street
-        set(value) { next.writable(this).street = value }
-
-    var city: String
-        get() = next.readable(this).city
-        set(value) { next.writable(this).city = value }
-
-    private var next: AddressRecord
-
-    init {
-        next = AddressRecord()
-        next.street = street
-        next.city = city
-    }
-
-    override fun prependFrameRecord(value: Record) {
-        value.next = next
-        next = value as AddressRecord
-    }
-
-    override val firstFrameRecord: AddressRecord get() = next
-}
-
-class AddressRecord : AbstractRecord() {
-    var street: String = ""
-    var city: String = ""
-
-    override fun create(): Record = AddressRecord()
-    override fun assign(value: Record) {
-        val other = value as AddressRecord
-        street = other.street
-        city = other.city
-    }
-}
diff --git a/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/MockViewValidator.kt b/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/MockViewValidator.kt
deleted file mode 100644
index 6d3377d..0000000
--- a/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/MockViewValidator.kt
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2019 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.mock
-
-import org.junit.Assert
-
-interface MockViewValidator {
-    val view: View
-    fun next(): Boolean
-}
-
-class MockViewListValidator(private val views: List<View>) :
-    MockViewValidator {
-    override lateinit var view: View
-
-    override fun next(): Boolean {
-        if (iterator.hasNext()) {
-            view = iterator.next()
-            return true
-        }
-        return false
-    }
-
-    private val iterator by lazy { views.iterator() }
-
-    fun validate(block: (MockViewValidator.() -> Unit)?) {
-        if (block != null) {
-            this.block()
-            val hasNext = next()
-            Assert.assertEquals("Expected children but none found", false, hasNext)
-        } else {
-            Assert.assertEquals("Not expecting children but some found", 0, views.size)
-        }
-    }
-}
-
-fun MockViewValidator.view(name: String, block: (MockViewValidator.() -> Unit)? = null) {
-    val hasNext = next()
-    Assert.assertEquals(true, hasNext)
-    Assert.assertEquals(name, view.name)
-    MockViewListValidator(view.children).validate(block)
-}
-
-fun <T> MockViewValidator.repeat(of: Iterable<T>, block: MockViewValidator.(value: T) -> Unit) {
-    for (value in of) {
-        block(value)
-    }
-}
-
-fun MockViewValidator.linear() = view("linear", null)
-fun MockViewValidator.linear(block: MockViewValidator.() -> Unit) = view("linear", block)
-fun MockViewValidator.box(block: MockViewValidator.() -> Unit) = view("box", block)
-fun MockViewValidator.text(value: String) {
-    view("text")
-    Assert.assertEquals(value, view.attributes["text"])
-}
-fun MockViewValidator.edit(value: String) {
-    view("edit")
-    Assert.assertEquals(value, view.attributes["value"])
-}
-
-fun MockViewValidator.selectBox(selected: Boolean, block: MockViewValidator.() -> Unit) {
-    if (selected) {
-        box {
-            block()
-        }
-    } else {
-        block()
-    }
-}
-
-fun MockViewValidator.skip(times: Int = 1) {
-    repeat(times) {
-        val hasNext = next()
-        Assert.assertEquals(true, hasNext)
-    }
-}
-
-fun validate(root: View, block: MockViewValidator.() -> Unit) {
-    MockViewListValidator(root.children).validate(block)
-}
diff --git a/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/ViewComposer.kt b/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/ViewComposer.kt
deleted file mode 100644
index e60ef68..0000000
--- a/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/ViewComposer.kt
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright 2019 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.mock
-
-import androidx.compose.Applier
-import androidx.compose.ApplyAdapter
-import androidx.compose.Composer
-import androidx.compose.Composition
-import androidx.compose.Recomposer
-import androidx.compose.SlotTable
-import androidx.compose.cache
-import androidx.compose.changed
-import androidx.compose.remember
-
-interface MockViewComposition {
-    val cc: Composition<View>
-}
-
-abstract class ViewComponent : MockViewComposition {
-    private var recomposer: ((sync: Boolean) -> Unit)? = null
-    private lateinit var _composition: Composition<View>
-    @PublishedApi
-    internal fun setComposition(value: Composition<View>) {
-        _composition = value
-    }
-
-    override val cc: Composition<View> get() = _composition
-
-    fun recompose() {
-        recomposer?.let { it(false) }
-    }
-
-    operator fun invoke() {
-        val cc = cc as MockViewComposer
-        val callback = cc.startJoin(false) { compose() }
-        compose()
-        cc.doneJoin(false)
-        recomposer = callback
-    }
-
-    abstract fun compose()
-}
-
-typealias Compose = MockViewComposition.() -> Unit
-
-@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
-object ViewApplierAdapter :
-    ApplyAdapter<View> {
-    override fun View.start(instance: View) {}
-    override fun View.insertAt(index: Int, instance: View) = addAt(index, instance)
-    override fun View.removeAt(index: Int, count: Int) = removeAt(index, count)
-    override fun View.move(from: Int, to: Int, count: Int) = moveAt(from, to, count)
-    override fun View.end(instance: View, parent: View) {}
-}
-
-class MockViewComposer(
-    val root: View
-) : Composer<View>(
-    SlotTable(),
-    Applier(root, ViewApplierAdapter), object : Recomposer() {
-        override fun scheduleChangesDispatch() {
-        }
-
-        override fun hasPendingChanges(): Boolean = false
-    }) {
-    private val rootComposer: MockViewComposition by lazy {
-        object : MockViewComposition {
-            override val cc: Composition<View> get() = this@MockViewComposer
-        }
-    }
-
-    fun compose(composition: MockViewComposition.() -> Unit) {
-        composeRoot {
-            rootComposer.composition()
-        }
-    }
-}
-
-/* inline */ fun <N, /* reified */ V> Composition<N>.applyNeeded(value: V): Boolean =
-    changed(value) && !inserting
-
-@Suppress("NOTHING_TO_INLINE")
-inline fun <V> MockViewComposition.remember(
-    /*crossinline*/
-    noinline block: () -> V
-): V = cc.remember(block)
-
-inline fun <V, reified P1> MockViewComposition.remember(
-    p1: P1,
-    /*crossinline*/
-    noinline block: () -> V
-) = cc.remember(p1, block)
-
-inline fun <V, reified P1, reified P2> MockViewComposition.remember(
-    p1: P1,
-    p2: P2,
-    /*crossinline*/
-    noinline block: () -> V
-) = cc.remember(p1, p2, block)
-
-inline fun <V, reified P1, reified P2, reified P3> MockViewComposition.remember(
-    p1: P1,
-    p2: P2,
-    p3: P3,
-    /*crossinline*/
-    noinline block: () -> V
-) = cc.remember(p1, p2, p3, block)
-
-inline fun <V, reified P1, reified P2, reified P3, reified P4> MockViewComposition.remember(
-    p1: P1,
-    p2: P2,
-    p3: P3,
-    p4: P4,
-    /*crossinline*/
-    noinline block: () -> V
-) = cc.remember(p1, p2, p3, p4, block)
-
-@Suppress("NOTHING_TO_INLINE")
-inline fun <V> MockViewComposition.remember(
-    vararg args: Any,
-    /*crossinline*/
-    noinline block: () -> V
-): V = cc.remember(*args, block = block)
-
-inline fun <reified P1> MockViewComposition.memoize(
-    key: Any,
-    p1: P1,
-    block: MockViewComposition.(p1: P1) -> Unit
-) {
-    cc.startGroup(key)
-    if (!cc.changed(p1)) {
-        cc.nextSlot()
-        cc.skipValue()
-        cc.skipGroup()
-    } else {
-        cc.startGroup(key)
-        block(p1)
-        cc.endGroup()
-    }
-    cc.endGroup()
-}
-
-inline fun <V : View> MockViewComposition.emit(
-    key: Any,
-    noinline factory: () -> V,
-    block: MockViewComposition.() -> Unit
-) {
-    cc.startNode(key)
-    cc.emitNode(factory)
-    block()
-    cc.endNode()
-}
-
-inline fun <V : View, reified A1> MockViewComposition.emit(
-    key: Any,
-    noinline factory: () -> V,
-    a1: A1,
-    noinline set1: V.(A1) -> Unit
-) {
-    cc.startNode(key)
-    cc.emitNode(factory)
-    if (cc.changed(a1)) {
-        cc.apply(a1, set1)
-    }
-    cc.endNode()
-}
-
-val invocation = Object()
-
-inline fun MockViewComposition.call(
-    key: Any,
-    invalid: Composition<View>.() -> Boolean,
-    block: () -> Unit
-) = with(cc) {
-    startGroup(key)
-    if (invalid() || inserting) {
-        startGroup(invocation)
-        block()
-        endGroup()
-    } else {
-        (cc as Composer<*>).skipGroup(invocation)
-    }
-    endGroup()
-}
-
-inline fun <T : ViewComponent> MockViewComposition.call(
-    key: Any,
-    ctor: () -> T,
-    invalid: ComponentUpdater<T>.() -> Unit,
-    block: (f: T) -> Unit
-) = with(cc) {
-    startGroup(key)
-    val f = cache(true, ctor).apply { setComposition(this@with) }
-    val updater = object : ComponentUpdater<T> {
-        override val cc: Composition<View> = this@with
-        override var changed: Boolean = false
-        override val component = f
-    }
-    updater.invalid()
-    if (updater.changed || inserting) {
-        startGroup(invocation)
-        block(f)
-        endGroup()
-    } else {
-        nextSlot()
-        skipValue()
-        skipGroup()
-    }
-    endGroup()
-}
-
-fun MockViewComposition.join(
-    key: Any,
-    block: (invalidate: (sync: Boolean) -> Unit) -> Unit
-) {
-    val myCC = cc as MockViewComposer
-    myCC.startGroup(key)
-    val invalidate = myCC.startJoin(false, block)
-    block(invalidate)
-    myCC.doneJoin(false)
-    myCC.endGroup()
-}
-
-interface ComponentUpdater<C> : MockViewComposition {
-    val component: C
-    var changed: Boolean
-}
-
-inline fun <C, reified V> ComponentUpdater<C>.set(value: V, noinline block: C.(V) -> Unit) {
-    if (cc.changed(value)) {
-        cc.apply<V, C>(value) { component.block(it) }
-        component.block(value)
-        changed = true
-    }
-}
-
-inline fun <C, reified V> ComponentUpdater<C>.update(value: V, noinline block: C.(V) -> Unit) {
-    if (cc.applyNeeded(value)) {
-        cc.apply<V, C>(value) { component.block(it) }
-        component.block(value)
-        changed = true
-    }
-}
diff --git a/compose/compose-runtime/src/androidAndroidTest/AndroidManifest.xml b/compose/compose-runtime/src/androidAndroidTest/AndroidManifest.xml
new file mode 100644
index 0000000..1cb1e26
--- /dev/null
+++ b/compose/compose-runtime/src/androidAndroidTest/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2019 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.compose">
+     <application>
+          <activity
+              android:name="androidx.compose.TestActivity"/>
+          <activity
+              android:name="androidx.compose.DisposeTests$DisposeTestActivity"/>
+     </application>
+</manifest>
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposeIntoTests.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposeIntoTests.kt
new file mode 100644
index 0000000..c0666fd
--- /dev/null
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposeIntoTests.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2019 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
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.rule.ActivityTestRule
+import org.junit.Assert.assertEquals
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class ComposeIntoTests {
+
+    @get:Rule
+    val activityRule = ActivityTestRule(DisposeTests.DisposeTestActivity::class.java)
+
+    @Test
+    @SmallTest
+    fun testMultipleSetContentCalls() {
+        val activity = activityRule.activity
+
+        var initializationCount = 0
+        var commitCount = 0
+        val composable = @Composable {
+            +onActive { initializationCount++ }
+            +onCommit { commitCount++ }
+        }
+
+        activity.show(composable)
+        activity.waitForAFrame()
+
+        assertEquals(1, initializationCount)
+        assertEquals(1, commitCount)
+
+        activity.show(composable)
+        activity.waitForAFrame()
+
+        // if we call setContent multiple times, we want to ensure that it doesn't tear
+        // down the whole hierarchy, so onActive should only get called once.
+        assertEquals(1, initializationCount)
+        assertEquals(2, commitCount)
+    }
+}
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposeModelTests.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposeModelTests.kt
new file mode 100644
index 0000000..1e359c9
--- /dev/null
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposeModelTests.kt
@@ -0,0 +1,392 @@
+/*
+ * Copyright 2019 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
+
+import android.app.Activity
+import android.widget.TextView
+import androidx.compose.frames.AbstractRecord
+import androidx.compose.frames.Framed
+import androidx.compose.frames.Record
+import androidx.compose.frames._created
+import androidx.compose.frames._readable
+import androidx.compose.frames._writable
+import androidx.compose.frames.commit
+import androidx.compose.frames.currentFrame
+import androidx.compose.frames.inFrame
+import androidx.compose.frames.open
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.rule.ActivityTestRule
+import junit.framework.TestCase.assertEquals
+import junit.framework.TestCase.assertFalse
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+val PRESIDENT_NAME_1 = "George Washington"
+val PRESIDENT_AGE_1 = 57
+val PRESIDENT_NAME_16 = "Abraham Lincoln"
+val PRESIDENT_AGE_16 = 52
+
+class Person(name: String, age: Int) : Framed {
+    var name
+        get() = (_readable(_first, this) as CustomerRecord).name
+        set(value) {
+            (_writable(_first, this) as CustomerRecord).name = value
+        }
+
+    var age
+        get() = (_readable(_first, this) as CustomerRecord).age
+        set(value) {
+            (_writable(_first, this) as CustomerRecord).age = value
+        }
+
+    private var _first: Record = CustomerRecord().apply {
+        this.name = name
+        this.age = age
+        this.frameId = currentFrame().id
+        _created(this@Person)
+    }
+
+    override val firstFrameRecord: Record get() = _first
+
+    override fun prependFrameRecord(value: Record) {
+        value.next = _first
+        _first = value
+    }
+
+    class CustomerRecord : AbstractRecord() {
+        @JvmField
+        var name: String = ""
+        @JvmField
+        var age: Int = 0
+
+        override fun assign(value: Record) {
+            (value as? CustomerRecord)?.let {
+                this.name = it.name
+                this.age = it.age
+            }
+        }
+
+        override fun create() = CustomerRecord()
+    }
+}
+
+class TestState<T>(value: T) : Framed {
+    @Suppress("UNCHECKED_CAST")
+    var value: T
+        get() = (_readable(myFirst, this) as StateRecord<T>).value
+        set(value) {
+            (_writable(myFirst, this) as StateRecord<T>).value = value
+        }
+
+    private var myFirst: Record
+
+    init {
+        myFirst = StateRecord(value)
+    }
+
+    override val firstFrameRecord: Record
+        get() = myFirst
+
+    override fun prependFrameRecord(value: Record) {
+        value.next = myFirst
+        myFirst = value
+    }
+
+    private class StateRecord<T>(myValue: T) : AbstractRecord() {
+        override fun assign(value: Record) {
+            @Suppress("UNCHECKED_CAST")
+            this.value = (value as StateRecord<T>).value
+        }
+
+        override fun create(): Record = StateRecord(value)
+
+        var value: T = myValue
+    }
+}
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ModelViewTests {
+
+    @get:Rule
+    val activityRule = ActivityTestRule(TestActivity::class.java)
+
+    @Test
+    fun testModelView_Simple() {
+        val tvId = 67
+        compose {
+            emit(62, { context ->
+                TextView(context).apply {
+                    text = "Hello world!"; id = tvId
+                }
+            }) { }
+        }.then { activity ->
+            val tv = activity.root.findViewById(tvId) as TextView
+            assertEquals("Hello world!", tv.text)
+        }
+    }
+
+    @Test
+    fun testModelView_Simple_Recompose() {
+        val tvId = 71
+        compose {
+            emit(73, { context ->
+                TextView(context).apply {
+                    text = "Hello world!"; id = tvId
+                }
+            }) { }
+        }.then { activity ->
+            val tv = activity.root.findViewById(tvId) as TextView
+            assertEquals("Hello world!", tv.text)
+        }.then { activity ->
+            val tv = activity.root.findViewById(tvId) as TextView
+            assertEquals("Hello world!", tv.text)
+        }
+    }
+
+    @Test
+    fun testModelView_PersonModel() {
+        val tvIdName = 90
+        val tvIdAge = 91
+        val president = frame {
+            Person(
+                PRESIDENT_NAME_1,
+                PRESIDENT_AGE_1
+            )
+        }
+
+        @Suppress("PLUGIN_WARNING")
+        compose {
+            call(147, { true }) {
+
+                (Observe {
+                    emit(93, { context -> TextView(context).apply { id = tvIdName } }) {
+                        set(president.name) { text = it }
+                    }
+                    emit(94, { context -> TextView(context).apply { id = tvIdAge } }) {
+                        set(president.age) { text = it.toString() }
+                    }
+                })
+            }
+        }.then {
+            val tvName = it.findViewById(tvIdName) as TextView
+            val tvAge = it.findViewById(tvIdAge) as TextView
+            assertEquals(PRESIDENT_NAME_1, tvName.text)
+            assertEquals(PRESIDENT_AGE_1.toString(), tvAge.text)
+
+            president.name = PRESIDENT_NAME_16
+            president.age = PRESIDENT_AGE_16
+        }.then {
+            val tvName = it.findViewById(tvIdName) as TextView
+            val tvAge = it.findViewById(tvIdAge) as TextView
+            assertEquals(PRESIDENT_NAME_16, tvName.text)
+            assertEquals(PRESIDENT_AGE_16.toString(), tvAge.text)
+        }
+    }
+
+    @Test
+    fun testModelView_RecomposeScopeCleanup() {
+        val washington = frame {
+            Person(
+                PRESIDENT_NAME_1,
+                PRESIDENT_AGE_1
+            )
+        }
+        val lincoln = frame {
+            Person(
+                PRESIDENT_NAME_16,
+                PRESIDENT_AGE_16
+            )
+        }
+        val displayLincoln = frame { TestState(true) }
+
+        @Suppress("PLUGIN_WARNING")
+        fun ViewComposition.display(person: Person) {
+            call(167, { true }) {
+                @Suppress("PLUGIN_ERROR")
+                (Observe {
+        emit(93, { context -> TextView(context) }) {
+            set(person.name) { text = it }
+        }
+        emit(94, { context -> TextView(context) }) {
+            set(person.age) { text = it.toString() }
+        }
+    })
+            }
+        }
+
+        @Suppress("PLUGIN_WARNING")
+        compose {
+            call(185, { true }) {
+                @Suppress("PLUGIN_ERROR")
+                (Observe {
+        display(washington)
+        if (displayLincoln.value)
+            display(lincoln)
+    })
+            }
+        }.then {
+            displayLincoln.value = false
+        }.then {
+            assertFalse(displayLincoln.value)
+        }.then {
+            assertFalse(displayLincoln.value)
+        }
+    }
+
+    // b/122548164
+    @Test
+    @Suppress("PLUGIN_WARNING")
+    fun testObserverEntering() {
+        val president = frame {
+            Person(
+                PRESIDENT_NAME_1,
+                PRESIDENT_AGE_1
+            )
+        }
+        val tvName = 204
+
+        fun ViewComposition.display(person: Person) {
+            call(167, { true }) {
+                (Observe {
+                    emit(93, { context -> TextView(context).apply { id = tvName } }) {
+                        set(person.name) { text = it }
+                    }
+                    emit(94, { context -> TextView(context) }) {
+                        set(person.age) { text = it.toString() }
+                    }
+                })
+                if (person.name == PRESIDENT_NAME_16) {
+                    (Observe {
+                        emit(211, { context -> TextView(context) }) {
+                            set(person.name) { text = it }
+                        }
+                        emit(211, { context -> TextView(context) }) {
+                            set(person.age) { text = it.toString() }
+                        }
+                    })
+                }
+            }
+        }
+
+        compose {
+            call(219, { true }) {
+                (Observe {
+                    display(president)
+                })
+            }
+        }.then { activity ->
+            assertEquals(PRESIDENT_NAME_1, (activity.findViewById(tvName) as TextView).text)
+            president.name = PRESIDENT_NAME_16
+        }.then { activity ->
+            assertEquals(PRESIDENT_NAME_16, (activity.findViewById(tvName) as TextView).text)
+        }
+    }
+
+    @Test
+    @Suppress("PLUGIN_WARNING")
+    fun testModelUpdatesNextFrameVisibility() {
+        val president = frame {
+            Person(
+                PRESIDENT_NAME_1,
+                PRESIDENT_AGE_1
+            )
+        }
+        val tvName = 204
+
+        fun ViewComposition.display(person: Person) {
+            call(167, { true }) {
+                (Observe {
+                    emit(93, { context -> TextView(context).apply { id = tvName } }) {
+                        set(person.name) { text = it }
+                    }
+                    emit(94, { context -> TextView(context) }) {
+                        set(person.age) {
+                            text = it.toString()
+                        }
+                    }
+                })
+                if (person.name == PRESIDENT_NAME_16) {
+                    (Observe {
+                        emit(211, { context -> TextView(context) }) {
+                            set(person.name) { text = it }
+                        }
+                        emit(211, { context -> TextView(context) }) {
+                            set(person.age) { text = it.toString() }
+                        }
+                    })
+                }
+            }
+        }
+
+        compose {
+            call(219, { true }) {
+                (Observe {
+                    display(president)
+                })
+            }
+        }.then { activity ->
+            assertEquals(PRESIDENT_NAME_1, (activity.findViewById(tvName) as TextView).text)
+            // schedule commit and recompose by this change, all for next frame
+            president.name = PRESIDENT_NAME_16
+            // check that changes aren't there yet
+            assertEquals(PRESIDENT_NAME_1, (activity.findViewById(tvName) as TextView).text)
+        }.then { activity ->
+            assertEquals(PRESIDENT_NAME_16, (activity.findViewById(tvName) as TextView).text)
+        }
+    }
+
+    private class Root(val block: ViewComposition.() -> Unit) : Component() {
+        override fun compose() {
+            ViewComposition(composer.composer).block()
+        }
+    }
+
+    fun compose(block: ViewComposition.() -> Unit) =
+        CompositionModelTest(block, activityRule.activity)
+
+    class CompositionModelTest(val composable: ViewComposition.() -> Unit, val activity: Activity) {
+        inner class ActiveTest(val activity: Activity) {
+            fun then(block: (activity: Activity) -> Unit): ActiveTest {
+                activity.waitForAFrame()
+                activity.uiThread {
+                    block(activity)
+                }
+                return this
+            }
+        }
+
+        fun then(block: (activity: Activity) -> Unit): ActiveTest {
+            activity.show {
+                composer.composable()
+            }
+            activity.waitForAFrame()
+            activity.uiThread {
+                block(activity)
+            }
+            return ActiveTest(activity)
+        }
+    }
+}
+
+fun <T> frame(block: () -> T): T {
+    val wasInFrame = inFrame
+    if (!wasInFrame) open()
+    return block().also { if (!wasInFrame) commit() }
+}
\ No newline at end of file
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposerComposeTestCase.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposerComposeTestCase.kt
new file mode 100644
index 0000000..fd80d2e
--- /dev/null
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposerComposeTestCase.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2019 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
+
+import android.app.Activity
+import android.view.ViewGroup
+
+abstract class ComposerComposeTestCase {
+
+    fun compose(
+        activity: Activity,
+        manualRecompose: Boolean,
+        composable: (ViewComposition) -> Unit
+    ) =
+        ComposeTest(
+            Root(composable),
+            manualRecompose,
+            activity
+        )
+
+    class ComposeTest(
+        val component: Component,
+        val manualRecompose: Boolean,
+        val activity: Activity
+    ) {
+        internal lateinit var root: ViewGroup
+        internal lateinit var cc: CompositionContext
+        fun then(fn: (CompositionContext, Component, ViewGroup, Activity) -> Unit): ActiveTest {
+            activity.uiThread {
+                root = activity.findViewById(ROOT_ID) as ViewGroup
+                cc = Compose.createCompositionContext(root.context, root, component, null)
+                cc.compose()
+                fn(cc, component, root, activity)
+            }
+            return ActiveTest()
+        }
+
+        inner class ActiveTest {
+            fun then(fn: (CompositionContext, Component, ViewGroup, Activity) -> Unit): ActiveTest {
+                if (!manualRecompose) {
+                    activity.uiThread {
+                        component.recomposeCallback?.invoke(false)
+                    }
+                }
+                activity.waitForAFrame()
+                activity.uiThread {
+                    fn(cc, component, root, activity)
+                }
+                return this
+            }
+        }
+    }
+
+    private class Root(var composable: (ViewComposition) -> Unit) : Component() {
+        override fun compose() = composable(composer)
+    }
+
+    companion object {
+        val ROOT_ID = 18284847
+    }
+}
+
+class Counter {
+    private var counts = mutableMapOf<String, Int>()
+    fun inc(key: String) = counts.getOrPut(key, { 0 }).let { counts[key] = it + 1 }
+    fun reset() {
+        counts = mutableMapOf()
+    }
+
+    operator fun get(key: String) = counts.getOrDefault(key, 0)
+}
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposerExtensions.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposerExtensions.kt
new file mode 100644
index 0000000..f8d8c8a
--- /dev/null
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposerExtensions.kt
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2019 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
+
+import android.content.Context
+import android.view.View
+import android.view.ViewGroup
+
+inline fun ViewComposition.group(key: Int, block: () -> Unit) {
+    try {
+        composer.startGroup(key)
+        block()
+    } finally {
+        composer.endGroup()
+    }
+}
+
+inline fun <reified T : Component> ViewComposition.emitComponent(
+    loc: Int,
+    ctor: () -> T,
+    noinline block: ViewValidator.(f: T) -> Boolean
+): Unit = emitComponent(loc, null, ctor, block)
+
+inline fun <reified T : Component> ViewComposition.emitComponent(
+    loc: Int,
+    ctor: () -> T
+): Unit = emitComponent(loc, null, ctor, { true })
+
+inline fun <reified T : Component> ViewComposition.emitComponent(
+    loc: Int,
+    key: Int?,
+    ctor: () -> T
+): Unit = emitComponent(loc, key, ctor, { true })
+
+inline fun <reified T : Component> ViewComposition.emitComponent(
+    loc: Int,
+    key: Int?,
+    ctor: () -> T,
+    noinline block: ViewValidator.(f: T) -> Boolean
+): Unit = call(
+    joinKey(loc, key),
+    ctor,
+    block,
+    { f -> f() }
+)
+
+inline fun <reified T : View> ViewComposition.emitView(
+    loc: Int,
+    ctor: (context: Context) -> T,
+    noinline updater: ViewUpdater<T>.() -> Unit
+): Unit = emitView(loc, null, ctor, updater)
+
+inline fun <reified T : View> ViewComposition.emitView(
+    loc: Int,
+    ctor: (context: Context) -> T
+): Unit = emitView(loc, null, ctor, {})
+
+inline fun <reified T : View> ViewComposition.emitView(
+    loc: Int,
+    key: Int?,
+    ctor: (context: Context) -> T
+): Unit = emitView(loc, key, ctor, {})
+
+inline fun <reified T : View> ViewComposition.emitView(
+    loc: Int,
+    key: Int?,
+    ctor: (context: Context) -> T,
+    noinline updater: ViewUpdater<T>.() -> Unit
+): Unit = emit(
+    joinKey(loc, key),
+    ctor,
+    updater
+)
+
+inline fun <reified T : ViewGroup> ViewComposition.emitViewGroup(
+    loc: Int,
+    ctor: (context: Context) -> T,
+    noinline updater: ViewUpdater<T>.() -> Unit,
+    block: @Composable() () -> Unit
+) = emitViewGroup(loc, null, ctor, updater, block)
+
+inline fun <reified T : ViewGroup> ViewComposition.emitViewGroup(
+    loc: Int,
+    key: Int?,
+    ctor: (context: Context) -> T,
+    noinline updater: ViewUpdater<T>.() -> Unit,
+    block: @Composable() () -> Unit
+) = emit(
+    joinKey(loc, key),
+    ctor,
+    updater,
+    block
+)
+
+inline fun <reified T : Emittable> ViewComposition.emitEmittable(
+    loc: Int,
+    ctor: () -> T,
+    noinline updater: ViewUpdater<T>.() -> Unit
+) = emitEmittable(loc, null, ctor, updater, {})
+
+inline fun <reified T : Emittable> ViewComposition.emitEmittable(
+    loc: Int,
+    ctor: () -> T,
+    noinline updater: ViewUpdater<T>.() -> Unit,
+    block: @Composable() () -> Unit
+) = emitEmittable(loc, null, ctor, updater, block)
+
+inline fun <reified T : Emittable> ViewComposition.emitEmittable(
+    loc: Int,
+    key: Int?,
+    ctor: () -> T,
+    noinline updater: ViewUpdater<T>.() -> Unit,
+    block: @Composable() () -> Unit
+) = emit(
+    joinKey(loc, key),
+    ctor,
+    updater,
+    block
+)
+
+inline fun <reified T> ViewComposition.provideAmbient(
+    key: Ambient<T>,
+    value: T,
+    noinline children: @Composable() () -> Unit
+) = call(
+    0,
+    { changed(key) + changed(value) + changed(children) },
+    { @Suppress("PLUGIN_ERROR") key.Provider(value, children) }
+)
\ No newline at end of file
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/EffectsTests.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/EffectsTests.kt
new file mode 100644
index 0000000..4119980
--- /dev/null
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/EffectsTests.kt
@@ -0,0 +1,729 @@
+/*
+ * Copyright 2019 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
+
+import android.app.Activity
+import android.widget.Button
+import android.widget.TextView
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SmallTest
+import androidx.test.rule.ActivityTestRule
+import junit.framework.TestCase.assertEquals
+import junit.framework.TestCase.assertFalse
+import junit.framework.TestCase.assertTrue
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@Suppress("PLUGIN_WARNING")
+class EffectsTests {
+
+    @get:Rule
+    val activityRule = ActivityTestRule(TestActivity::class.java)
+
+    @Test
+    fun testMemoization1() {
+        var inc = 0
+
+        compose {
+            +memo { ++inc }
+        }.then { _ ->
+            assertEquals(1, inc)
+        }.then { _ ->
+            assertEquals(1, inc)
+        }
+    }
+
+    @Test
+    fun testMemoization2() {
+        var calculations = 0
+        var compositions = 0
+        var calculation = 0
+        var key = 0
+
+        compose {
+            compositions++
+            calculation = +memo(key) { 100 * ++calculations }
+        }.then { _ ->
+            assertEquals(1, calculations)
+            assertEquals(100, calculation)
+            assertEquals(1, compositions)
+        }.then { _ ->
+            assertEquals(1, calculations)
+            assertEquals(100, calculation)
+            assertEquals(2, compositions)
+            key++
+        }.then { _ ->
+            assertEquals(2, calculations)
+            assertEquals(200, calculation)
+            assertEquals(3, compositions)
+        }.then { _ ->
+            assertEquals(2, calculations)
+            assertEquals(200, calculation)
+            assertEquals(4, compositions)
+            key++
+        }.then { _ ->
+            assertEquals(3, calculations)
+            assertEquals(300, calculation)
+            assertEquals(5, compositions)
+        }
+    }
+
+    @Test
+    fun testState1() {
+        val tv1Id = 100
+        var inc = 0
+        var local = State("invalid")
+
+        compose {
+            local = +state { "Hello world! ${inc++}" }
+            composer.emit(
+                168,
+                { context -> TextView(context).apply { id = tv1Id } },
+                { set(local.value) { text = it } }
+            )
+        }.then { activity ->
+            val helloText = activity.findViewById(tv1Id) as TextView
+            assertEquals("Hello world! 0", helloText.text)
+            assertEquals(local.value, helloText.text)
+        }.then { activity ->
+            val helloText = activity.findViewById(tv1Id) as TextView
+            assertEquals("Hello world! 0", helloText.text)
+            assertEquals(local.value, helloText.text)
+
+            local.value = "New string"
+        }.then { activity ->
+            val helloText = activity.findViewById(tv1Id) as TextView
+            assertEquals("New string", helloText.text)
+            assertEquals(local.value, helloText.text)
+        }
+    }
+
+    @Test
+    fun testState2() {
+        val tv1Id = 100
+        val tv2Id = 200
+        var local1 = State("invalid")
+        var local2 = State("invalid")
+
+        compose {
+            local1 = +state { "First" }
+            local2 = +state { "Second" }
+            composer.emit(
+                168,
+                { context -> TextView(context).apply { id = tv1Id } },
+                { set(local1.value) { text = it } }
+            )
+            composer.emit(
+                169,
+                { context -> TextView(context).apply { id = tv2Id } },
+                { set(local2.value) { text = it } }
+            )
+        }.then { activity ->
+            val tv1 = activity.findViewById(tv1Id) as TextView
+            val tv2 = activity.findViewById(tv2Id) as TextView
+            assertEquals("First", tv1.text)
+            assertEquals("Second", tv2.text)
+            assertEquals(local1.value, tv1.text)
+            assertEquals(local2.value, tv2.text)
+        }.then { activity ->
+            val tv1 = activity.findViewById(tv1Id) as TextView
+            val tv2 = activity.findViewById(tv2Id) as TextView
+            assertEquals("First", tv1.text)
+            assertEquals("Second", tv2.text)
+            assertEquals(local1.value, tv1.text)
+            assertEquals(local2.value, tv2.text)
+
+            local1.value = "New First"
+        }.then { activity ->
+            val tv1 = activity.findViewById(tv1Id) as TextView
+            val tv2 = activity.findViewById(tv2Id) as TextView
+            assertEquals("New First", tv1.text)
+            assertEquals("Second", tv2.text)
+            assertEquals(local1.value, tv1.text)
+            assertEquals(local2.value, tv2.text)
+        }
+    }
+
+    @Test
+    fun testPreCommit1() {
+        var mount = true
+
+        val logHistory = mutableListOf<String>()
+        fun log(x: String) = logHistory.add(x)
+
+        @Composable
+        fun Unmountable() {
+            log("Unmountable:start")
+            +onPreCommit {
+                log("onPreCommit")
+                onDispose {
+                    log("onDispose")
+                }
+            }
+            log("Unmountable:end")
+        }
+
+        compose {
+            with(composer) {
+                log("compose:start")
+                if (mount) {
+                    call(
+                        168,
+                        { true },
+                        { @Suppress("PLUGIN_ERROR") Unmountable() }
+                    )
+                }
+                log("compose:end")
+            }
+        }.then { _ ->
+            assertArrayEquals(
+                listOf(
+                    "compose:start",
+                    "Unmountable:start",
+                    "Unmountable:end",
+                    "compose:end",
+                    "onPreCommit"
+                ),
+                logHistory
+            )
+            mount = false
+        }.then { _ ->
+            assertArrayEquals(
+                listOf(
+                    "compose:start",
+                    "Unmountable:start",
+                    "Unmountable:end",
+                    "compose:end",
+                    "onPreCommit",
+                    "compose:start",
+                    "compose:end",
+                    "onDispose"
+                ),
+                logHistory
+            )
+        }
+    }
+
+    @Test
+    fun testPreCommit2() {
+        var mount = true
+
+        val logHistory = mutableListOf<String>()
+        fun log(x: String) = logHistory.add(x)
+
+        @Composable
+        fun Unmountable() {
+            +onPreCommit {
+                log("onPreCommit:a2")
+                onDispose {
+                    log("onDispose:a2")
+                }
+            }
+            +onPreCommit {
+                log("onPreCommit:b2")
+                onDispose {
+                    log("onDispose:b2")
+                }
+            }
+        }
+
+        compose {
+            +onPreCommit {
+                log("onPreCommit:a1")
+                onDispose {
+                    log("onDispose:a1")
+                }
+            }
+            if (mount) {
+                composer.call(
+                    168,
+                    { true },
+                    { @Suppress("PLUGIN_ERROR") Unmountable() }
+                )
+            }
+            +onPreCommit {
+                log("onPreCommit:b1")
+                onDispose {
+                    log("onDispose:b1")
+                }
+            }
+        }.then { _ ->
+            assertArrayEquals(
+                listOf(
+                    "onPreCommit:a1",
+                    "onPreCommit:a2",
+                    "onPreCommit:b2",
+                    "onPreCommit:b1"
+                ),
+                logHistory
+            )
+            mount = false
+            log("recompose")
+        }.then { _ ->
+            assertArrayEquals(
+                listOf(
+                    "onPreCommit:a1",
+                    "onPreCommit:a2",
+                    "onPreCommit:b2",
+                    "onPreCommit:b1",
+                    "recompose",
+                    "onDispose:b2",
+                    "onDispose:a2",
+                    "onDispose:b1",
+                    "onDispose:a1",
+                    "onPreCommit:a1",
+                    "onPreCommit:b1"
+                ),
+                logHistory
+            )
+        }
+    }
+
+    @Test
+    fun testPreCommit3() {
+        var x = 0
+
+        val logHistory = mutableListOf<String>()
+        fun log(x: String) = logHistory.add(x)
+
+        compose {
+            +onPreCommit {
+                val y = x++
+                log("onPreCommit:$y")
+                onDispose {
+                    log("dispose:$y")
+                }
+            }
+        }.then { _ ->
+            log("recompose")
+        }.then { _ ->
+            assertArrayEquals(
+                listOf(
+                    "onPreCommit:0",
+                    "recompose",
+                    "dispose:0",
+                    "onPreCommit:1"
+                ),
+                logHistory
+            )
+        }
+    }
+
+    @Test
+    fun testPreCommit31() {
+        var a = 0
+        var b = 0
+
+        val logHistory = mutableListOf<String>()
+        fun log(x: String) = logHistory.add(x)
+
+        compose {
+            +onPreCommit {
+                val y = a++
+                log("onPreCommit a:$y")
+                onDispose {
+                    log("dispose a:$y")
+                }
+            }
+            +onPreCommit {
+                val y = b++
+                log("onPreCommit b:$y")
+                onDispose {
+                    log("dispose b:$y")
+                }
+            }
+        }.then { _ ->
+            log("recompose")
+        }.then { _ ->
+            assertArrayEquals(
+                listOf(
+                    "onPreCommit a:0",
+                    "onPreCommit b:0",
+                    "recompose",
+                    "dispose b:0",
+                    "dispose a:0",
+                    "onPreCommit a:1",
+                    "onPreCommit b:1"
+                ),
+                logHistory
+            )
+        }
+    }
+
+    @Test
+    fun testPreCommit4() {
+        var x = 0
+        var key = 123
+
+        val logHistory = mutableListOf<String>()
+        fun log(x: String) = logHistory.add(x)
+
+        compose {
+            +onPreCommit(key) {
+                val y = x++
+                log("onPreCommit:$y")
+                onDispose {
+                    log("dispose:$y")
+                }
+            }
+        }.then { _ ->
+            log("recompose")
+        }.then { _ ->
+            assertArrayEquals(
+                listOf(
+                    "onPreCommit:0",
+                    "recompose"
+                ),
+                logHistory
+            )
+            log("recompose (key -> 345)")
+            key = 345
+        }.then { _ ->
+            assertArrayEquals(
+                listOf(
+                    "onPreCommit:0",
+                    "recompose",
+                    "recompose (key -> 345)",
+                    "dispose:0",
+                    "onPreCommit:1"
+                ),
+                logHistory
+            )
+        }
+    }
+
+    @Test
+    fun testPreCommit5() {
+        var a = 0
+        var b = 0
+        var c = 0
+
+        val logHistory = mutableListOf<String>()
+        fun log(x: String) = logHistory.add(x)
+
+        @Composable
+        fun Sub() {
+            +onPreCommit {
+                val y = c++
+                log("onPreCommit c:$y")
+                onDispose {
+                    log("dispose c:$y")
+                }
+            }
+        }
+
+        compose {
+            +onPreCommit {
+                val y = a++
+                log("onPreCommit a:$y")
+                onDispose {
+                    log("dispose a:$y")
+                }
+            }
+
+            +onPreCommit {
+                val y = b++
+                log("onPreCommit b:$y")
+                onDispose {
+                    log("dispose b:$y")
+                }
+            }
+
+            composer.call(
+                1234,
+                { true },
+                { @Suppress("PLUGIN_ERROR") Sub() }
+            )
+        }.then { _ ->
+            log("recompose")
+        }.then { _ ->
+            assertArrayEquals(
+                listOf(
+                    "onPreCommit a:0",
+                    "onPreCommit b:0",
+                    "onPreCommit c:0",
+                    "recompose",
+                    "dispose c:0",
+                    "dispose b:0",
+                    "dispose a:0",
+                    "onPreCommit a:1",
+                    "onPreCommit b:1",
+                    "onPreCommit c:1"
+                ),
+                logHistory
+            )
+        }
+    }
+
+    @Test
+    fun testOnCommit1() {
+        var mount = true
+
+        val logHistory = mutableListOf<String>()
+        fun log(x: String) = logHistory.add(x)
+
+        @Composable
+        fun Unmountable() {
+            log("Unmountable:start")
+            +onCommit {
+                log("onCommit 1")
+                onDispose {
+                    log("onDispose 1")
+                }
+            }
+            +onPreCommit {
+                log("onPreCommit 2")
+                onDispose {
+                    log("onDispose 2")
+                }
+            }
+            +onCommit {
+                log("onCommit 3")
+                onDispose {
+                    log("onDispose 3")
+                }
+            }
+            log("Unmountable:end")
+        }
+
+        compose {
+            with(composer) {
+                log("compose:start")
+                if (mount) {
+                    call(
+                        168,
+                        { true },
+                        { @Suppress("PLUGIN_ERROR") Unmountable() }
+                    )
+                }
+                log("compose:end")
+            }
+        }.then { _ ->
+            assertArrayEquals(
+                listOf(
+                    "compose:start",
+                    "Unmountable:start",
+                    "Unmountable:end",
+                    "compose:end",
+                    "onPreCommit 2",
+                    "onCommit 1",
+                    "onCommit 3"
+                ),
+                logHistory
+            )
+            mount = false
+        }.then { _ ->
+            assertArrayEquals(
+                listOf(
+                    "compose:start",
+                    "Unmountable:start",
+                    "Unmountable:end",
+                    "compose:end",
+                    "onPreCommit 2",
+                    "onCommit 1",
+                    "onCommit 3",
+                    "compose:start",
+                    "compose:end",
+                    "onDispose 3",
+                    "onDispose 2",
+                    "onDispose 1"
+                ),
+                logHistory
+            )
+        }
+    }
+
+    @Test
+    fun testAmbient1() {
+        val tv1Id = 100
+
+        val Foo = Ambient.of<String>()
+        var current = "Hello World"
+
+        @Composable
+        fun Bar() {
+            composer.call(
+                21323,
+                { true },
+                {
+                    @Suppress("PLUGIN_ERROR")
+                    (Observe {
+                        val foo = +ambient(Foo)
+                        composer.emit(
+                            168,
+                            { context -> TextView(context).apply { id = tv1Id } },
+                            { set(foo) { text = it } }
+                        )
+                    })
+                }
+            )
+        }
+
+        compose {
+            with(composer) {
+                provideAmbient(Foo, current) {
+                    call(
+                        123,
+                        { false },
+                        { @Suppress("PLUGIN_ERROR") Bar() }
+                    )
+                }
+            }
+        }.then { activity ->
+            val helloText = activity.findViewById(tv1Id) as TextView
+            assertEquals(current, helloText.text)
+            current = "abcd"
+        }.then { activity ->
+            val helloText = activity.findViewById(tv1Id) as TextView
+            assertEquals(current, helloText.text)
+        }
+    }
+
+    @Test
+    @MediumTest
+    fun testAmbient2() {
+        val MyAmbient = Ambient.of<Int>("Hello") { throw Exception("not set") }
+
+        var requestRecompose: (() -> Unit)? = null
+        var buttonCreated = false
+        var ambientValue = 1
+
+        fun SimpleComposable2() {
+            Observe {
+                with(composer) {
+                    val value = +ambient(MyAmbient)
+                    emit(534, { context -> TextView(context) }, {
+                        set("$value") { text = it }
+                    })
+                }
+            }
+        }
+
+        fun SimpleComposable() {
+            composer.call(531, { true }) {
+                Recompose {
+                    requestRecompose = it
+                    composer.provideAmbient(MyAmbient, ambientValue++) {
+                        composer.call(523, { false }) { SimpleComposable2() }
+                        composer.emitView(525) { context ->
+                            Button(context).also {
+                                buttonCreated = true
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        fun Root() {
+            with(composer) {
+                call(547, { false }) {
+                    SimpleComposable()
+                }
+            }
+        }
+
+        compose(manualRecompose = true) {
+            with(composer) {
+                call(556, { false }) {
+                    Root()
+                }
+            }
+        }.then {
+            assertTrue("Expected button to be created", buttonCreated)
+            buttonCreated = false
+            requestRecompose?.invoke()
+        }.then {
+            assertFalse("Expected button to not be recreated", buttonCreated)
+        }
+    }
+
+    @Test
+    fun testUpdatedComposition() {
+        val tv1Id = 100
+        var inc = 0
+
+        compose {
+            val local = +state { "Hello world! ${inc++}" }
+            composer.emit(
+                168,
+                { context -> TextView(context).apply { id = tv1Id } },
+                { set(local.value) { text = it } }
+            )
+        }.then { activity ->
+            val helloText = activity.findViewById(tv1Id) as TextView
+            assertEquals("Hello world! 0", helloText.text)
+        }.then { activity ->
+            val helloText = activity.findViewById(tv1Id) as TextView
+            assertEquals("Hello world! 0", helloText.text)
+        }
+    }
+
+    class CompositionTest(
+        val composable: () -> Unit,
+        private val manualRecompose: Boolean,
+        private val activity: Activity
+    ) {
+        lateinit var doRecompose: () -> Unit
+        inner class ActiveTest(private val activity: Activity) {
+            fun then(block: (activity: Activity) -> Unit): ActiveTest {
+                if (!manualRecompose) {
+                    activity.uiThread {
+                        doRecompose()
+                    }
+                }
+                activity.waitForAFrame()
+                activity.uiThread {
+                    block(activity)
+                }
+                return this
+            }
+        }
+
+        fun then(block: (activity: Activity) -> Unit): ActiveTest {
+            activity.show {
+                Recompose {
+                    doRecompose = it
+                    composable()
+                }
+            }
+            activity.waitForAFrame()
+            activity.uiThread {
+                block(activity)
+            }
+            return ActiveTest(activity)
+        }
+    }
+
+    fun compose(manualRecompose: Boolean = false, composable: () -> Unit) =
+        CompositionTest(composable, manualRecompose, activityRule.activity)
+}
+
+fun <T> assertArrayEquals(
+    expected: Collection<T>,
+    actual: Collection<T>,
+    transform: (T) -> String = { "$it" }
+) {
+    assertEquals(
+        expected.joinToString("\n", transform = transform),
+        actual.joinToString("\n", transform = transform)
+    )
+}
\ No newline at end of file
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/RecomposerTests.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/RecomposerTests.kt
new file mode 100644
index 0000000..7336824
--- /dev/null
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/RecomposerTests.kt
@@ -0,0 +1,651 @@
+/*
+ * Copyright 2019 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
+
+import android.view.View
+import android.view.ViewGroup
+import android.widget.LinearLayout
+import android.widget.TextView
+import androidx.compose.frames.currentFrame
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SmallTest
+import androidx.test.rule.ActivityTestRule
+import junit.framework.TestCase.assertEquals
+import junit.framework.TestCase.assertFalse
+import junit.framework.TestCase.assertNotSame
+import junit.framework.TestCase.assertTrue
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class ComposerCompositionContextTests : ComposerComposeTestCase() {
+
+    @get:Rule
+    val activityRule = ActivityTestRule(TestActivity::class.java)
+
+    private fun compose(manualRecompose: Boolean = false, composable: (ViewComposition) -> Unit) =
+        compose(activityRule.activity, manualRecompose = manualRecompose, composable = composable)
+
+    @Test
+    @SmallTest
+    fun testNativeViewWithAttributes() {
+        compose {
+            with(it) {
+                // TextView(id=456 text="some text")
+                emitView(123, ::TextView) {
+                    set(456) { id = it }
+                    set("some text") { text = it }
+                }
+            }
+        }.then { _, _, root, activity ->
+            assertEquals(1, root.childCount)
+
+            val tv = activity.findViewById(456) as TextView
+            assertEquals("some text", tv.text)
+
+            assertEquals(tv, root.getChildAt(0))
+        }
+    }
+
+    @Test
+    @SmallTest
+    fun testSlotKeyChangeCausesRecreate() {
+        var i = 1
+        var tv1: TextView? = null
+        compose {
+            // this should cause the textview to get recreated on every compose
+            i++
+
+            with(it) {
+                // TextView(id=456 text="some text")
+                emitView(i, ::TextView) {
+                    set(456) { id = it }
+                    set("some text") { text = it }
+                }
+            }
+        }.then { _, _, _, activity ->
+            tv1 = activity.findViewById(456) as TextView
+        }.then { _, _, root, activity ->
+            assertEquals("Compose got called twice", 3, i)
+
+            val tv2 = activity.findViewById(456) as TextView
+
+            assertFalse(
+                "The text views should be different instances",
+                tv1 === tv2
+            )
+
+            assertEquals(
+                "The unused child got removed from the view hierarchy",
+                1,
+                root.childCount
+            )
+        }
+    }
+
+    @Test
+    @SmallTest
+    fun testViewWithViewChildren() {
+        compose {
+            // LinearLayout(id = 345) {>
+            with(it) {
+                emitViewGroup(100, ::LinearLayout, {
+                    set(345) { id = it }
+                }) {
+                    // TextView(id = 456, text="some text")
+                    emitView(101, ::TextView) {
+                        set(456) { id = it }
+                        set("some text") { text = it }
+                    }
+                    // TextView(id = 567, text="some text")
+                    emitView(102, ::TextView) {
+                        set(567) { id = it }
+                        set("some text") { text = it }
+                    }
+                }
+            }
+        }.then { _, _, root, activity ->
+            val ll = activity.findViewById(345) as LinearLayout
+            val tv1 = activity.findViewById(456) as TextView
+            val tv2 = activity.findViewById(567) as TextView
+
+            assertEquals("The linear layout should be the only child of root", 1, root.childCount)
+            assertEquals("Both children should have been added", 2, ll.childCount)
+            assertTrue(
+                "Should be the expected TextView (1)",
+                ll.getChildAt(0) === tv1
+            )
+            assertTrue(
+                "Should be the expected TextView (2)",
+                ll.getChildAt(1) === tv2
+            )
+        }
+    }
+
+    @Test
+    @SmallTest
+    fun testForLoop() {
+        val items = listOf(1, 2, 3, 4, 5, 6)
+        compose {
+            // this should cause the TextView to get recreated on every compose
+            with(it) {
+                emitViewGroup(100, ::LinearLayout, {
+                    set(345) { id = it }
+                }) {
+                    for (i in items) {
+                        // TextView(id=456, text="some text")
+                        emitView(101, ::TextView) {
+                            set(456) { id = it }
+                            set("some text $i") { text = it }
+                        }
+                    }
+                }
+            }
+        }.then { _, _, root, activity ->
+            val ll = activity.findViewById(345) as LinearLayout
+
+            assertEquals("The linear layout should be the only child of root", 1, root.childCount)
+            assertEquals("Each item in the for loop should be a child", items.size, ll.childCount)
+            items.forEachIndexed { index, i ->
+                assertEquals(
+                    "Should be the correct child", "some text $i",
+                    (ll.getChildAt(index) as TextView).text
+                )
+            }
+        }
+    }
+
+    @Test
+    @SmallTest
+    fun testRecompose() {
+        val counter = Counter()
+
+        compose(manualRecompose = true) {
+            // <A />
+            it.emitComponent(123) {
+                RecomposeTestComponents.A(
+                    counter,
+                    RecomposeTestComponents.ClickAction.Recompose
+                )
+            }
+        }.then { _, _, _, activity ->
+            // everything got rendered once
+            assertEquals(1, counter["A"])
+            assertEquals(1, counter["100"])
+            assertEquals(1, counter["101"])
+            assertEquals(1, counter["102"])
+
+            (activity.findViewById(100) as TextView).performClick()
+            (activity.findViewById(102) as TextView).performClick()
+
+            // nothing should happen synchronously
+            assertEquals(1, counter["A"])
+            assertEquals(1, counter["100"])
+            assertEquals(1, counter["101"])
+            assertEquals(1, counter["102"])
+        }.then { _, _, _, activity ->
+            // only the clicked view got rerendered
+            assertEquals(1, counter["A"])
+            assertEquals(2, counter["100"])
+            assertEquals(1, counter["101"])
+            assertEquals(2, counter["102"])
+
+            // recompose() both the parent and the child... and show that the child only
+            // recomposes once as a result
+            (activity.findViewById(99) as LinearLayout).performClick()
+            (activity.findViewById(102) as TextView).performClick()
+        }.then { _, _, _, _ ->
+
+            assertEquals(2, counter["A"])
+            assertEquals(2, counter["100"])
+            assertEquals(1, counter["101"])
+            assertEquals(3, counter["102"])
+        }
+    }
+
+    @Test
+    @SmallTest
+    fun testRecomposeSync() {
+        val counter = Counter()
+
+        compose(manualRecompose = true) {
+            // A()
+            it.emitComponent(123) {
+                RecomposeTestComponents.A(
+                    counter,
+                    RecomposeTestComponents.ClickAction.RecomposeSync
+                )
+            }
+        }.then { _, _, _, activity ->
+            // everything got rendered once
+            assertEquals(1, counter["A"])
+            assertEquals(1, counter["100"])
+            assertEquals(1, counter["101"])
+            assertEquals(1, counter["102"])
+
+            (activity.findViewById(100) as TextView).performClick()
+        }.then { _, _, _, _ ->
+            // only the clicked view got rerendered
+            assertEquals(1, counter["A"])
+            assertEquals(2, counter["100"])
+            assertEquals(1, counter["101"])
+            assertEquals(1, counter["102"])
+        }.then { _, _, _, activity ->
+            assertEquals(1, counter["A"])
+            assertEquals(2, counter["100"])
+            assertEquals(1, counter["101"])
+            assertEquals(1, counter["102"])
+
+            // try to recompose the parent, but ensure that even if we tap textView several times,
+            // it's all got recomposed once
+            (activity.findViewById(99) as LinearLayout).performClick()
+            (activity.findViewById(100) as TextView).performClick()
+        }.then { _, _, _, activity ->
+            (activity.findViewById(100) as TextView).performClick()
+        }.then { _, _, _, activity ->
+            (activity.findViewById(100) as TextView).performClick()
+        }.then { _, _, _, _ ->
+            // only the twice clicked view got rerendered twice
+            assertEquals(2, counter["A"])
+            // this should be 5, as it gets recomposed synchronously 3 times due to TV taps
+            assertEquals(5, counter["100"])
+            assertEquals(1, counter["101"])
+            assertEquals(1, counter["102"])
+        }
+    }
+
+    @Test
+    @SmallTest
+    fun testRootRecompose() {
+        val counter = Counter()
+
+        val listener =
+            RecomposeTestComponents.ClickAction.PerformOnView {
+                Compose.findRoot(it)?.let {
+                    it.recomposeCallback?.invoke(false)
+                }
+            }
+
+        compose(manualRecompose = true) {
+            // <A />
+            it.emitComponent(123) {
+                RecomposeTestComponents.A(
+                    counter,
+                    listener
+                )
+            }
+        }.then { _, _, _, activity ->
+            // everything got rendered once
+            assertEquals(1, counter["A"])
+            assertEquals(1, counter["100"])
+            assertEquals(1, counter["101"])
+            assertEquals(1, counter["102"])
+
+            (activity.findViewById(100) as TextView).performClick()
+            (activity.findViewById(102) as TextView).performClick()
+
+            // nothing should happen synchronously
+            assertEquals(1, counter["A"])
+            assertEquals(1, counter["100"])
+            assertEquals(1, counter["101"])
+            assertEquals(1, counter["102"])
+        }.then { _, _, _, activity ->
+            // as we recompose ROOT on every tap, only root(and LinearLayout) counter should we
+            // increased once, because two clicks layed to one frame
+            assertEquals(2, counter["A"])
+            assertEquals(1, counter["100"])
+            assertEquals(1, counter["101"])
+            assertEquals(1, counter["102"])
+
+            (activity.findViewById(99) as LinearLayout).performClick()
+            (activity.findViewById(102) as TextView).performClick()
+        }.then { _, _, _, _ ->
+            // again, no matter what we tappes, we want to recompose root, so LinearLayout's counter
+            // got increased
+            assertEquals(3, counter["A"])
+            assertEquals(1, counter["100"])
+            assertEquals(1, counter["101"])
+            assertEquals(1, counter["102"])
+        }
+    }
+    @Test
+    @SmallTest
+    fun testRootRecomposeSync() {
+        val counter = Counter()
+
+        val listener =
+            RecomposeTestComponents.ClickAction.PerformOnView {
+                Compose.findRoot(it)?.let {
+                    it.recomposeCallback?.invoke(true)
+                }
+            }
+        compose(manualRecompose = true) {
+            // <A />
+            it.emitComponent(123) {
+                RecomposeTestComponents.A(
+                    counter,
+                    listener
+                )
+            }
+        }.then { _, _, _, activity ->
+            // everything got rendered once
+            assertEquals(1, counter["A"])
+            assertEquals(1, counter["100"])
+            assertEquals(1, counter["101"])
+            assertEquals(1, counter["102"])
+
+            (activity.findViewById(100) as TextView).performClick()
+
+            // important! as we recompose Root every time
+            // no matter what we clicked, root (and LinearLayout) gets rerendered
+            assertEquals(2, counter["A"])
+            assertEquals(1, counter["100"])
+            assertEquals(1, counter["101"])
+            assertEquals(1, counter["102"])
+
+            (activity.findViewById(99) as LinearLayout).performClick()
+
+            assertEquals(3, counter["A"])
+            assertEquals(1, counter["100"])
+            assertEquals(1, counter["101"])
+            assertEquals(1, counter["102"])
+
+            // make sure nothing has been scheduled inside recomposeSync()
+            assertEquals(3, counter["A"])
+            assertEquals(1, counter["100"])
+            assertEquals(1, counter["101"])
+            assertEquals(1, counter["102"])
+        }
+    }
+    // components for testing recompose behavior above
+    private object RecomposeTestComponents {
+        sealed class ClickAction {
+            object Recompose : ClickAction()
+            object RecomposeSync : ClickAction()
+            class PerformOnView(val action: (View) -> Unit) : ClickAction()
+        }
+
+        class B(val counter: Counter, val listener: ClickAction) : Component() {
+            var id: Int = 0
+            override fun compose() {
+                counter.inc("$id")
+
+                with(composer) {
+                    // <TextView id={id} onClickListener={{ clickAction() }} />
+                    emitView(24, ::TextView) {
+                        set(id) { id = it }
+                        set(View.OnClickListener {
+                            @Suppress("DEPRECATION")
+                            when (listener) {
+                                is ClickAction.Recompose -> recompose()
+                                is ClickAction.RecomposeSync -> recomposeSync()
+                                is ClickAction.PerformOnView -> listener.action.invoke(it)
+                            }
+                        }) { setOnClickListener(it) }
+                    }
+                }
+            }
+        }
+
+        class A(val counter: Counter, val listener: ClickAction) : Component() {
+            override fun compose() {
+                counter.inc("A")
+                // LinearLayout(onClickListener={ clickAction() }. id=99) {
+                //     B(id=100)
+                //     B(id=101)
+                //     B(id=102)
+                // }
+
+                with(composer) {
+
+                    // LinearLayout(id=99, onClickListener={ clickAction() }) { />
+                    emitViewGroup(897, ::LinearLayout, {
+                        set(99) { id = it }
+                        set(View.OnClickListener {
+                            @Suppress("DEPRECATION")
+                            when (listener) {
+                                is ClickAction.Recompose -> recompose()
+                                is ClickAction.RecomposeSync -> recomposeSync()
+                                is ClickAction.PerformOnView -> listener.action.invoke(it)
+                            }
+                        }) { setOnClickListener(it) }
+                    }) {
+                        for (id in 100..102) {
+                            // B(key=id, id=id)
+                            emitComponent(878983, id, {
+                                B(
+                                    counter,
+                                    listener
+                                )
+                            }) { f ->
+                                set(id) { f.id = it }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Test
+    @SmallTest
+    fun testCorrectViewTree() {
+        compose {
+            // LinearLayout {
+            //   LinearLayout { }
+            //   LinearLayout { }
+            // }
+            // LinearLayout { }
+
+            with(it) {
+                emitViewGroup(123, ::LinearLayout, {}) {
+                    emitView(123, ::LinearLayout)
+                    emitView(123, ::LinearLayout)
+                }
+                emitView(123, ::LinearLayout)
+            }
+        }.then { _, _, root, _ ->
+            assertChildHierarchy(root) {
+                """
+                    <LinearLayout>
+                        <LinearLayout />
+                        <LinearLayout />
+                    </LinearLayout>
+                    <LinearLayout />
+                """
+            }
+        }
+    }
+
+    @Test
+    @SmallTest
+    fun testCorrectViewTreeWithComponents() {
+
+        class B : Component() {
+            override fun compose() {
+                with(composer) {
+                    // TextView()
+                    emitView(123, ::TextView)
+                }
+            }
+        }
+
+        compose {
+            // LinearLayout {
+            //   LinearLayout {
+            //     B()
+            //   }
+            //   LinearLayout {
+            //     B()
+            //   }
+            // }
+
+            with(it) {
+                emitViewGroup(123, ::LinearLayout, {}) {
+                    emitViewGroup(123, ::LinearLayout, {}) {
+                        emitComponent(123, ::B)
+                    }
+                    emitViewGroup(123, ::LinearLayout, {}) {
+                        emitComponent(123, ::B)
+                    }
+                }
+            }
+        }.then { _, _, root, _ ->
+
+            assertChildHierarchy(root) {
+                """
+                <LinearLayout>
+                    <LinearLayout>
+                        <TextView />
+                    </LinearLayout>
+                    <LinearLayout>
+                        <TextView />
+                    </LinearLayout>
+                </LinearLayout>
+                """
+            }
+        }
+    }
+
+    @Test
+    @MediumTest
+    fun testCorrectViewTreeWithComponentWithMultipleRoots() {
+
+        class B : Component() {
+            override fun compose() {
+                with(composer) {
+                    // TextView()
+                    emitView(123, ::TextView)
+                    // TextView()
+                    emitView(124, ::TextView)
+                }
+            }
+        }
+
+        compose {
+            // LinearLayout {
+            //   LinearLayout {
+            //     B()
+            //   }
+            //   LinearLayout {
+            //     B()
+            //   }
+            // }
+
+            with(it) {
+                emitViewGroup(123, ::LinearLayout, {}) {
+                    emitViewGroup(123, ::LinearLayout, {}) {
+                        emitComponent(123, ::B)
+                    }
+                    emitViewGroup(123, ::LinearLayout, {}) {
+                        emitComponent(123, ::B)
+                    }
+                }
+            }
+        }.then { _, _, root, _ ->
+
+            assertChildHierarchy(root) {
+                """
+                <LinearLayout>
+                    <LinearLayout>
+                        <TextView />
+                        <TextView />
+                    </LinearLayout>
+                    <LinearLayout>
+                        <TextView />
+                        <TextView />
+                    </LinearLayout>
+                </LinearLayout>
+                """
+            }
+        }
+    }
+
+    @Test
+    @SmallTest
+    fun testFrameTransition() {
+        var frameId: Int? = null
+        compose {
+            frameId = currentFrame().id
+        }.then { _, _, _, _ ->
+            assertNotSame(frameId, currentFrame().id)
+        }
+    }
+}
+
+fun assertChildHierarchy(root: ViewGroup, getHierarchy: () -> String) {
+    val realHierarchy = printChildHierarchy(root)
+
+    assertEquals(
+        normalizeString(getHierarchy()),
+        realHierarchy.trim()
+    )
+}
+
+fun normalizeString(str: String): String {
+    val lines = str.split('\n').dropWhile { it.isBlank() }.dropLastWhile {
+        it.isBlank()
+    }
+    if (lines.isEmpty()) return ""
+    val toRemove = lines.first().takeWhile { it == ' ' }.length
+    return lines.joinToString("\n") { it.substring(Math.min(toRemove, it.length)) }
+}
+
+fun printChildHierarchy(root: ViewGroup): String {
+    val sb = StringBuilder()
+    for (i in 0 until root.childCount) {
+        printView(root.getChildAt(i), 0, sb)
+    }
+    return sb.toString()
+}
+
+fun printView(view: View, indent: Int, sb: StringBuilder) {
+    val whitespace = " ".repeat(indent)
+    val name = view.javaClass.simpleName
+    val attributes = printAttributes(view)
+    if (view is ViewGroup && view.childCount > 0) {
+        sb.appendln("$whitespace<$name$attributes>")
+        for (i in 0 until view.childCount) {
+            printView(view.getChildAt(i), indent + 4, sb)
+        }
+        sb.appendln("$whitespace</$name>")
+    } else {
+        sb.appendln("$whitespace<$name$attributes />")
+    }
+}
+
+fun printAttributes(view: View): String {
+    val attrs = mutableListOf<String>()
+
+    // NOTE: right now we only look for id and text as attributes to print out... but we are
+    // free to add more if it makes sense
+    if (view.id != -1) {
+        attrs.add("id=${view.id}")
+    }
+
+    if (view is TextView && view.text.length > 0) {
+        attrs.add("text='${view.text}'")
+    }
+
+    val result = attrs.joinToString(" ", prefix = " ")
+    if (result.length == 1) {
+        return ""
+    }
+    return result
+}
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ViewComposerTests.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ViewComposerTests.kt
new file mode 100644
index 0000000..a2c49cc
--- /dev/null
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ViewComposerTests.kt
@@ -0,0 +1,1062 @@
+/*
+ * Copyright 2019 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
+
+import android.app.Activity
+import android.content.Context
+import android.os.Bundle
+import android.os.Looper
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import android.widget.LinearLayout
+import android.widget.TextView
+import androidx.test.annotation.UiThreadTest
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.rule.ActivityTestRule
+import junit.framework.TestCase.assertEquals
+import org.junit.Assert
+import org.junit.Rule
+import org.junit.runner.RunWith
+import org.junit.Test
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+
+class TestActivity : Activity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(LinearLayout(this).apply {
+            id =
+                ComposerComposeTestCase.ROOT_ID
+        })
+    }
+}
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class NewCodeGenTests {
+
+    @get:Rule
+    val activityRule = ActivityTestRule(TestActivity::class.java)
+
+    @Test
+    @UiThreadTest
+    fun testStaticComposition() {
+        val tv1Id = 100
+        val tv2Id = 200
+
+        compose {
+            emit(168, { context ->
+                TextView(context).apply {
+                    text = "Hello world!"; id = tv1Id
+                }
+            }) { }
+
+            emit(170, { context ->
+                LinearLayout(context).apply {
+                    orientation = LinearLayout.HORIZONTAL
+                }
+            }, { }) {
+                emit(171, { context ->
+                    TextView(context).apply {
+                        text = "Yellow world"; id = tv2Id
+                    }
+                }) { }
+            }
+        }.then { activity ->
+            val helloText = activity.findViewById(tv1Id) as TextView
+            assertEquals("Hello world!", helloText.text)
+            val yellowText = activity.findViewById(tv2Id) as TextView
+            assertEquals("Yellow world", yellowText.text)
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun testUpdatedComposition() {
+        val tv1Id = 100
+        val tv2Id = 200
+
+        var text1 = "Hello world!"
+        var text2 = "Yellow world"
+
+        compose {
+            emit(168, { context -> TextView(context).apply { id = tv1Id } }) {
+                set(text1) { text = it }
+            }
+            emit(170, { context ->
+                LinearLayout(context).apply {
+                    orientation = LinearLayout.HORIZONTAL
+                }
+            }, { }) {
+                emit(171, { context -> TextView(context).apply { id = tv2Id } }) {
+                    set(text2) { text = it }
+                }
+            }
+        }.then { activity ->
+            val helloText = activity.findViewById(tv1Id) as TextView
+            assertEquals(text1, helloText.text)
+            val yellowText = activity.findViewById(tv2Id) as TextView
+            assertEquals(text2, yellowText.text)
+
+            // Modify the composed state
+            text1 += " (changed)"
+            text2 += " (changed)"
+        }.then { activity ->
+            val helloText = activity.findViewById(tv1Id) as TextView
+            assertEquals(text1, helloText.text)
+            val yellowText = activity.findViewById(tv2Id) as TextView
+            assertEquals(text2, yellowText.text)
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun testSingleView() {
+        val tvId = 237
+        var text = "Hello world"
+
+        compose {
+            // <TextView text id=tvId />
+            emit(242, { context -> TextView(context).apply { id = tvId } }) {
+                set(text) { this.text = it }
+            }
+        }.then { activity ->
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("Hello world", tv.text)
+
+            text = "Salutations!"
+        }.then { activity ->
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("Salutations!", tv.text)
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun testViewGroup() {
+        val tvId = 258
+        val llId = 260
+        var text = "Hello world"
+        var orientation = LinearLayout.HORIZONTAL
+
+        compose {
+            // <LinearLayout>
+            //  <TextView text />
+            // </LinearLayout
+            emit(264, { context: Context -> LinearLayout(context).apply { id = llId } }, {
+                set(orientation) { this.orientation = it }
+            }) {
+                emit(265, { context -> TextView(context).apply { id = tvId } }) {
+                    set(text) { this.text = it }
+                }
+            }
+        }.then { activity ->
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("Hello world", tv.text)
+
+            text = "Salutations!"
+            orientation = LinearLayout.VERTICAL
+        }.then { activity ->
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("Salutations!", tv.text)
+
+            val ll = activity.findViewById(llId) as LinearLayout
+            assertEquals(LinearLayout.VERTICAL, ll.orientation)
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun testComposableFunctionInvocationOneParameter() {
+        data class Phone(val area: String, val prefix: String, val number: String)
+
+        var phone = Phone("123", "456", "7890")
+        var phoneCalled = 0
+        compose {
+
+            // Composition function
+            //  @Composable
+            //  fun PhoneView(phone: Phone) {
+            //    phoneCalled++
+            //   TextView(text="...")
+            //  }
+            fun PhoneView(phone: Phone) {
+                phoneCalled++
+                emit(225, { context -> TextView(context) }) {
+                    set(
+                        "${if (phone.area.isBlank()) ""
+                        else "(${phone.area}) "}${phone.prefix}-${phone.number}"
+                    ) { text = it }
+                }
+            }
+
+            // <PhoneView phone />
+            call(453, { changed(phone) }) {
+                PhoneView(phone)
+            }
+        }.then { _ ->
+            assertEquals(1, phoneCalled)
+        }.then { _ ->
+            assertEquals(1, phoneCalled)
+
+            phone = Phone("124", "456", "7890")
+        }.then { _ ->
+            assertEquals(2, phoneCalled)
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun testComposableFunctionInvocationTwoParameters() {
+        val tvId = 279
+        var left = 0
+        var right = 1
+        var addCalled = 0
+        compose {
+
+            // Composition function
+            //  @Composable
+            //  fun AddView(left: Int, right: Int) {
+            //    addCalled++
+            //   <TextView text="$left + $right = ${left + right}" />
+            //  }
+            fun AddView(left: Int, right: Int) {
+                addCalled++
+                emit(292, { context -> TextView(context).apply { id = tvId } }) {
+                    set("$left + $right = ${left + right}") { text = it }
+                }
+            }
+
+            // <AddView left right />
+            call(491, { changed(left) + changed(right) }) {
+                AddView(left, right)
+            }
+        }.then { activity ->
+            assertEquals(1, addCalled)
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+        }.then { activity ->
+            assertEquals(1, addCalled)
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+
+            left = 1
+        }.then { activity ->
+            assertEquals(2, addCalled)
+
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+        }.then { activity ->
+            assertEquals(2, addCalled)
+
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+
+            right = 41
+        }.then { activity ->
+            assertEquals(3, addCalled)
+
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun testStatelessComposableClassInvocationProperties() {
+        val tvId = 338
+        var addCalled = 0
+
+        var left = 0
+        var right = 0
+        compose {
+            // TODO: The composition field is a work-around for an IR bug. The IR doesn't support a
+            // local class capturing a variable so this make the capture explicit
+            class AddView(val composition: ViewComposition) {
+                var left = 0
+                var right = 0
+
+                operator fun invoke() {
+                    with(composition) {
+                        // <TextView "$left + $right = ${left + right}" />
+                        emit(350, { context -> TextView(context).apply { id = tvId } }) {
+                            addCalled++
+                            set(
+                                "${this@AddView.left} + ${this@AddView.right} = ${
+                                this@AddView.left + this@AddView.right}"
+                            ) { text = it }
+                        }
+                    }
+                }
+            }
+
+            // <AddView left right />
+            call(358,
+                { AddView(this@compose) },
+                { f -> set(left) { f.left = it } + set(right) { f.right = it } }) { f ->
+                f()
+            }
+        }.then { activity ->
+            assertEquals(1, addCalled)
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+        }.then { activity ->
+            assertEquals(1, addCalled)
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+
+            left = 1
+        }.then { activity ->
+            assertEquals(2, addCalled)
+
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+        }.then { activity ->
+            assertEquals(2, addCalled)
+
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+
+            right = 41
+        }.then { activity ->
+            assertEquals(3, addCalled)
+
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun testStatelessComposableClassInvocationParameters() {
+        val tvId = 338
+        var addCalled = 0
+
+        var left = 0
+        var right = 0
+
+        compose {
+            // TODO: The composition field is a work-around for an IR bug. The IR doesn't support a
+            // local class capturing a variable so this make the capture explicit
+            class AddView(val composition: ViewComposition) {
+
+                operator fun invoke(left: Int, right: Int) {
+                    with(composition) {
+                        // <TextView "$left + $right = ${left + right}" />
+                        emit(350, { context -> TextView(context).apply { id = tvId } }) {
+                            addCalled++
+                            set("$left + $right = ${left + right}") { text = it }
+                        }
+                    }
+                }
+            }
+
+            // <AddView left right />
+            call(612, { changed(left) + changed(right) }) {
+                AddView(this@compose)(left, right)
+            }
+        }.then { activity ->
+            assertEquals(1, addCalled)
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+        }.then { activity ->
+            assertEquals(1, addCalled)
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+
+            left = 1
+        }.then { activity ->
+            assertEquals(2, addCalled)
+
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+        }.then { activity ->
+            assertEquals(2, addCalled)
+
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+
+            right = 41
+        }.then { activity ->
+            assertEquals(3, addCalled)
+
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun testStatefulComposableClassInvocation() {
+        val tvId = 470
+        val tvPrivateValue = 471
+        var addCalled = 0
+
+        var left = 0
+        var right = 0
+
+        lateinit var updatePrivate: (value: String) -> Unit
+
+        compose {
+            // TODO: The composition field is a work-around for an IR bug. The IR doesn't support a
+            // local class capturing a variable so this make the capture explicit
+            class AddView(val composition: ViewComposition) {
+
+                var left = 0
+                var right = 0
+
+                private var privateValue = "Unmodified"
+
+                operator fun invoke() {
+                    with(composition) {
+                        addCalled++
+
+                        // <TextView "$left + $right = ${left + right}" />
+                        emit(491, { context -> TextView(context).apply { id = tvId } }) {
+                            set(
+                                "${this@AddView.left} + ${this@AddView.right} = ${
+                                this@AddView.left + this@AddView.right}"
+                            ) { text = it }
+                        }
+
+                        emit(496, { context ->
+                            TextView(context).apply {
+                                id = tvPrivateValue
+                            }
+                        }) {
+                            set(privateValue) { text = it }
+                        }
+
+                        updatePrivate = {
+                            privateValue = it
+                            // TODO: This actually requires recompose(). Update when that is
+                            // available recompose()
+                        }
+                    }
+                }
+            }
+
+            // <AddView left right />
+            // TODO: remove the + true when recompose() is available.
+            call(690,
+                { AddView(this@compose) },
+                { f -> set(left) { f.left = it } + set(right) { f.right = it } + true }) { f ->
+                f()
+            }
+        }.then { activity ->
+            assertEquals(1, addCalled)
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+        }.then { activity ->
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+
+            left = 1
+        }.then { activity ->
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+        }.then { activity ->
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+
+            right = 41
+        }.then { activity ->
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+
+            val privateTv = activity.findViewById(tvPrivateValue) as TextView
+            assertEquals("Unmodified", privateTv.text)
+
+            updatePrivate("Modified value")
+        }.then { activity ->
+            val privateTv = activity.findViewById(tvPrivateValue) as TextView
+            assertEquals("Modified value", privateTv.text)
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun testStatefulComposableClassWithCtorParametersInvocation() {
+        val tvId = 604
+        val tvOffsetId = 605
+
+        var offset = 0
+        var left = 0
+        var right = 0
+        compose {
+            // TODO: The composition field is a work-around for an IR bug. The IR doesn't support a
+            // local class capturing a variable so this make the capture explicit
+            class OffsetAddView(
+                val composition: ViewComposition,
+                var offset: Int
+            ) {
+
+                var left = 0
+                var right = 0
+
+                operator fun invoke() {
+                    with(composition) {
+
+                        // <TextView "$left + $right = ${left + right}" />
+                        emit(619, { context -> TextView(context).apply { id = tvId } }) {
+                            set(
+                                "${this@OffsetAddView.left} + ${this@OffsetAddView.right} = ${
+                                this@OffsetAddView.left + this@OffsetAddView.right}"
+                            ) {
+                                text = it
+                            }
+                        }
+
+                        // <TextView text="$offset" />
+                        emit(623, { context -> TextView(context).apply { id = tvOffsetId } }) {
+                            set("$offset") { this.text = it }
+                        }
+                    }
+                }
+            }
+
+            // <OffsetAddView offset left right />
+            call(768,
+                { OffsetAddView(this@compose, offset) },
+                { f ->
+                    update(offset) { f.offset = it } + set(left) { f.left = it } + set(right) {
+                        f.right = it
+                    }
+                }
+            ) { f ->
+                f()
+            }
+        }.then { activity ->
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+
+            val offsetTv = activity.findViewById(tvOffsetId) as TextView
+            assertEquals("$offset", offsetTv.text)
+
+            offset = 30
+        }.then { activity ->
+            val offsetTv = activity.findViewById(tvOffsetId) as TextView
+            assertEquals("$offset", offsetTv.text)
+
+            left = 20
+            right = 21
+        }.then { activity ->
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun testStatefulComposableClassWithPivotalProperty() {
+        val tvId = 604
+        val tvOffsetId = 605
+
+        var offset = 0
+        var left = 0
+        var right = 0
+        compose {
+            // TODO: The composition field is a work-around for an IR bug. The IR doesn't support a
+            // local class capturing a variable so this make the capture explicit
+            class OffsetAddView(
+                val composition: ViewComposition,
+                val offset: Int
+            ) {
+
+                var left = 0
+                var right = 0
+
+                operator fun invoke() {
+                    with(composition) {
+
+                        // <TextView "$left + $right = ${left + right}" />
+                        emit(709, { context -> TextView(context).apply { id = tvId } }) {
+                            set(
+                                "${this@OffsetAddView.left} + ${this@OffsetAddView.right} = ${
+                                this@OffsetAddView.left + this@OffsetAddView.right}"
+                            ) {
+                                text = it
+                            }
+                        }
+
+                        // <TextView text="$offset" />
+                        emit(714, { context ->
+                            TextView(context).apply {
+                                id = tvOffsetId
+                            }
+                        }) {
+                            set("${this@OffsetAddView.offset}") { this.text = it }
+                        }
+                    }
+                }
+            }
+
+            // <OffsetAddView offset left right />
+            call(joinKey(831, offset),
+                { OffsetAddView(this@compose, offset) },
+                { f -> set(left) { f.left = it } + set(right) { f.right = it } }) { f ->
+                f()
+            }
+        }.then { activity ->
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+
+            val offsetTv = activity.findViewById(tvOffsetId) as TextView
+            assertEquals("$offset", offsetTv.text)
+
+            offset = 30
+        }.then { activity ->
+            val offsetTv = activity.findViewById(tvOffsetId) as TextView
+            assertEquals("$offset", offsetTv.text)
+
+            left = 20
+            right = 21
+        }.then { activity ->
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("$left + $right = ${left + right}", tv.text)
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun testMoveComponents() {
+        val data = mutableListOf(1, 2, 3, 4, 5)
+        compose {
+            for (item in data) {
+                emit(joinKey(560, item), { context ->
+                    TextView(context).apply { text = "$item View" }
+                }) { }
+            }
+        }.then {
+            data.add(data.removeAt(0))
+        }.then { activity ->
+            val root = activity.root
+            for (index in 0 until data.size) {
+                val textView = root.getChildAt(index) as TextView
+                assertEquals("${data[index]} View", textView.text)
+            }
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun testViewClassWithCtorParametersInvocation() {
+        val tvId = 749
+
+        class MyTextView(context: Context) : TextView(context) {
+            constructor(context: Context, someText: String) : this(context) {
+                text = someText
+            }
+        }
+
+        var hello = "Hello world!"
+        compose {
+            // <MyTextView someText=hello />
+            emit(joinKey(760, hello), { context ->
+                MyTextView(context, hello).apply { id = tvId }
+            }) { }
+        }.then { activity ->
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("Hello world!", tv.text)
+
+            hello = "Salutations!"
+        }.then { activity ->
+            val tv = activity.findViewById(tvId) as TextView
+            assertEquals("Salutations!", tv.text)
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun testViewClassWithMutableCtorParameter() {
+        val tvId = 749
+
+        class MyTextView(context: Context, var someValue: String) : TextView(context)
+
+        var hello = "Hello world!"
+        var value = "Unmodified"
+        compose {
+            // <MyTextView someText=hello />
+            emit(760, { context -> MyTextView(context, value).apply { id = tvId } }) {
+                update(value) { someValue = it }
+                set(hello) { this.text = it }
+            }
+        }.then { activity ->
+            val tv = activity.findViewById(tvId) as MyTextView
+            assertEquals("Hello world!", tv.text)
+            assertEquals("Unmodified", tv.someValue)
+
+            hello = "Salutations!"
+            value = "Modified"
+        }.then { activity ->
+            val tv = activity.findViewById(tvId) as MyTextView
+            assertEquals("Salutations!", tv.text)
+            assertEquals("Modified", tv.someValue)
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun testEmittingAnEmittable() {
+
+        class MyEmittable : MockEmittable() {
+            var message: String = ""
+        }
+
+        compose {
+            adaptable {
+                emit(615, { context -> LinearLayout(context) }, {}) {
+                    emit(616, { -> MyEmittable() }, { set("Message") { message = it } }) {
+                        emit(617, { context -> TextView(context) }, {
+                            set("SomeValue") { text = it }
+                        })
+                        emit(620, { -> MyEmittable() }, { set("Message2") { message = it } })
+                    }
+                }
+            }
+        }.then { activity ->
+            val root = activity.root.getChildAt(0) as LinearLayout
+            val firstChild = root.getChildAt(0) as ViewEmitWrapper
+            val emitted = firstChild.emittable as MockEmittable
+            val firstEmitChild = emitted.children[0] as EmitViewWrapper
+            firstEmitChild.view as TextView
+            val secondEmit = emitted.children[1] as MyEmittable
+            assertEquals(0, secondEmit.children.size)
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun testCGEmittingAnEmittable() {
+
+        class MyEmittable : MockEmittable() {
+            var message: String = ""
+        }
+
+        composeCG {
+            adaptable {
+                val cc = composer
+                cc.emitViewGroup(615, { context -> LinearLayout(context) }, {}) {
+                    cc.emitEmittable(616, { -> MyEmittable() }, {
+                        set("Message") { message = it }
+                    }) {
+                        cc.emit(617, { context -> TextView(context) }, {
+                            set("SomeValue") { text = it }
+                        })
+                        cc.emitEmittable(620, { -> MyEmittable() }, {
+                            set("Message2") { message = it }
+                        })
+                    }
+                }
+            }
+        }.then { activity ->
+            val root = activity.root.getChildAt(0) as LinearLayout
+            val firstChild = root.getChildAt(0) as ViewEmitWrapper
+            val emitted = firstChild.emittable as MockEmittable
+            val firstEmitChild = emitted.children[0] as EmitViewWrapper
+            firstEmitChild.view as TextView
+            val secondEmit = emitted.children[1] as MyEmittable
+            assertEquals(0, secondEmit.children.size)
+        }.then { activity ->
+            val root = activity.root.getChildAt(0) as LinearLayout
+            val firstChild = root.getChildAt(0) as ViewEmitWrapper
+            val emitted = firstChild.emittable as MockEmittable
+            val firstEmitChild = emitted.children[0] as EmitViewWrapper
+            firstEmitChild.view as TextView
+            val secondEmit = emitted.children[1] as MyEmittable
+            assertEquals(0, secondEmit.children.size)
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun testCGEmittableAsRoot() {
+        class MyEmittable : MockEmittable() {
+            var message: String = ""
+        }
+
+        val root = MyEmittable()
+
+        var first = "Hi"
+        var second = "there"
+        composeCG { activity ->
+            adaptable {
+                Compose.composeInto(root, activity) {
+                    val cc = composer
+                    cc.emitEmittable(686, { MyEmittable() }, { set(first) { message = it } }) {
+                        cc.emitEmittable(687, { MyEmittable() }, {
+                            set(second) { message = it }
+                        })
+                    }
+                }
+            }
+        }.then {
+            assertEquals(first, (root.children.first() as MyEmittable).message)
+            assertEquals(
+                second,
+                ((root.children.first() as MyEmittable).children.first() as MyEmittable).message
+            )
+
+            first = "hello"
+            second = "dolly"
+        }.then {
+            assertEquals(first, (root.children.first() as MyEmittable).message)
+            assertEquals(
+                second,
+                ((root.children.first() as MyEmittable).children.first() as MyEmittable).message
+            )
+        }
+    }
+
+    open class MockEmittable : Emittable {
+        val children = mutableListOf<Emittable>()
+        override fun emitInsertAt(index: Int, instance: Emittable) {
+            children.add(index, instance)
+        }
+
+        override fun emitRemoveAt(index: Int, count: Int) {
+            children.subList(index, count).clear()
+        }
+
+        override fun emitMove(from: Int, to: Int, count: Int) {
+            val range = children.subList(from, count)
+            val moved = range.map { it }
+            range.clear()
+            children.addAll(if (to > from) to - count else to, moved)
+        }
+    }
+
+    class ViewEmitWrapper(context: Context) : View(context) {
+        var emittable: Emittable? = null
+    }
+
+    class EmitViewWrapper : MockEmittable() {
+        var view: View? = null
+    }
+
+    fun ViewComposition.adaptable(block: ViewComposition.() -> Unit) {
+        composer.adapters?.register { parent, child ->
+            when (parent) {
+                is ViewGroup -> when (child) {
+                    is View -> child
+                    is Emittable -> ViewEmitWrapper(composer.context).apply { emittable = child }
+                    else -> null
+                }
+                is Emittable -> when (child) {
+                    is View -> EmitViewWrapper().apply { view = child }
+                    is Emittable -> child
+                    else -> null
+                }
+                else -> null
+            }
+        }
+        block()
+    }
+
+    fun compose(block: ViewComposition.() -> Unit) =
+        CompositionTest(activityRule.activity, block)
+
+    class CompositionTest(val activity: Activity, val composable: ViewComposition.() -> Unit) {
+
+        inner class ActiveTest(val composition: ViewComposition, val activity: Activity) {
+            private fun compose() {
+                composition.composer.startRoot()
+                composition.composable()
+                composition.composer.endRoot()
+                composition.composer.applyChanges()
+            }
+
+            fun then(block: (activity: Activity) -> Unit): ActiveTest {
+                compose()
+                block(activity)
+                return this
+            }
+        }
+
+        fun then(block: (activity: Activity) -> Unit): ActiveTest {
+            val composition = ViewComposition(
+                ViewComposer(activity.root, activity, object : Recomposer() {
+                    override fun scheduleChangesDispatch() {}
+
+                    override fun hasPendingChanges(): Boolean = false
+                })
+            )
+            return ActiveTest(composition, activity).then(block)
+        }
+    }
+
+    class TestContext(val cc: CompositionContext) {
+        fun adaptable(block: TestContext.() -> Unit) {
+            composer.registerAdapter { parent, child ->
+                when (parent) {
+                    is ViewGroup -> when (child) {
+                        is View -> child
+                        is Emittable -> ViewEmitWrapper(parent.context).apply { emittable = child }
+                        else -> null
+                    }
+                    is Emittable -> when (child) {
+                        is View -> EmitViewWrapper().apply { view = child }
+                        is Emittable -> child
+                        else -> null
+                    }
+                    else -> null
+                }
+            }
+            block()
+        }
+    }
+
+    fun composeCG(block: TestContext.(activity: Activity) -> Unit) =
+        CompositionCodeGenTest(activityRule.activity, block)
+
+    private class Root : Component() {
+        override fun compose() {}
+    }
+
+    class CompositionCodeGenTest(
+        val activity: Activity,
+        val composable: TestContext.(activity: Activity) -> Unit
+    ) {
+        inner class ActiveTest(
+            val activity: Activity,
+            val context: TestContext
+        ) {
+
+            fun then(block: TestContext.(activity: Activity) -> Unit): ActiveTest {
+                val composer = context.cc.composer
+                composer.runWithCurrent {
+                    composer.startRoot()
+                    context.composable(activity)
+                    composer.endRoot()
+                    composer.applyChanges()
+                    context.block(activity)
+                }
+                return this
+            }
+        }
+
+        fun then(block: TestContext.(activity: Activity) -> Unit): ActiveTest {
+            val root = activity.root
+            val component = Root()
+            val cc = Compose.createCompositionContext(root.context, root, component, null)
+            return ActiveTest(activity, TestContext(cc)).then(block)
+        }
+    }
+}
+
+@RunWith(AndroidJUnit4::class)
+class DisposeTests {
+
+    @get:Rule
+    val disposeActivityRule = ActivityTestRule(DisposeTestActivity::class.java)
+
+    class DisposeTestActivity : Activity() {
+        lateinit var root: ViewGroup
+        override fun onCreate(savedInstanceState: Bundle?) {
+            super.onCreate(savedInstanceState)
+            root = FrameLayout(this)
+            root.id = ComposerComposeTestCase.ROOT_ID
+            setContentView(root)
+        }
+    }
+
+    @Test
+    @SmallTest
+    fun testDisposeComposition() {
+        val log = mutableListOf<String>()
+
+        val composable = @Composable {
+            +onPreCommit {
+                log.add("onPreCommit")
+                onDispose {
+                    log.add("onPreCommitDispose")
+                }
+            }
+            +onActive {
+                log.add("onActive")
+                onDispose {
+                    log.add("onActiveDispose")
+                }
+            }
+        }
+
+        val activity = disposeActivityRule.activity
+
+        fun assertLog(expected: String, block: () -> Unit) {
+            log.clear()
+            block()
+            assertEquals(expected, log.joinToString())
+        }
+
+        assertLog("onPreCommit, onActive") {
+            activity.show(composable)
+            activity.waitForAFrame()
+        }
+
+        assertLog("onPreCommitDispose, onPreCommit") {
+            activity.show(composable)
+            activity.waitForAFrame()
+        }
+
+        assertLog("onActiveDispose, onPreCommitDispose") {
+            activity.disposeTestComposition()
+            activity.waitForAFrame()
+        }
+
+        assertLog("onPreCommit, onActive") {
+            activity.show(composable)
+            activity.waitForAFrame()
+        }
+    } }
+
+internal val Activity.root get() = findViewById(ComposerComposeTestCase.ROOT_ID) as ViewGroup
+
+internal fun Activity.uiThread(block: () -> Unit) {
+    runOnUiThread(object : Runnable {
+        override fun run() {
+            block()
+        }
+    })
+}
+
+internal fun Activity.disposeTestComposition() {
+    uiThread {
+        Compose.disposeComposition(root)
+    }
+}
+
+internal fun Activity.show(block: @Composable() () -> Unit) {
+    uiThread {
+        FrameManager.nextFrame()
+        Compose.composeInto(container = root, composable = block)
+    }
+}
+
+internal fun Activity.waitForAFrame() {
+    if (Looper.getMainLooper() == Looper.myLooper()) {
+        throw Exception("Cannot be run from the main looper thread")
+    }
+    val latch = CountDownLatch(1)
+    uiThread {
+        Choreographer.postFrameCallback(object : ChoreographerFrameCallback {
+            override fun doFrame(frameTimeNanos: Long) = latch.countDown()
+        })
+    }
+    Assert.assertTrue(latch.await(1, TimeUnit.MINUTES))
+}
diff --git a/compose/compose-runtime/src/androidMain/AndroidManifest.xml b/compose/compose-runtime/src/androidMain/AndroidManifest.xml
index cd9867b..ddf4182b 100644
--- a/compose/compose-runtime/src/androidMain/AndroidManifest.xml
+++ b/compose/compose-runtime/src/androidMain/AndroidManifest.xml
@@ -13,10 +13,4 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<manifest package="androidx.compose.runtime" xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <application/>
-
-
-</manifest>
-
+<manifest package="androidx.compose.runtime"/>
diff --git a/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ActualAndroid.kt b/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ActualAndroid.kt
index 60234d1..7fc2dcd 100644
--- a/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ActualAndroid.kt
+++ b/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ActualAndroid.kt
@@ -64,14 +64,16 @@
 }
 
 // TODO(b/137794558): Create portable abstraction for scheduling
+actual typealias ChoreographerFrameCallback = android.view.Choreographer.FrameCallback
+
 actual object Choreographer {
-    actual fun postFrameCallback(callback: (Long) -> Unit) {
+    actual fun postFrameCallback(callback: ChoreographerFrameCallback) {
         android.view.Choreographer.getInstance().postFrameCallback(callback)
     }
-    actual fun postFrameCallbackDelayed(delayMillis: Long, callback: (Long) -> Unit) {
+    actual fun postFrameCallbackDelayed(delayMillis: Long, callback: ChoreographerFrameCallback) {
         android.view.Choreographer.getInstance().postFrameCallbackDelayed(callback, delayMillis)
     }
-    actual fun removeFrameCallback(callback: (Long) -> Unit) {
+    actual fun removeFrameCallback(callback: ChoreographerFrameCallback) {
         android.view.Choreographer.getInstance().removeFrameCallback(callback)
     }
 }
diff --git a/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ActualJvm.kt b/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ActualJvm.kt
index 7762a4c..dce8cf8 100644
--- a/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ActualJvm.kt
+++ b/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ActualJvm.kt
@@ -34,9 +34,6 @@
 
 actual typealias WeakHashMap<K, V> = java.util.WeakHashMap<K, V>
 
-internal actual fun arraycopy(source: Any, sourcePos: Int, dest: Any, destPos: Int, len: Int) =
-    System.arraycopy(source, sourcePos, dest, destPos, len)
-
 actual fun identityHashCode(instance: Any?): Int = System.identityHashCode(instance)
 
 actual inline fun <R> synchronized(lock: Any, block: () -> R): R {
diff --git a/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/KeySourceInfo.kt b/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/KeySourceInfo.kt
new file mode 100644
index 0000000..03408d6
--- /dev/null
+++ b/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/KeySourceInfo.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2019 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
+
+internal val keyInfo = mutableMapOf<Int, String>()
+
+private fun findSourceKey(key: Any): Int? =
+    when (key) {
+        is Int -> key
+        is JoinedKey -> {
+            key.left?.let { findSourceKey(it) } ?: key.right?.let { findSourceKey(it) }
+        }
+        else -> null
+    }
+
+internal actual fun recordSourceKeyInfo(key: Any) {
+    val sk = findSourceKey(key)
+    sk?.let {
+        keyInfo.getOrPut(sk, {
+            val stack = Thread.currentThread().stackTrace
+            // On Android the frames looks like:
+            //  0: getThreadStackTrace() (native method)
+            //  1: getStackTrace()
+            //  2: recordSourceKey()
+            //  3: start()
+            //  4: startGroup() or startNode()
+            //  5: <calling method>
+            // On a desktop VM this looks like:
+            //  0: getStackTrace()
+            //  1: recordSourceKey()
+            //  2: start()
+            //  3: startGroup() or startNode()
+            //  4: <calling method>
+            // If the stack method at 4 is startGroup assume we want 5 instead.
+            val frame = stack[4].let {
+                if (it.methodName == "startGroup" || it.methodName == "startNode") stack[5] else it
+            }
+            "${frame.fileName}:${frame.lineNumber}"
+        })
+    }
+}
+
+actual fun keySourceInfoOf(key: Any): String? = keyInfo[key]
diff --git a/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ViewComposer.kt b/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ViewComposer.kt
index c93eaf0..08ec161 100644
--- a/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ViewComposer.kt
+++ b/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ViewComposer.kt
@@ -170,12 +170,13 @@
         endNode()
     }
 
+    @Suppress("PLUGIN_WARNING")
     inline fun <T : ViewGroup> emit(
         key: Any,
         /*crossinline*/
         ctor: (context: Context) -> T,
         update: ViewUpdater<T>.() -> Unit,
-        children: () -> Unit
+        children: @Composable() () -> Unit
     ) = with(composer) {
         startNode(key)
         val node = if (inserting) ctor(context).also { emitNode(it) }
@@ -198,12 +199,13 @@
         endNode()
     }
 
+    @Suppress("PLUGIN_WARNING")
     inline fun <T : Emittable> emit(
         key: Any,
         /*crossinline*/
         ctor: () -> T,
         update: ViewUpdater<T>.() -> Unit,
-        children: () -> Unit
+        children: @Composable() () -> Unit
     ) = with(composer) {
         startNode(key)
         val node = if (inserting) ctor().also { emitNode(it) }
@@ -216,11 +218,12 @@
     @Suppress("NOTHING_TO_INLINE")
     inline fun joinKey(left: Any, right: Any?): Any = composer.joinKey(left, right)
 
+    @Suppress("PLUGIN_WARNING")
     inline fun call(
         key: Any,
         /*crossinline*/
         invalid: ViewValidator.() -> Boolean,
-        block: () -> Unit
+        block: @Composable() () -> Unit
     ) = with(composer) {
         startGroup(key)
         if (ViewValidator(composer).invalid() || inserting) {
diff --git a/compose/compose-runtime/src/androidTest/AndroidManifest.xml b/compose/compose-runtime/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 356bbf4..0000000
--- a/compose/compose-runtime/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright 2019 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 package="androidx.ui.material" xmlns:android="http://schemas.android.com/apk/res/android">
-     <application/>
-
-</manifest>
diff --git a/compose/compose-runtime/src/androidTest/java/EMPTY_FILE b/compose/compose-runtime/src/androidTest/java/EMPTY_FILE
new file mode 100644
index 0000000..d2b6b6f
--- /dev/null
+++ b/compose/compose-runtime/src/androidTest/java/EMPTY_FILE
@@ -0,0 +1,4 @@
+This file is needed to work around a problem with the Kotlin-MPP plugin with
+single-Kotlin-module test structure.  Without this file,
+./gradlew :compose:compose-runtime:connectedAndroidTest
+does not do anything.  See b/139385662 for more details.
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Component.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Component.kt
index 809eb78..1bc0663 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Component.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Component.kt
@@ -55,8 +55,7 @@
 @Suppress("PLUGIN_ERROR")
 abstract class Component {
     @HiddenAttribute
-    // TODO(138720404): Investigate if Compose APIs can be internal despite MPP limitations
-    var recomposeCallback: ((sync: Boolean) -> Unit)? = null
+    internal var recomposeCallback: ((sync: Boolean) -> Unit)? = null
     private var composing = false
 
     /**
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composer.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composer.kt
index d0f032a..40e9e13 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composer.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composer.kt
@@ -171,10 +171,10 @@
 
 // TODO(lmr): this could be named MutableTreeComposer
 open class Composer<N>(
-    private val slotTable: SlotTable,
+    val slotTable: SlotTable,
     private val applier: Applier<N>,
     private val recomposer: Recomposer
-) : Composition<N>() {
+) {
     private val changes = mutableListOf<Change<N>>()
     private val lifecycleObservers = mutableMapOf<
             CompositionLifecycleObserverHolder,
@@ -188,6 +188,7 @@
     private var nodeIndexStack = IntStack()
     private var groupNodeCount: Int = 0
     private var groupNodeCountStack = IntStack()
+    private var collectKeySources = false
 
     private var childrenAllowed = true
     private var invalidations: MutableList<Invalidation> = mutableListOf()
@@ -241,7 +242,11 @@
         slots.close()
     }
 
-    override val inserting: Boolean get() = slots.inEmpty
+    val inserting: Boolean get() = slots.inEmpty
+
+    fun collectKeySourceInformation() {
+        collectKeySources = true
+    }
 
     fun applyChanges() {
         trace("Compose:applyChanges") {
@@ -299,10 +304,10 @@
         }
     }
 
-    override fun startGroup(key: Any) = start(key, START_GROUP)
-    override fun endGroup() = end(END_GROUP)
+    fun startGroup(key: Any) = start(key, START_GROUP)
+    fun endGroup() = end(END_GROUP)
 
-    override fun skipGroup() {
+    fun skipGroup() {
         recordSkip(START_GROUP)
         groupNodeCount += slots.skipGroup()
     }
@@ -313,13 +318,13 @@
         skipGroupAndRecomposeRange()
     }
 
-    override fun startNode(key: Any) {
+    fun startNode(key: Any) {
         start(key, START_NODE)
         childrenAllowed = false
     }
 
     // Deprecated
-    override fun <T : N> emitNode(factory: () -> T) {
+    fun <T : N> emitNode(factory: () -> T) {
         if (inserting) {
             val insertIndex = nodeIndexStack.peek()
             // The pending is the pending information for where the node is being inserted.
@@ -339,7 +344,7 @@
         childrenAllowed = true
     }
 
-    override fun <T : N> createNode(factory: () -> T) {
+    fun <T : N> createNode(factory: () -> T) {
         val insertIndex = nodeIndexStack.peek()
         // see emitNode
         pending?.let { it.nodeCount++ }
@@ -353,7 +358,7 @@
         childrenAllowed = true
     }
 
-    override fun emitNode(node: N) {
+    fun emitNode(node: N) {
         require(inserting) { "emitNode() called when not inserting" }
         val insertIndex = nodeIndexStack.peek()
         // see emitNode
@@ -367,7 +372,7 @@
         childrenAllowed = true
     }
 
-    override fun useNode(): N {
+    fun useNode(): N {
         require(!inserting) { "useNode() called while inserting" }
         recordDown()
         val result = slots.next()
@@ -376,24 +381,24 @@
         return result as N
     }
 
-    override fun endNode() {
+    fun endNode() {
         end(END_NODE)
     }
 
-    override fun <V, T> apply(value: V, block: T.(V) -> Unit) {
+    fun <V, T> apply(value: V, block: T.(V) -> Unit) {
         recordOperation { applier, _, _ ->
             @Suppress("UNCHECKED_CAST")
             (applier.current as T).block(value)
         }
     }
 
-    override fun joinKey(left: Any?, right: Any?): Any =
+    fun joinKey(left: Any?, right: Any?): Any =
         getKey(slots.get(slots.current), left, right)
             ?: JoinedKey(left, right)
 
-    override fun nextSlot(): Any? = slots.next()
+    fun nextSlot(): Any? = slots.next()
 
-    override fun skipValue() = recordSlotNext()
+    fun skipValue() = recordSlotNext()
 
     fun <T> changed(value: T): Boolean {
         return if (nextSlot() != value || inserting) {
@@ -405,7 +410,7 @@
         }
     }
 
-    override fun updateValue(value: Any?) {
+    fun updateValue(value: Any?) {
         recordOperation { _, slots, lifecycleManager ->
             val previous = if (value is CompositionLifecycleObserver) {
                 val slotValue = lifecycleManager.entering(
@@ -441,7 +446,7 @@
         endGroup()
     }
 
-    internal fun <T> consume(key: Ambient<T>): T = trace("Compose:consumeAmbient:$key") {
+    internal fun <T> consume(key: Ambient<T>): T {
         startGroup(consumer)
         changed(key)
         changed(invalidateStack.peek())
@@ -542,50 +547,48 @@
     private fun <T> invalidateConsumers(key: Ambient<T>) {
         // Inserting components don't have children yet.
         if (!inserting) {
-            trace("Compose:invalidateAmbient:$key") {
-                // Get the parent size from the slot table
-                val startStack = slots.startStack
-                val containingGroupIndex = if (startStack.isEmpty()) 1 else startStack.peek()
-                val start = containingGroupIndex + 1
-                val end = start + slots.groupSize(containingGroupIndex)
-                var index = start
+            // Get the parent size from the slot table
+            val startStack = slots.startStack
+            val containingGroupIndex = if (startStack.isEmpty()) 1 else startStack.peek()
+            val start = containingGroupIndex + 1
+            val end = start + slots.groupSize(containingGroupIndex)
+            var index = start
 
-                // Check the slots in range for recomposabile instances
-                loop@ while (index < end) {
-                    // A recomposable (i.e. a component) will always be in the first slot after the
-                    // group marker.  This is true because that is where the recompose routine will look
-                    // for it. If the slot does not hold a recomposable it is not a recomposable group
-                    // so skip it.
-                    if (slots.isGroup(index)) {
-                        val sentinel = slots.get(index - 1)
-                        when {
-                            sentinel === consumer -> {
-                                val ambient = slots.get(index + 1)
-                                if (ambient == key) {
-                                    val scope = slots.get(index + 2)
-                                    if (scope is RecomposeScope) {
-                                        scope.invalidate?.let { it(false) }
-                                    }
-                                }
-                            }
-                            sentinel === provider -> {
-                                val element = slots.get(index + 1)
-                                if (element is Ambient.Holder<*> && element.ambient == key) {
-                                    index += slots.groupSize(index)
-                                    continue@loop
-                                }
-                            }
-                            sentinel === reference -> {
-                                val element = slots.get(index + 1)
-                                if (element is CompositionLifecycleObserverHolder) {
-                                    val subElement = element.instance as CompositionReference
-                                    subElement.invalidateConsumers(key)
+            // Check the slots in range for recomposabile instances
+            loop@ while (index < end) {
+                // A recomposable (i.e. a component) will always be in the first slot after the
+                // group marker.  This is true because that is where the recompose routine will look
+                // for it. If the slot does not hold a recomposable it is not a recomposable group
+                // so skip it.
+                if (slots.isGroup(index)) {
+                    val sentinel = slots.get(index - 1)
+                    when {
+                        sentinel === consumer -> {
+                            val ambient = slots.get(index + 1)
+                            if (ambient == key) {
+                                val scope = slots.get(index + 2)
+                                if (scope is RecomposeScope) {
+                                    scope.invalidate?.let { it(false) }
                                 }
                             }
                         }
+                        sentinel === provider -> {
+                            val element = slots.get(index + 1)
+                            if (element is Ambient.Holder<*> && element.ambient == key) {
+                                index += slots.groupSize(index)
+                                continue@loop
+                            }
+                        }
+                        sentinel === reference -> {
+                            val element = slots.get(index + 1)
+                            if (element is CompositionLifecycleObserverHolder) {
+                                val subElement = element.instance as CompositionReference
+                                subElement.invalidateConsumers(key)
+                            }
+                        }
                     }
-                    index += 1
                 }
+                index += 1
             }
         }
     }
@@ -603,6 +606,8 @@
         // there is no need to track insert, deletes and moves with a pending changes object.
         if (inserting) {
             slots.beginEmpty()
+            if (collectKeySources)
+                recordSourceKeyInfo(key)
             recordOperation { _, slots, _ ->
                 slots.update(key)
                 slots.start(action)
@@ -686,6 +691,8 @@
                     recordOperation { _, slots, _ -> slots.beginInsert() }
                 }
                 slots.beginEmpty()
+                if (collectKeySources)
+                    recordSourceKeyInfo(key)
                 recordOperation { _, slots, _ ->
                     slots.update(key)
                     slots.start(action)
@@ -1288,6 +1295,92 @@
     }
 }
 
+fun <N> Composer<N>.nextValue(): Any? = nextSlot().let {
+    if (it is CompositionLifecycleObserverHolder) it.instance else it
+}
+
+inline fun <N, T> Composer<N>.cache(valid: Boolean = true, block: () -> T): T {
+    var result = nextValue()
+    if (result === SlotTable.EMPTY || !valid) {
+        val value = block()
+        updateValue(value)
+        result = value
+    } else skipValue()
+
+    @Suppress("UNCHECKED_CAST")
+    return result as T
+}
+
+/* inline */
+fun <N, V> Composer<N>.remember(block: () -> V): V = cache(true, block)
+
+/* inline */
+fun <N, V, /* reified */ P1> Composer<N>.remember(p1: P1, block: () -> V) =
+    cache(!changed(p1), block)
+
+/* inline */
+fun <
+        N,
+        V,
+        /* reified */
+        P1,
+        /* reified */
+        P2
+        > Composer<N>.remember(p1: P1, p2: P2, block: () -> V): V {
+    var valid = !changed(p1)
+    valid = !changed(p2) && valid
+    return cache(valid, block)
+}
+
+/* inline */
+fun <
+        N,
+        V,
+        /* reified */
+        P1,
+        /* reified */
+        P2,
+        /* reified */
+        P3
+        > Composer<N>.remember(p1: P1, p2: P2, p3: P3, block: () -> V): V {
+    var valid = !changed(p1)
+    valid = !changed(p2) && valid
+    valid = !changed(p3) && valid
+    return cache(valid, block)
+}
+
+/* inline */
+fun <
+        N,
+        V,
+        /* reified */
+        P1,
+        /* reified */
+        P2,
+        /* reified */
+        P3,
+        /* reified */
+        P4
+        > Composer<N>.remember(
+            p1: P1,
+            p2: P2,
+            p3: P3,
+            p4: P4,
+            block: () -> V
+        ): V {
+    var valid = !changed(p1)
+    valid = !changed(p2) && valid
+    valid = !changed(p3) && valid
+    valid = !changed(p4) && valid
+    return cache(valid, block)
+}
+
+/* inline */ fun <N, V> Composer<N>.remember(vararg args: Any?, block: () -> V): V {
+    var valid = true
+    for (arg in args) valid = !changed(arg) && valid
+    return cache(valid, block)
+}
+
 private fun removeCurrentItem(slots: SlotWriter, lifecycleManager: LifeCycleManager) {
     // Notify the lifecycle manager of any observers leaving the slot table
     // The notification order should ensure that listeners are notified of leaving
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composition.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composition.kt
deleted file mode 100644
index add5f59..0000000
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composition.kt
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2019 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
-
-// TODO(lmr): this should be named Composer. also we can probably remove
-abstract class Composition<N> {
-    abstract val inserting: Boolean
-
-    abstract fun startGroup(key: Any)
-    abstract fun endGroup()
-    abstract fun skipGroup()
-
-    abstract fun startNode(key: Any)
-    // NOTE(lmr): When we move to a model where composition defers creations/mutations to nodes
-    // to the applyChanges phase, we will want to move all usages of emitNode(N) to createNode(() -> T)
-    abstract fun <T : N> emitNode(factory: () -> T) // Deprecated // TODO(lmr): only used in mock
-    // TODO(lmr): never used. replace usages of emitNode?
-    abstract fun <T : N> createNode(factory: () -> T)
-    abstract fun emitNode(node: N) // Deprecated - single threaded
-    abstract fun useNode(): N
-    abstract fun endNode()
-
-    abstract fun joinKey(left: Any?, right: Any?): Any
-
-    abstract fun nextSlot(): Any?
-
-    abstract fun skipValue()
-    abstract fun updateValue(value: Any?)
-    abstract fun <V, T> apply(value: V, block: T.(V) -> Unit)
-}
-
-fun <N> Composition<N>.nextValue(): Any? = nextSlot().let {
-    if (it is CompositionLifecycleObserverHolder) it.instance else it
-}
-
-inline fun <N, T> Composition<N>.cache(valid: Boolean = true, block: () -> T): T {
-    var result = nextValue()
-    if (result === SlotTable.EMPTY || !valid) {
-        val value = block()
-        updateValue(value)
-        result = value
-    } else skipValue()
-
-    @Suppress("UNCHECKED_CAST")
-    return result as T
-}
-
-/* inline */ fun <N, /* reified */ V> Composition<N>.changed(value: V): Boolean {
-    return if (nextSlot() != value) {
-        updateValue(value)
-        true
-    } else {
-        skipValue()
-        false
-    }
-}
-
-/* inline */ fun <N, V> Composition<N>.remember(block: () -> V): V = cache(true, block)
-
-/* inline */ fun <N, V, /* reified */ P1> Composition<N>.remember(p1: P1, block: () -> V) =
-    cache(!changed(p1), block)
-
-/* inline */ fun <
-        N,
-        V,
-        /* reified */
-        P1,
-        /* reified */
-        P2
-        > Composition<N>.remember(p1: P1, p2: P2, block: () -> V): V {
-    var valid = !changed(p1)
-    valid = !changed(p2) && valid
-    return cache(valid, block)
-}
-
-/* inline */ fun <
-        N,
-        V,
-        /* reified */
-        P1,
-        /* reified */
-        P2,
-        /* reified */
-        P3
-        > Composition<N>.remember(p1: P1, p2: P2, p3: P3, block: () -> V): V {
-    var valid = !changed(p1)
-    valid = !changed(p2) && valid
-    valid = !changed(p3) && valid
-    return cache(valid, block)
-}
-
-/* inline */ fun <
-        N,
-        V,
-        /* reified */
-        P1,
-        /* reified */
-        P2,
-        /* reified */
-        P3,
-        /* reified */
-        P4
-        > Composition<N>.remember(
-            p1: P1,
-            p2: P2,
-            p3: P3,
-            p4: P4,
-            block: () -> V
-        ): V {
-    var valid = !changed(p1)
-    valid = !changed(p2) && valid
-    valid = !changed(p3) && valid
-    valid = !changed(p4) && valid
-    return cache(valid, block)
-}
-
-/* inline */ fun <N, V> Composition<N>.remember(vararg args: Any?, block: () -> V): V {
-    var valid = true
-    for (arg in args) valid = !changed(arg) && valid
-    return cache(valid, block)
-}
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Effects.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Effects.kt
index c8560cb..6b7bc94 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Effects.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Effects.kt
@@ -184,7 +184,7 @@
 @PublishedApi
 internal class PostCommitScopeImpl(
     internal val onCommit: CommitScope.() -> Unit
-) : CommitScope, CompositionLifecycleObserver {
+) : CommitScope, CompositionLifecycleObserver, ChoreographerFrameCallback {
 
     private var disposeCallback = emptyDispose
     private var hasRun = false
@@ -196,13 +196,13 @@
         disposeCallback = callback
     }
 
-    private val doFrame: (Long) -> Unit = {
+    override fun doFrame(frameTimeNanos: Long) {
         hasRun = true
         onCommit(this)
     }
 
     override fun onEnter() {
-        Choreographer.postFrameCallback(doFrame)
+        Choreographer.postFrameCallback(this)
     }
 
     override fun onLeave() {
@@ -211,7 +211,7 @@
         if (hasRun) {
             disposeCallback()
         } else {
-            Choreographer.removeFrameCallback(doFrame)
+            Choreographer.removeFrameCallback(this)
         }
     }
 }
@@ -684,9 +684,8 @@
  * @see [state]
  * @see [stateFor]
  */
-// TODO(138720404): Investigate if Compose APIs can be internal despite MPP limitations
 @Model
-class State<T> /*@PublishedApi internal*/ constructor(value: T) : Framed {
+class State<T> @PublishedApi internal constructor(value: T) : Framed {
     /* NOTE(lmr): When this module is compiled with IR, we will need to remove the below Framed implementation */
 
     @Suppress("UNCHECKED_CAST")
@@ -887,4 +886,4 @@
  * Resolves the effect and returns the result.
  */
 @Suppress("NOTHING_TO_INLINE")
-/* inline */ operator fun <T> Effect<T>.unaryPlus(): T = resolve(currentComposerNonNull)
\ No newline at end of file
+/* inline */ operator fun <T> Effect<T>.unaryPlus(): T = resolve(currentComposerNonNull)
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Expect.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Expect.kt
index 59307db..bc96998 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Expect.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Expect.kt
@@ -31,8 +31,6 @@
 
 expect class WeakHashMap<K, V>() : MutableMap<K, V>
 
-internal expect fun arraycopy(source: Any, sourcePos: Int, dest: Any, destPos: Int, len: Int)
-
 expect fun identityHashCode(instance: Any?): Int
 
 expect interface ViewParent
@@ -70,10 +68,14 @@
     fun postAtFrontOfQueue(block: () -> Unit): Boolean
 }
 
+expect interface ChoreographerFrameCallback {
+    fun doFrame(frameTimeNanos: Long)
+}
+
 expect object Choreographer {
-    fun postFrameCallback(callback: (Long) -> Unit)
-    fun postFrameCallbackDelayed(delayMillis: Long, callback: (Long) -> Unit)
-    fun removeFrameCallback(callback: (Long) -> Unit)
+    fun postFrameCallback(callback: ChoreographerFrameCallback)
+    fun postFrameCallbackDelayed(delayMillis: Long, callback: ChoreographerFrameCallback)
+    fun removeFrameCallback(callback: ChoreographerFrameCallback)
 }
 
 @MustBeDocumented
@@ -99,4 +101,4 @@
 @MustBeDocumented
 expect annotation class CheckResult(
     val suggest: String
-)
\ No newline at end of file
+)
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/JoinedKey.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/JoinedKey.kt
index bd37846..aaa79fa 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/JoinedKey.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/JoinedKey.kt
@@ -21,4 +21,15 @@
 internal data class JoinedKey(
     @JvmField val left: Any?,
     @JvmField val right: Any?
-)
\ No newline at end of file
+)
+
+fun isJoinedKey(key: Any?) = key is JoinedKey
+fun joinedKeyLeft(key: Any?): Any? = when (key) {
+    is JoinedKey -> key.left
+    else -> null
+}
+
+fun joinedKeyRight(key: Any?): Any? = when (key) {
+    is JoinedKey -> key.right
+    else -> null
+}
\ No newline at end of file
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/KeySourceInfo.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/KeySourceInfo.kt
new file mode 100644
index 0000000..d428fe6
--- /dev/null
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/KeySourceInfo.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2019 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
+
+internal expect fun recordSourceKeyInfo(key: Any)
+
+expect fun keySourceInfoOf(key: Any): String?
\ No newline at end of file
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Recomposer.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Recomposer.kt
index baa8521..8facd9a 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Recomposer.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Recomposer.kt
@@ -81,8 +81,7 @@
         }
     }
 
-    // TODO(138720404): Investigate if Compose APIs can be internal despite MPP limitations
-    protected abstract fun hasPendingChanges(): Boolean
+    internal abstract fun hasPendingChanges(): Boolean
 
     internal fun scheduleRecompose(composer: Composer<*>) {
         composers.add(composer)
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/SlotTable.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/SlotTable.kt
index d93deac2..0e15904 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/SlotTable.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/SlotTable.kt
@@ -211,6 +211,7 @@
         ) {
             "Invalid state. Start location stack doesn't refer to a start location"
         }
+
         val len = current - startLocation - 1
         if (writing) {
             slots[effectiveStartLocation] = GroupStart(groupKind, len, nodeCount)
@@ -498,13 +499,9 @@
         val newMoveLocation = moveLocation + moveLen
         current = oldCurrent
         nodeCount = oldNodeCount
-        arraycopy(
-            slots,
-            effectiveIndex(newMoveLocation),
-            slots,
-            effectiveIndex(current),
-            moveLen
-        )
+
+        slots.copyInto(slots, effectiveIndex(current),
+            effectiveIndex(newMoveLocation), effectiveIndex(newMoveLocation) + moveLen)
 
         // Before we remove the old location, move any anchors
         table.moveAnchors(newMoveLocation, current, moveLen)
@@ -581,17 +578,12 @@
                 pendingClear = false
                 if (table.anchors.isNotEmpty()) table.updateAnchors(index)
                 if (index < table.gapStart) {
-                    val len = table.gapStart - index
-                    arraycopy(slots, index, slots, index + table.gapLen, len)
+                    slots.copyInto(slots, index + table.gapLen,
+                        index, table.gapStart)
                 } else {
-                    val len = index - table.gapStart
-                    arraycopy(
-                        slots,
+                    slots.copyInto(slots, table.gapStart,
                         table.gapStart + table.gapLen,
-                        slots,
-                        table.gapStart,
-                        len
-                    )
+                        index + table.gapLen)
                 }
                 table.gapStart = index
                 pendingClear = true
@@ -619,8 +611,8 @@
                     val oldGapEnd = table.gapStart + table.gapLen
                     val newGapEnd = table.gapStart + newGapLen
                     // Copy the old array into the new array
-                    arraycopy(slots, 0, newSlots, 0, table.gapStart)
-                    arraycopy(slots, oldGapEnd, newSlots, newGapEnd, oldCapacity - oldGapEnd)
+                    slots.copyInto(newSlots, 0, 0, table.gapStart)
+                    slots.copyInto(newSlots, newGapEnd, oldGapEnd, oldCapacity)
 
                     // Update the anchors
                     if (table.anchors.isNotEmpty()) table.anchorGapResize(newGapLen - table.gapLen)
@@ -641,8 +633,7 @@
         }
     }
 
-    // TODO(138720404): Investigate if Compose APIs can be internal despite MPP limitations
-    fun remove(start: Int, len: Int): Boolean {
+    internal fun remove(start: Int, len: Int): Boolean {
         return if (len > 0) {
             pendingClear = false
             var anchorsRemoved = false
@@ -729,8 +720,7 @@
 
     internal fun clearGap() = repeat(gapLen) { i -> slots[gapStart + i] = null }
 
-    // TODO(138720404): Investigate if Compose APIs can be internal despite MPP limitations
-    fun anchor(index: Int): Anchor {
+    internal fun anchor(index: Int): Anchor {
         // TODO: Consider a buffer gap list of anchors if middle inserts and deletes are common
         val anchorIndex = effectiveIndex(index)
         val location = anchors.search(anchorIndex)
@@ -827,8 +817,7 @@
         }
     }
 
-    // TODO(138720404): Investigate if Compose APIs can be internal despite MPP limitations
-    fun anchorLocation(anchor: Anchor) = anchor.loc.let {
+    internal fun anchorLocation(anchor: Anchor) = anchor.loc.let {
         if (it > gapStart) it - gapLen else it
     }
 
@@ -875,4 +864,4 @@
 private const val GROUP: GroupKind = 0
 private const val NODE: GroupKind = 1
 
-private const val MIN_GROWTH_SIZE = 128
\ No newline at end of file
+private const val MIN_GROWTH_SIZE = 128
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/ViewComposerCommon.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/ViewComposerCommon.kt
index a6a573c6..b873017 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/ViewComposerCommon.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/ViewComposerCommon.kt
@@ -22,9 +22,8 @@
 internal expect fun createComposer(root: Any, context: Context, recomposer: Recomposer): Composer<*>
 expect fun <T> Composer<*>.runWithCurrent(block: () -> T): T
 
-// TODO(138720404): Investigate if Compose APIs can be internal despite MPP limitations
-/*@PublishedApi
-internal*/ val invocation = Any()
+@PublishedApi
+internal val invocation = Any()
 
 @PublishedApi
 internal val provider = Any()
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/frames/Frames.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/frames/Frames.kt
index 02ead93..13e49bc 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/frames/Frames.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/frames/Frames.kt
@@ -110,8 +110,7 @@
 ) {
     internal val modified = if (readOnly) null else HashSet<Framed>()
 
-    // TODO(138720404): Investigate if Compose APIs can be internal despite MPP limitations
-    val readObservers = mutableListOf<FrameReadObserver>()
+    internal val readObservers = mutableListOf<FrameReadObserver>()
 
     init {
         if (readObserver != null) {
diff --git a/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/CompositionTests.kt b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/CompositionTests.kt
new file mode 100644
index 0000000..7c7df7e
--- /dev/null
+++ b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/CompositionTests.kt
@@ -0,0 +1,1853 @@
+/*
+ * Copyright 2019 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
+
+import androidx.compose.mock.Compose
+import androidx.compose.mock.Contact
+import androidx.compose.mock.ContactModel
+import androidx.compose.mock.MockViewComposer
+import androidx.compose.mock.MockViewComposition
+import androidx.compose.mock.MockViewValidator
+import androidx.compose.mock.Point
+import androidx.compose.mock.Report
+import androidx.compose.mock.View
+import androidx.compose.mock.ViewComponent
+import androidx.compose.mock.call
+import androidx.compose.mock.contact
+import androidx.compose.mock.edit
+import androidx.compose.mock.join
+import androidx.compose.mock.linear
+import androidx.compose.mock.memoize
+import androidx.compose.mock.points
+import androidx.compose.mock.remember
+import androidx.compose.mock.repeat
+import androidx.compose.mock.reportsReport
+import androidx.compose.mock.reportsTo
+import androidx.compose.mock.selectContact
+import androidx.compose.mock.set
+import androidx.compose.mock.skip
+import androidx.compose.mock.text
+import androidx.compose.mock.update
+import androidx.compose.mock.validate
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertNotEquals
+import kotlin.test.assertTrue
+
+class CompositionTests {
+
+    @Test
+    fun testComposeAModel() {
+        val model = testModel()
+        val composer = compose(model)
+
+        validate(composer.root) {
+            linear {
+                linear {
+                    text("Filter:")
+                    edit("")
+                }
+                linear {
+                    text(value = "Contacts:")
+                    linear {
+                        contact(bob)
+                        contact(jon)
+                        contact(steve)
+                    }
+                }
+            }
+        }
+    }
+
+    @Test
+    fun testRecomposeWithoutChanges() {
+        val model = testModel()
+        val composer = compose(model)
+
+        compose(model, composer, expectChanges = false)
+
+        validate(composer.root) {
+            selectContact(model)
+        }
+    }
+
+    @Test
+    fun testInsertAContact() {
+        val model =
+            testModel(mutableListOf(bob, jon))
+        val composer = compose(model)
+
+        validate(composer.root) {
+            linear {
+                skip()
+                linear {
+                    skip()
+                    linear {
+                        contact(bob)
+                        contact(jon)
+                    }
+                }
+            }
+        }
+
+        model.add(steve, after = bob)
+        compose(model, composer)
+
+        validate(composer.root) {
+            linear {
+                skip()
+                linear {
+                    skip()
+                    linear {
+                        contact(bob)
+                        contact(steve)
+                        contact(jon)
+                    }
+                }
+            }
+        }
+    }
+
+    @Test
+    fun testMoveAContact() {
+        val model = testModel(
+            mutableListOf(
+                bob,
+                steve,
+                jon
+            )
+        )
+        val composer = compose(model)
+
+        model.move(steve, after = jon)
+        compose(model, composer)
+
+        validate(composer.root) {
+            linear {
+                skip()
+                linear {
+                    skip()
+                    linear {
+                        contact(bob)
+                        contact(jon)
+                        contact(steve)
+                    }
+                }
+            }
+        }
+    }
+
+    @Test
+    fun testChangeTheFilter() {
+        val model = testModel(
+            mutableListOf(
+                bob,
+                steve,
+                jon
+            )
+        )
+        val composer = compose(model)
+
+        model.filter = "Jon"
+        compose(model, composer)
+
+        validate(composer.root) {
+            linear {
+                skip()
+                linear {
+                    skip()
+                    linear {
+                        contact(jon)
+                    }
+                }
+            }
+        }
+    }
+
+    @Test
+    fun testComposeCompositionWithMultipleRoots() {
+        val reports = listOf(
+            jim_reports_to_sally,
+            rob_reports_to_alice,
+            clark_reports_to_lois
+        )
+
+        val composer = compose {
+            reportsReport(reports)
+        }
+
+        validate(composer.root) {
+            reportsReport(reports)
+        }
+    }
+
+    @Test
+    fun testMoveCompositionWithMultipleRoots() {
+        val reports = listOf(
+            jim_reports_to_sally,
+            rob_reports_to_alice,
+            clark_reports_to_lois
+        )
+        val composer = compose {
+            reportsReport(reports)
+        }
+
+        val newReports = listOf(
+            jim_reports_to_sally,
+            clark_reports_to_lois,
+            rob_reports_to_alice
+        )
+        compose(composer) {
+            reportsReport(newReports)
+        }
+
+        validate(composer.root) {
+            reportsReport(newReports)
+        }
+    }
+
+    @Test
+    fun testReplace() {
+        var includeA = true
+        fun MockViewComposition.composition() {
+            text("Before")
+            if (includeA) {
+                linear {
+                    text("A")
+                }
+            } else {
+                edit("B")
+            }
+            text("After")
+        }
+        fun MockViewValidator.composition() {
+            text("Before")
+            if (includeA) {
+                linear {
+                    text("A")
+                }
+            } else {
+                edit("B")
+            }
+            text("After")
+        }
+        val composer = compose {
+            composition()
+        }
+        validate(composer.root) {
+            composition()
+        }
+        includeA = false
+        compose(composer) {
+            composition()
+        }
+        validate(composer.root) {
+            composition()
+        }
+        includeA = true
+        compose(composer) {
+            composition()
+        }
+        validate(composer.root) {
+            composition()
+        }
+    }
+
+    @Test
+    fun testInsertWithMultipleRoots() {
+        val chars = listOf('a', 'b', 'c')
+
+        fun MockViewComposition.textOf(c: Char) {
+            text(c.toString())
+        }
+
+        fun MockViewValidator.textOf(c: Char) {
+            text(c.toString())
+        }
+
+        fun MockViewComposition.chars(chars: Iterable<Char>) {
+            repeat(of = chars) { c -> textOf(c) }
+        }
+
+        fun MockViewValidator.chars(chars: Iterable<Char>) {
+            repeat(of = chars) { c -> textOf(c) }
+        }
+
+        val composer = compose {
+            chars(chars)
+            chars(chars)
+            chars(chars)
+        }.apply { applyChanges() }
+
+        validate(composer.root) {
+            chars(chars)
+            chars(chars)
+            chars(chars)
+        }
+
+        val newChars = listOf('a', 'b', 'x', 'c')
+
+        compose(composer) {
+            chars(newChars)
+            chars(newChars)
+            chars(newChars)
+        }.apply { applyChanges() }
+
+        validate(composer.root) {
+            chars(newChars)
+            chars(newChars)
+            chars(newChars)
+        }
+    }
+
+    @Test
+    fun testSimpleMemoize() {
+        val points = listOf(Point(1, 2), Point(2, 3))
+        val composer = compose {
+            points(points)
+        }.apply { applyChanges() }
+
+        validate(composer.root) { points(points) }
+
+        compose(composer, expectChanges = false) {
+            points(points)
+        }
+    }
+
+    @Test
+    fun testMovingMemoization() {
+        val points = listOf(
+            Point(1, 2),
+            Point(2, 3),
+            Point(4, 5),
+            Point(6, 7)
+        )
+        val composer = compose {
+            points(points)
+        }
+
+        validate(composer.root) { points(points) }
+
+        val modifiedPoints = listOf(
+            Point(1, 2),
+            Point(4, 5),
+            Point(2, 3),
+            Point(6, 7)
+        )
+        compose(composer) {
+            points(modifiedPoints)
+        }
+
+        validate(composer.root) { points(modifiedPoints) }
+    }
+
+    @Test
+    fun testComponent() {
+        val slReportReports = object {}
+
+        class Reporter : ViewComponent() {
+            var report: Report? = null
+
+            override fun compose() {
+                val r = report
+                if (r != null) {
+                    text(r.from)
+                    text("reports to")
+                    text(r.to)
+                } else {
+                    text("no report to report")
+                }
+            }
+        }
+
+        fun MockViewComposition.reportsReport(reports: Iterable<Report>) {
+            linear {
+                repeat(of = reports) { report ->
+                    call(
+                        slReportReports,
+                        { Reporter() },
+                        { set(report) { this.report = it } },
+                        { it() }
+                    )
+                }
+            }
+        }
+
+        val reports = listOf(
+            jim_reports_to_sally,
+            rob_reports_to_alice,
+            clark_reports_to_lois
+        )
+        val composer = compose {
+            reportsReport(reports)
+        }
+
+        validate(composer.root) {
+            linear {
+                reportsTo(jim_reports_to_sally)
+                reportsTo(rob_reports_to_alice)
+                reportsTo(clark_reports_to_lois)
+            }
+        }
+
+        compose(composer, expectChanges = false) {
+            reportsReport(reports)
+        }
+    }
+
+    @Test
+    fun testComposeTwoAttributeComponent() {
+        class Two : ViewComponent() {
+            var first: Int = 1
+            var second: Int = 2
+
+            override fun compose() {
+                linear {
+                    text("$first $second")
+                }
+            }
+        }
+
+        fun MockViewValidator.two(first: Int, second: Int) {
+            linear {
+                text("$first $second")
+            }
+        }
+
+        val two = object {}
+        val composer = compose {
+            call(
+                two,
+                { Two() },
+                {
+                    set(41) { this.first = it }
+                    set(42) { this.second = it }
+                },
+                { it() }
+            )
+        }
+
+        validate(composer.root) {
+            two(41, 42)
+        }
+    }
+
+    @Test
+    fun testComposeThreeAttributeComponent() {
+        class Three : ViewComponent() {
+            var first: Int = 1
+            var second: Int = 2
+            var third: Int = 3
+
+            override fun compose() {
+                linear {
+                    text("$first $second $third")
+                }
+            }
+        }
+
+        fun MockViewValidator.three(first: Int, second: Int, third: Int) {
+            linear {
+                text("$first $second $third")
+            }
+        }
+
+        val three = object {}
+        val composer = compose {
+            call(
+                three,
+                { Three() },
+                {
+                    set(41) { this.first = it }
+                    set(42) { this.second = it }
+                    set(43) { this.third = it }
+                },
+                { it() }
+            )
+        }
+
+        validate(composer.root) {
+            three(41, 42, 43)
+        }
+    }
+
+    @Test
+    fun testComposeFourOrMoreAttributeComponent() {
+        class Four : ViewComponent() {
+            var first: Int = 1
+            var second: Int = 2
+            var third: Int = 3
+            var fourth: Int = 4
+
+            override fun compose() {
+                linear {
+                    text("$first $second $third $fourth")
+                }
+            }
+        }
+
+        fun MockViewValidator.four(first: Int, second: Int, third: Int, fourth: Int) {
+            linear {
+                text("$first $second $third $fourth")
+            }
+        }
+
+        val four = object {}
+        val composer = compose {
+            call(
+                four,
+                { Four() },
+                {
+                    set(41) { this.first = it }
+                    set(42) { this.second = it }
+                    set(43) { this.third = it }
+                    set(44) { this.fourth = it }
+                },
+                { it() }
+            )
+        }
+
+        validate(composer.root) {
+            four(41, 42, 43, 44)
+        }
+    }
+
+    @Test
+    fun testComponentWithVarCtorParameter() {
+        class One(var first: Int) : ViewComponent() {
+            override fun compose() {
+                text("$first")
+            }
+        }
+
+        fun MockViewValidator.one(first: Int) {
+            text("$first")
+        }
+
+        val key = object {}
+        fun MockViewComposition.callOne(value: Int) {
+            call(
+                key,
+                { One(first = value) },
+                {
+                    update(value) { this.first = it }
+                },
+                { it() }
+            )
+        }
+
+        var value = 42
+        val composer = compose {
+            callOne(value)
+        }
+
+        validate(composer.root) {
+            one(42)
+        }
+
+        value = 43
+
+        compose(composer) {
+            callOne(value)
+        }
+
+        validate(composer.root) {
+            one(43)
+        }
+    }
+
+    @Test
+    fun testComponentWithValCtorParameter() {
+        class One(val first: Int) : ViewComponent() {
+            override fun compose() {
+                text("$first")
+            }
+        }
+
+        fun MockViewValidator.one(first: Int) {
+            text("$first")
+        }
+
+        val key = object {}
+        fun MockViewComposition.callOne(value: Int) {
+            call(
+                cc.joinKey(key, value),
+                { One(first = value) },
+                { },
+                { it() }
+            )
+        }
+
+        var value = 42
+        val composer = compose {
+            callOne(value)
+        }
+
+        validate(composer.root) {
+            one(42)
+        }
+
+        value = 43
+
+        compose(composer) {
+            callOne(value)
+        }
+
+        validate(composer.root) {
+            one(43)
+        }
+
+        compose(composer, expectChanges = false) {
+            callOne(value)
+        }
+    }
+
+    @Test
+    fun testComposePartOfTree() {
+        val slReportReports = object {}
+        var recomposeLois: (() -> Unit)? = null
+
+        class Reporter : ViewComponent() {
+            var report: Report? = null
+
+            override fun compose() {
+                val r = report
+                if (r != null) {
+                    if (r.from == "Lois" || r.to == "Lois") recomposeLois = { recompose() }
+                    text(r.from)
+                    text("reports to")
+                    text(r.to)
+                } else {
+                    text("no report to report")
+                }
+            }
+        }
+
+        fun MockViewComposition.reportsReport(reports: Iterable<Report>) {
+            linear {
+                repeat(of = reports) { report ->
+                    call(
+                        slReportReports,
+                        { Reporter() },
+                        { set(report) { this.report = it } },
+                        { it() }
+                    )
+                }
+            }
+        }
+
+        val r = Report("Lois", "Perry")
+        val reports = listOf(
+            jim_reports_to_sally,
+            rob_reports_to_alice,
+            clark_reports_to_lois, r)
+        val composer = compose {
+            reportsReport(reports)
+        }.apply { applyChanges() }
+
+        validate(composer.root) {
+            linear {
+                reportsTo(jim_reports_to_sally)
+                reportsTo(rob_reports_to_alice)
+                reportsTo(clark_reports_to_lois)
+                reportsTo(r)
+            }
+        }
+
+        compose(composer, expectChanges = false) {
+            reportsReport(reports)
+        }
+
+        // Demote Perry
+        r.from = "Perry"
+        r.to = "Lois"
+
+        // Compose only the Lois report
+        recomposeLois?.let { it() }
+
+        composer.recompose()
+        composer.applyChanges()
+
+        validate(composer.root) {
+            linear {
+                reportsTo(jim_reports_to_sally)
+                reportsTo(rob_reports_to_alice)
+                reportsTo(clark_reports_to_lois)
+                reportsTo(r)
+            }
+        }
+    }
+
+    @Test
+    fun testRecomposeWithReplace() {
+        val slReportReports = object {}
+        var recomposeLois: (() -> Unit)? = null
+        var key = 0
+
+        class Reporter : ViewComponent() {
+            var report: Report? = null
+
+            override fun compose() {
+                val r = report
+                if (r != null) {
+                    if (r.from == "Lois" || r.to == "Lois") recomposeLois = { recompose() }
+                    cc.startGroup(key)
+                    text(r.from)
+                    text("reports to")
+                    text(r.to)
+                    cc.endGroup()
+                } else {
+                    text("no report to report")
+                }
+            }
+        }
+
+        fun MockViewComposition.reportsReport(reports: Iterable<Report>) {
+            linear {
+                repeat(of = reports) { report ->
+                    call(
+                        slReportReports,
+                        { Reporter() },
+                        { set(report) { this.report = it } },
+                        { it() }
+                    )
+                }
+            }
+        }
+
+        val r = Report("Lois", "Perry")
+        val reports = listOf(
+            jim_reports_to_sally,
+            rob_reports_to_alice,
+            clark_reports_to_lois, r)
+        val composer = compose {
+            reportsReport(reports)
+        }.apply { applyChanges() }
+
+        validate(composer.root) {
+            linear {
+                reportsTo(jim_reports_to_sally)
+                reportsTo(rob_reports_to_alice)
+                reportsTo(clark_reports_to_lois)
+                reportsTo(r)
+            }
+        }
+
+        compose(composer, expectChanges = false) {
+            reportsReport(reports)
+        }
+
+        // Demote Perry
+        r.from = "Perry"
+        r.to = "Lois"
+
+        // Cause a new group to be generated in the component
+        key = 2
+
+        // Compose only the Lois report
+        recomposeLois?.let { it() }
+
+        composer.recompose()
+        composer.applyChanges()
+
+        validate(composer.root) {
+            linear {
+                reportsTo(jim_reports_to_sally)
+                reportsTo(rob_reports_to_alice)
+                reportsTo(clark_reports_to_lois)
+                reportsTo(r)
+            }
+        }
+    }
+
+    @Test
+    fun testInvalidationAfterRemoval() {
+        val slReportReports = object {}
+        var recomposeLois: (() -> Unit)? = null
+        val key = 0
+
+        class Reporter : ViewComponent() {
+            var report: Report? = null
+
+            override fun compose() {
+                val r = report
+                if (r != null) {
+                    if (r.from == "Lois" || r.to == "Lois") recomposeLois = { recompose() }
+                    cc.startGroup(key)
+                    text(r.from)
+                    text("reports to")
+                    text(r.to)
+                    cc.endGroup()
+                } else {
+                    text("no report to report")
+                }
+            }
+        }
+
+        fun MockViewComposition.reportsReport(
+            reports: Iterable<Report>,
+            include: (report: Report) -> Boolean
+        ) {
+            linear {
+                repeat(of = reports) { report ->
+                    if (include(report)) {
+                        call(
+                            slReportReports,
+                            { Reporter() },
+                            { set(report) { this.report = it } },
+                            { it() }
+                        )
+                    }
+                }
+            }
+        }
+
+        val r = Report("Lois", "Perry")
+        val reports = listOf(
+            jim_reports_to_sally,
+            rob_reports_to_alice,
+            clark_reports_to_lois,
+            r
+        )
+        val all: (report: Report) -> Boolean = { true }
+        val notLois: (report: Report) -> Boolean = { it.from != "Lois" && it.to != "Lois" }
+        val composer = compose {
+            reportsReport(reports, all)
+        }.apply { applyChanges() }
+
+        validate(composer.root) {
+            linear {
+                reportsTo(jim_reports_to_sally)
+                reportsTo(rob_reports_to_alice)
+                reportsTo(clark_reports_to_lois)
+                reportsTo(r)
+            }
+        }
+
+        compose(composer, expectChanges = true) {
+            reportsReport(reports, notLois)
+        }
+
+        validate(composer.root) {
+            linear {
+                reportsTo(jim_reports_to_sally)
+                reportsTo(rob_reports_to_alice)
+            }
+        }
+
+        // Invalidate Lois which is now removed.
+        recomposeLois?.let { it() }
+
+        composer.recompose()
+        composer.applyChanges()
+
+        validate(composer.root) {
+            linear {
+                reportsTo(jim_reports_to_sally)
+                reportsTo(rob_reports_to_alice)
+            }
+        }
+    }
+
+    // remember()
+
+    @Test
+    fun testSimpleRemember() {
+        var count = 0
+
+        class Wrapper(val value: Int) {
+            init {
+                count++
+            }
+        }
+
+        fun MockViewComposition.test(value: Int) {
+            val w = remember { Wrapper(value) }
+            text("value = ${w.value}")
+        }
+
+        fun MockViewValidator.test(value: Int) {
+            text("value = $value")
+        }
+
+        val composer = compose {
+            test(1)
+        }
+
+        validate(composer.root) { test(1) }
+
+        assertEquals(1, count)
+
+        compose(composer, expectChanges = false) {
+            test(1)
+        }
+
+        // Expect the previous instance to be remembered
+        assertEquals(1, count)
+    }
+
+    @Test
+    fun testRememberOneParameter() {
+        var count = 0
+
+        class Wrapper(val value: Int) {
+            init {
+                count++
+            }
+        }
+
+        fun MockViewComposition.test(value: Int) {
+            val w = remember(value) { Wrapper(value) }
+            text("value = ${w.value}")
+        }
+
+        fun MockViewValidator.test(value: Int) {
+            text("value = $value")
+        }
+
+        val composer = compose {
+            test(1)
+        }
+
+        validate(composer.root) { test(1) }
+
+        compose(composer) {
+            test(2)
+        }
+
+        validate(composer.root) { test(2) }
+
+        compose(composer, expectChanges = false) {
+            test(2)
+        }
+
+        validate(composer.root) { test(2) }
+
+        assertEquals(2, count)
+    }
+
+    @Test
+    fun testRememberTwoParameters() {
+        var count = 0
+
+        class Wrapper(val a: Int, val b: Int) {
+            init {
+                count++
+            }
+        }
+
+        fun MockViewComposition.test(a: Int, b: Int) {
+            val w = remember(a, b) { Wrapper(a, b) }
+            text("a = ${w.a} b = ${w.b}")
+        }
+
+        fun MockViewValidator.test(a: Int, b: Int) {
+            text("a = $a b = $b")
+        }
+
+        val composer = compose {
+            test(1, 2)
+        }
+
+        validate(composer.root) { test(1, 2) }
+
+        compose(composer) {
+            test(2, 3)
+        }
+
+        validate(composer.root) { test(2, 3) }
+
+        compose(composer, expectChanges = false) {
+            test(2, 3)
+        }
+
+        validate(composer.root) { test(2, 3) }
+
+        assertEquals(2, count)
+    }
+
+    @Test
+    fun testRememberThreeParameters() {
+        var count = 0
+
+        class Wrapper(val a: Int, val b: Int, val c: Int) {
+            init {
+                count++
+            }
+        }
+
+        fun MockViewComposition.test(a: Int, b: Int, c: Int) {
+            val w = remember(a, b, c) { Wrapper(a, b, c) }
+            text("a = ${w.a} b = ${w.b} c = ${w.c}")
+        }
+
+        fun MockViewValidator.test(a: Int, b: Int, c: Int) {
+            text("a = $a b = $b c = $c")
+        }
+
+        val composer = compose {
+            test(1, 2, 3)
+        }
+
+        validate(composer.root) { test(1, 2, 3) }
+
+        compose(composer) {
+            test(1, 2, 4)
+        }
+
+        validate(composer.root) { test(1, 2, 4) }
+
+        compose(composer, expectChanges = false) {
+            test(1, 2, 4)
+        }
+
+        validate(composer.root) { test(1, 2, 4) }
+
+        assertEquals(2, count)
+    }
+
+    @Test
+    fun testRememberFourParameters() {
+        var count = 0
+
+        class Wrapper(val a: Int, val b: Int, val c: Int, val d: Int) {
+            init {
+                count++
+            }
+        }
+
+        fun MockViewComposition.test(a: Int, b: Int, c: Int, d: Int) {
+            val w = remember(a, b, c, d) { Wrapper(a, b, c, d) }
+            text("a = ${w.a} b = ${w.b} c = ${w.c} d = ${w.d}")
+        }
+
+        fun MockViewValidator.test(a: Int, b: Int, c: Int, d: Int) {
+            text("a = $a b = $b c = $c d = $d")
+        }
+
+        val composer = compose {
+            test(1, 2, 3, 4)
+        }
+
+        validate(composer.root) { test(1, 2, 3, 4) }
+
+        compose(composer) {
+            test(1, 2, 4, 5)
+        }
+
+        validate(composer.root) { test(1, 2, 4, 5) }
+
+        compose(composer, expectChanges = false) {
+            test(1, 2, 4, 5)
+        }
+
+        validate(composer.root) { test(1, 2, 4, 5) }
+
+        assertEquals(2, count)
+    }
+
+    @Test
+    fun testRememberFiveParameters() {
+        var count = 0
+
+        class Wrapper(val a: Int, val b: Int, val c: Int, val d: Int, val e: Int) {
+            init {
+                count++
+            }
+        }
+
+        fun MockViewComposition.test(a: Int, b: Int, c: Int, d: Int, e: Int) {
+            val w = remember(a, b, c, d, e) { Wrapper(a, b, c, d, e) }
+            text("a = ${w.a} b = ${w.b} c = ${w.c} d = ${w.d} e = ${w.e}")
+        }
+
+        fun MockViewValidator.test(a: Int, b: Int, c: Int, d: Int, e: Int) {
+            text("a = $a b = $b c = $c d = $d e = $e")
+        }
+
+        val composer = compose {
+            test(1, 2, 3, 4, 5)
+        }
+
+        validate(composer.root) { test(1, 2, 3, 4, 5) }
+
+        compose(composer) {
+            test(1, 2, 4, 5, 6)
+        }
+
+        validate(composer.root) { test(1, 2, 4, 5, 6) }
+
+        compose(composer, expectChanges = false) {
+            test(1, 2, 4, 5, 6)
+        }
+
+        validate(composer.root) { test(1, 2, 4, 5, 6) }
+
+        assertEquals(2, count)
+    }
+
+    @Test
+    fun testInsertGroupInContainer() {
+        val values = mutableListOf(0)
+
+        fun MockViewComposition.composition() {
+            linear {
+                for (value in values) {
+                    memoize(value, value) {
+                        text("$value")
+                    }
+                }
+            }
+        }
+
+        fun MockViewValidator.composition() {
+            linear {
+                for (value in values)
+                    text("$value")
+            }
+        }
+
+        val composer = compose { composition() }
+
+        validate(composer.root) { composition() }
+
+        for (i in 1..10) {
+            values.add(i)
+            compose(composer) { composition() }
+            validate(composer.root) { composition() }
+        }
+    }
+
+    @Test
+    fun testStartJoin() {
+        var text = "Starting"
+        var invalidate: (() -> Unit)? = null
+        fun MockViewComposition.composition() {
+            linear {
+                join(860) { myInvalidate ->
+                    invalidate = { myInvalidate(false) }
+                    text(text)
+                }
+            }
+        }
+
+        fun MockViewValidator.composition() {
+            linear {
+                text(text)
+            }
+        }
+
+        val composer = compose { composition() }
+
+        validate(composer.root) { composition() }
+
+        text = "Ending"
+        invalidate?.let { it() }
+
+        composer.recompose()
+        composer.applyChanges()
+
+        validate(composer.root) { composition() }
+    }
+
+    @Test
+    fun testInvalidateJoin_End() {
+        var text = "Starting"
+        var includeNested = true
+        var invalidate1: (() -> Unit)? = null
+        var invalidate2: (() -> Unit)? = null
+
+        fun MockViewComposition.composition() {
+            linear {
+                join(860) { myInvalidate ->
+                    invalidate1 = { myInvalidate(false) }
+                    text(text)
+                    if (includeNested) {
+                        join(899) { joinInvalidate ->
+                            invalidate2 = { joinInvalidate(false) }
+                            text("Nested in $text")
+                        }
+                    }
+                }
+            }
+        }
+
+        fun MockViewValidator.composition() {
+            linear {
+                text(text)
+                if (includeNested) {
+                    text("Nested in $text")
+                }
+            }
+        }
+
+        val composer = compose { composition() }
+
+        validate(composer.root) { composition() }
+
+        text = "Ending"
+        includeNested = false
+        invalidate1?.invoke()
+        invalidate2?.invoke()
+
+        composer.recompose()
+        composer.applyChanges()
+
+        validate(composer.root) { composition() }
+
+        composer.recompose()
+        composer.applyChanges()
+
+        validate(composer.root) { composition() }
+    }
+
+    @Test
+    fun testInvalidateJoin_Start() {
+        var text = "Starting"
+        var includeNested = true
+        var invalidate1: (() -> Unit)? = null
+        var invalidate2: (() -> Unit)? = null
+
+        fun MockViewComposition.composition() {
+            linear {
+                join(860) { myInvalidate ->
+                    invalidate1 = { myInvalidate(false) }
+                    if (includeNested) {
+                        join(899) { joinInvalidate ->
+                            invalidate2 = { joinInvalidate(false) }
+                            text("Nested in $text")
+                        }
+                    }
+                    text(text)
+                }
+            }
+        }
+
+        fun MockViewValidator.composition() {
+            linear {
+                if (includeNested) {
+                    text("Nested in $text")
+                }
+                text(text)
+            }
+        }
+
+        val composer = compose { composition() }
+
+        validate(composer.root) { composition() }
+
+        text = "Ending"
+        includeNested = false
+        invalidate1?.invoke()
+        invalidate2?.invoke()
+
+        composer.recompose()
+        composer.applyChanges()
+
+        validate(composer.root) { composition() }
+
+        composer.recompose()
+        composer.applyChanges()
+
+        validate(composer.root) { composition() }
+    }
+
+    // b/132638679
+    @Test
+    fun testJoinInvalidate() {
+        var texts = 5
+        var invalidateOuter: (() -> Unit)? = null
+        var invalidateInner: (() -> Unit)? = null
+
+        fun MockViewComposition.composition() {
+            linear {
+                join(1106) { outerInvalidate ->
+                    invalidateOuter = { outerInvalidate(false) }
+                    for (i in 1..texts) {
+                        text("Some text")
+                    }
+
+                    skip(1114) {
+                        join(1116) { innerInvalidate ->
+                            text("Some text")
+
+                            // Force the invalidation to survive the compose
+                            innerInvalidate(false)
+                            invalidateInner = { innerInvalidate(false) }
+                        }
+                    }
+                }
+            }
+        }
+
+        val composer = compose { composition() }
+
+        texts = 4
+        invalidateOuter?.invoke()
+        invalidateInner?.invoke()
+        composer.recompose()
+        composer.applyChanges()
+
+        texts = 3
+        invalidateOuter?.invoke()
+        composer.recompose()
+        composer.applyChanges()
+    }
+
+    @Test
+    fun testLifecycle_Enter_Simple() {
+        val lifecycleObject = object : CompositionLifecycleObserver {
+            var count = 0
+            override fun onEnter() {
+                count++
+            }
+
+            override fun onLeave() {
+                count--
+            }
+        }
+
+        fun MockViewComposition.composition() {
+            linear {
+                remember { lifecycleObject }
+                text("Some text")
+            }
+        }
+
+        fun MockViewValidator.composition() {
+            linear {
+                text("Some text")
+            }
+        }
+
+        val composer = compose { composition() }
+        validate(composer.root) { composition() }
+
+        assertEquals(1, lifecycleObject.count, "object should have been notified of an enter")
+
+        compose(composer, expectChanges = false) {
+            composition()
+        }
+        validate(composer.root) { composition() }
+
+        assertEquals(1, lifecycleObject.count, "Object should have only been notified once")
+    }
+
+    @Test
+    fun testLifecycle_Enter_SingleNotification() {
+        val lifecycleObject = object : CompositionLifecycleObserver {
+            var count = 0
+            override fun onEnter() {
+                count++
+            }
+
+            override fun onLeave() {
+                count--
+            }
+        }
+
+        fun MockViewComposition.composition() {
+            linear {
+                val l = remember { lifecycleObject }
+                assertEquals(lifecycleObject, l, "Lifecycle object should be returned")
+                text("Some text")
+            }
+            linear {
+                val l = remember { lifecycleObject }
+                assertEquals(lifecycleObject, l, "Lifecycle object should be returned")
+                text("Some other text")
+            }
+        }
+
+        fun MockViewValidator.composition() {
+            linear {
+                text("Some text")
+            }
+            linear {
+                text("Some other text")
+            }
+        }
+
+        val composer = compose { composition() }
+        validate(composer.root) { composition() }
+
+        assertEquals(1, lifecycleObject.count, "object should have been notified of an enter")
+
+        compose(composer, expectChanges = false) {
+            composition()
+        }
+        validate(composer.root) { composition() }
+
+        assertEquals(1, lifecycleObject.count, "Object should have only been notified once")
+    }
+
+    @Test
+    fun testLifecycle_Leave_Simple() {
+        val lifecycleObject = object : CompositionLifecycleObserver {
+            var count = 0
+            override fun onEnter() {
+                count++
+            }
+
+            override fun onLeave() {
+                count--
+            }
+        }
+
+        fun MockViewComposition.composition(includeLifecycleObject: Boolean) {
+            linear {
+                if (includeLifecycleObject) {
+                    linear {
+                        val l = remember { lifecycleObject }
+                        assertEquals(lifecycleObject, l, "Lifecycle object should be returned")
+                        text("Some text")
+                    }
+                }
+            }
+        }
+
+        fun MockViewValidator.composition(includeLifecycleObject: Boolean) {
+            linear {
+                if (includeLifecycleObject) {
+                    linear {
+                        text("Some text")
+                    }
+                }
+            }
+        }
+
+        val composer = compose { composition(true) }
+        validate(composer.root) { composition(true) }
+
+        assertEquals(1, lifecycleObject.count, "object should have been notified of an enter")
+
+        compose(composer, expectChanges = false) {
+            composition(true)
+        }
+        validate(composer.root) { composition(true) }
+
+        assertEquals(1, lifecycleObject.count, "Object should have only been notified once")
+
+        compose(composer, expectChanges = true) {
+            composition(false)
+        }
+        validate(composer.root) { composition(false) }
+
+        assertEquals(0, lifecycleObject.count, "Object should have been notified of a leave")
+    }
+
+    @Test
+    fun testLifecycle_Leave_NoLeaveOnReenter() {
+        var expectedEnter = true
+        var expectedLeave = true
+        val lifecycleObject = object : CompositionLifecycleObserver {
+            var count = 0
+            override fun onEnter() {
+                count++
+                assertTrue(expectedEnter, "No enter expected")
+            }
+
+            override fun onLeave() {
+                count--
+                assertTrue(expectedLeave, "No leave expected")
+            }
+        }
+
+        fun MockViewComposition.composition(a: Boolean, b: Boolean, c: Boolean) {
+            linear {
+                if (a) {
+                    linear(1) {
+                        val l = remember { lifecycleObject }
+                        assertEquals(lifecycleObject, l, "Lifecycle object should be returned")
+                        text("a")
+                    }
+                }
+                if (b) {
+                    linear(2) {
+                        val l = remember { lifecycleObject }
+                        assertEquals(lifecycleObject, l, "Lifecycle object should be returned")
+                        text("b")
+                    }
+                }
+                if (c) {
+                    linear(3) {
+                        val l = remember { lifecycleObject }
+                        assertEquals(lifecycleObject, l, "Lifecycle object should be returned")
+                        text("c")
+                    }
+                }
+            }
+        }
+
+        fun MockViewValidator.composition(a: Boolean, b: Boolean, c: Boolean) {
+            linear {
+                if (a) {
+                    linear {
+                        text("a")
+                    }
+                }
+                if (b) {
+                    linear {
+                        text("b")
+                    }
+                }
+                if (c) {
+                    linear {
+                        text("c")
+                    }
+                }
+            }
+        }
+
+        expectedEnter = true
+        expectedLeave = false
+        val composer = compose { composition(a = true, b = false, c = false) }
+        validate(composer.root) {
+            composition(
+                a = true,
+                b = false,
+                c = false
+            )
+        }
+
+        assertEquals(
+            1,
+            lifecycleObject.count,
+            "object should have been notified of an enter"
+        )
+
+        expectedEnter = false
+        expectedLeave = false
+        compose(composer, expectChanges = false) {
+            composition(a = true, b = false, c = false)
+        }
+        validate(composer.root) {
+            composition(
+                a = true,
+                b = false,
+                c = false
+            )
+        }
+        assertEquals(
+            1,
+            lifecycleObject.count,
+            "Object should have only been notified once"
+        )
+
+        expectedEnter = false
+        expectedLeave = false
+        compose(composer, expectChanges = true) {
+            composition(a = false, b = true, c = false)
+        }
+        validate(composer.root) {
+            composition(
+                a = false,
+                b = true,
+                c = false
+            )
+        }
+        assertEquals(1, lifecycleObject.count, "No enter or leaves")
+
+        expectedEnter = false
+        expectedLeave = false
+        compose(composer, expectChanges = true) {
+            composition(a = false, b = false, c = true)
+        }
+        validate(composer.root) {
+            composition(
+                a = false,
+                b = false,
+                c = true
+            )
+        }
+        assertEquals(1, lifecycleObject.count, "No enter or leaves")
+
+        expectedEnter = false
+        expectedLeave = false
+        compose(composer, expectChanges = true) {
+            composition(a = true, b = false, c = false)
+        }
+        validate(composer.root) {
+            composition(
+                a = true,
+                b = false,
+                c = false
+            )
+        }
+        assertEquals(1, lifecycleObject.count, "No enter or leaves")
+
+        expectedEnter = false
+        expectedLeave = true
+        compose(composer, expectChanges = true) {
+            composition(a = false, b = false, c = false)
+        }
+        validate(composer.root) {
+            composition(
+                a = false,
+                b = false,
+                c = false
+            )
+        }
+        assertEquals(0, lifecycleObject.count, "A leave")
+    }
+
+    @Test
+    fun testLifecycle_Leave_LeaveOnReplace() {
+        val lifecycleObject1 = object : CompositionLifecycleObserver {
+            var count = 0
+            override fun onEnter() {
+                count++
+            }
+
+            override fun onLeave() {
+                count--
+            }
+        }
+
+        val lifecycleObject2 = object : CompositionLifecycleObserver {
+            var count = 0
+            override fun onEnter() {
+                count++
+            }
+
+            override fun onLeave() {
+                count--
+            }
+        }
+
+        fun MockViewComposition.composition(obj: Any) {
+            linear {
+                linear(1) {
+                    remember(obj) { obj }
+                    text("Some value")
+                }
+            }
+        }
+
+        fun MockViewValidator.composition() {
+            linear {
+                linear {
+                    text("Some value")
+                }
+            }
+        }
+
+        val composer = compose { composition(obj = lifecycleObject1) }
+        validate(composer.root) { composition() }
+        assertEquals(1, lifecycleObject1.count, "first object should enter")
+        assertEquals(0, lifecycleObject2.count, "second object should not have entered")
+
+        compose(composer, expectChanges = true) {
+            composition(lifecycleObject2)
+        }
+        validate(composer.root) { composition() }
+        assertEquals(0, lifecycleObject1.count, "first object should have left")
+        assertEquals(1, lifecycleObject2.count, "second object should have entered")
+
+        compose(composer, expectChanges = true) {
+            composition(object {})
+        }
+        validate(composer.root) { composition() }
+        assertEquals(0, lifecycleObject1.count, "first object should have left")
+        assertEquals(0, lifecycleObject2.count, "second object should have left")
+    }
+
+    @Test
+    fun testLifecycle_EnterLeaveOrder() {
+        var order = 0
+        val objects = mutableListOf<Any>()
+        val newLifecycleObject = { name: String ->
+            object : CompositionLifecycleObserver, Counted,
+                Ordered, Named {
+                override var name = name
+                override var count = 0
+                override var enterOrder = -1
+                override var leaveOrder = -1
+                override fun onEnter() {
+                    assertEquals(-1, enterOrder, "Only one call to onEnter expected")
+                    enterOrder = order++
+                    count++
+                }
+
+                override fun onLeave() {
+                    assertEquals(-1, leaveOrder, "Only one call to onLeave expected")
+                    leaveOrder = order++
+                    count--
+                }
+            }.also { objects.add(it) }
+        }
+
+        fun MockViewComposition.lifecycleUser(name: String) {
+            linear {
+                remember(name) { newLifecycleObject(name) }
+                text(value = name)
+            }
+        }
+
+        /*
+        A
+        |- B
+        |  |- C
+        |  |- D
+        |- E
+        |- F
+        |  |- G
+        |  |- H
+        |     |-I
+        |- J
+
+        Should enter as: A, B, C, D, E, F, G, H, I, J
+        Should leave as: J, I, H, G, F, E, D, C, B, A
+        */
+
+        fun MockViewComposition.tree() {
+            linear {
+                lifecycleUser("A")
+                linear {
+                    lifecycleUser("B")
+                    linear {
+                        lifecycleUser("C")
+                        lifecycleUser("D")
+                    }
+                    lifecycleUser("E")
+                    lifecycleUser("F")
+                    linear {
+                        lifecycleUser("G")
+                        lifecycleUser("H")
+                        linear {
+                            lifecycleUser("I")
+                        }
+                    }
+                    lifecycleUser("J")
+                }
+            }
+        }
+
+        fun MockViewComposition.composition(includeTree: Boolean) {
+            linear {
+                if (includeTree) tree()
+            }
+        }
+
+        val composer = compose { composition(true) }
+
+        assertTrue(
+            objects.mapNotNull { it as? Counted }.map { it.count == 1 }.all { it },
+            "All object should have entered"
+        )
+
+        compose(composer) {
+            composition(false)
+        }
+
+        assertTrue(
+            objects.mapNotNull { it as? Counted }.map { it.count == 0 }.all { it },
+            "All object should have left"
+        )
+
+        assertArrayEquals(
+            "Expected enter order",
+            arrayOf("A", "B", "C", "D", "E", "F", "G", "H", "I", "J"),
+            objects.mapNotNull { it as? Ordered }.sortedBy { it.enterOrder }.map {
+                (it as Named).name
+            }.toTypedArray()
+        )
+
+        assertArrayEquals(
+            "Expected leave order",
+            arrayOf("J", "I", "H", "G", "F", "E", "D", "C", "B", "A"),
+            objects.mapNotNull { it as? Ordered }.sortedBy { it.leaveOrder }.map {
+                (it as Named).name
+            }.toTypedArray()
+        )
+    }
+}
+
+private fun <T> assertArrayEquals(message: String, expected: Array<T>, received: Array<T>) {
+    fun Array<T>.getString() = this.joinToString(", ") { it.toString() }
+    fun err(msg: String): Nothing = error("$message: $msg, expected: [${
+    expected.getString()}], received: [${received.getString()}]")
+    if (expected.size != received.size) err("sizes are different")
+    expected.indices.forEach { index ->
+        if (expected[index] != received[index])
+            err("item at index $index was different (expected [${
+            expected[index]}], received: [${received[index]}]")
+    }
+}
+
+private fun compose(
+    composer: MockViewComposer? = null,
+    expectChanges: Boolean = true,
+    block: Compose
+): MockViewComposer {
+    val myComposer = composer ?: run {
+        val root = View().apply { name = "root" }
+        MockViewComposer(root)
+    }
+
+    myComposer.compose {
+        block()
+    }
+    if (expectChanges) {
+        assertNotEquals(0, myComposer.changeCount, "changes were expected")
+        myComposer.applyChanges()
+    } else {
+        assertEquals(0, myComposer.changeCount, "no changes were expected")
+    }
+
+    return myComposer
+}
+
+private fun compose(
+    model: ContactModel,
+    composer: MockViewComposer? = null,
+    expectChanges: Boolean = true
+): MockViewComposer =
+    compose(composer = composer, expectChanges = expectChanges) {
+        selectContact(model)
+    }
+
+// Contact test data
+private val bob = Contact("Bob Smith", email = "bob@smith.com")
+private val jon = Contact(name = "Jon Alberton", email = "jon@alberton.com")
+private val steve = Contact("Steve Roberson", email = "steverob@somemail.com")
+
+private fun testModel(
+    contacts: MutableList<Contact> = mutableListOf(
+        bob,
+        jon,
+        steve
+    )
+) = ContactModel(filter = "", contacts = contacts)
+
+// Report test data
+private val jim_reports_to_sally = Report("Jim", "Sally")
+private val rob_reports_to_alice = Report("Rob", "Alice")
+private val clark_reports_to_lois = Report("Clark", "Lois")
+
+private interface Counted {
+    val count: Int
+}
+
+private interface Ordered {
+    val enterOrder: Int
+    val leaveOrder: Int
+}
+
+private interface Named {
+    val name: String
+}
diff --git a/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/ObserverMapTests.kt b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/ObserverMapTests.kt
new file mode 100644
index 0000000..cb3d67e
--- /dev/null
+++ b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/ObserverMapTests.kt
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2019 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
+
+import kotlin.test.assertEquals
+import kotlin.test.BeforeTest
+import kotlin.test.Test
+
+class ObserverMapTests {
+
+    private val node1 = 1
+    private val node2 = 2
+    private lateinit var map: ObserverMap<TestModel, Int>
+
+    @BeforeTest
+    fun setup() {
+        map = ObserverMap()
+    }
+
+    @Test
+    fun testMapContainsPreviouslyAddedModel() {
+        val model = TestModel()
+        map.add(model, node1)
+
+        map.assertNodes(model, node1)
+    }
+
+    @Test
+    fun testMapAssociateBothNodesWithTheModel() {
+        val model = TestModel()
+        map.add(model, node1)
+        map.add(model, node2)
+
+        map.assertNodes(model, node1, node2)
+    }
+
+    @Test
+    fun testMapContainsModelWithChangedHashCode() {
+        val model = TestModel("Original")
+        map.add(model, node1)
+        model.content = "Changed"
+
+        map.assertNodes(model, node1)
+    }
+
+    @Test
+    fun testMapRemovesTheModel() {
+        val model = TestModel()
+        map.add(model, node1)
+        map.add(model, node2)
+
+        map.remove(model)
+
+        map.assertNodes(model)
+    }
+
+    @Test
+    fun testMapRemovesTheNode() {
+        val model = TestModel()
+        map.add(model, node1)
+        map.add(model, node2)
+
+        map.remove(model, node1)
+
+        map.assertNodes(model, node2)
+    }
+
+    @Test
+    fun testMapClearsAllTheModels() {
+        val model1 = TestModel("Test1")
+        val model2 = TestModel("Test2")
+        map.add(model1, node1)
+        map.add(model2, node2)
+
+        map.clear()
+
+        map.assertNodes(model1)
+        map.assertNodes(model2)
+    }
+
+    @Test
+    fun testMapClearsTheValuesByPredicate() {
+        val model1 = TestModel("Test1")
+        val model2 = TestModel("Test2")
+        val node3 = 3
+        map.add(model1, node1)
+        map.add(model2, node2)
+        map.add(model2, node3)
+
+        map.clearValues { it == node1 || it == node3 }
+
+        map.assertNodes(model1)
+        map.assertNodes(model2, node2)
+    }
+
+    @Test
+    fun testGetForMultipleModels() {
+        val model1 = TestModel("Test1")
+        val model2 = TestModel("Test2")
+        val model3 = TestModel("Test2")
+        val node3 = 3
+        val node4 = 4
+        map.add(model1, node1)
+        map.add(model1, node2)
+        map.add(model2, node3)
+        map.add(model3, node4)
+
+        map.assertNodes(listOf(model1, model2, model3), node1, node2, node3, node4)
+    }
+
+    @Test
+    fun testGetFiltersDuplicates() {
+        val model1 = TestModel("Test1")
+        val model2 = TestModel("Test2")
+        map.add(model1, node1)
+        map.add(model2, node1)
+
+        map.assertNodes(listOf(model1, model2), node1)
+    }
+
+    private data class TestModel(var content: String = "Test")
+
+    private fun ObserverMap<TestModel, Int>.assertNodes(
+        model: TestModel,
+        vararg nodes: Int
+    ) {
+        assertNodes(listOf(model), *nodes)
+    }
+
+    private fun ObserverMap<TestModel, Int>.assertNodes(
+        models: List<TestModel>,
+        vararg nodes: Int
+    ) {
+        val expected = nodes.toList().sorted()
+        val actual = get(models).sorted()
+        assertEquals(expected, actual)
+    }
+}
\ No newline at end of file
diff --git a/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/SlotTableTests.kt b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/SlotTableTests.kt
new file mode 100644
index 0000000..66e5833
--- /dev/null
+++ b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/SlotTableTests.kt
@@ -0,0 +1,1123 @@
+/*
+ * Copyright 2019 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
+
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+
+class SlotTableTests {
+
+    @Test
+    fun testCanCreate() {
+        SlotTable()
+    }
+
+    // Raw slot tests (testing the buffer gap)
+
+    @Test
+    fun testCanInsert() {
+        val slots = SlotTable()
+        slots.write { writer ->
+            writer.beginInsert()
+            writer.startGroup()
+            writer.skip()
+            writer.endGroup()
+            writer.endInsert()
+        }
+    }
+
+    @Test
+    fun testValidateSlots() {
+        val slots = testSlotsNumbered()
+        slots.read { reader ->
+            for (i in 0 until 100) {
+                assertEquals(i, reader.next())
+            }
+        }
+    }
+
+    @Test
+    fun testPrevious() {
+        val slots = testSlotsNumbered()
+        slots.read { reader ->
+            for (i in 0 until 100) {
+                assertEquals(i, reader.next())
+                reader.previous()
+                assertEquals(i, reader.next())
+            }
+            for (i in 99 downTo 0) {
+                reader.previous()
+                assertEquals(i, reader.next())
+                reader.previous()
+            }
+        }
+    }
+
+    @Test
+    fun testInsertAtTheStart() {
+        val slots = testSlotsNumbered()
+        slots.write { writer ->
+            writer.beginInsert()
+            writer.skip()
+            writer.set(-1)
+            writer.endInsert()
+        }
+        slots.read { reader ->
+            assertEquals(-1, reader.next())
+            for (i in 0 until 100) {
+                assertEquals(i, reader.next())
+            }
+        }
+    }
+
+    @Test
+    fun testInsertAtTheEnd() {
+        val slots = testSlotsNumbered()
+
+        val current = slots.read { reader ->
+            for (i in 0 until 100) {
+                assertEquals(i, reader.next())
+            }
+            reader.current
+        }
+
+        slots.write { writer ->
+            writer.current = current
+            writer.beginInsert()
+            writer.skip()
+            writer.set(-1)
+            writer.endInsert()
+        }
+
+        slots.read { reader ->
+            for (i in 0 until 100) {
+                assertEquals(i, reader.next())
+            }
+            assertEquals(-1, reader.next())
+        }
+    }
+
+    @Test
+    fun testInsertInTheMiddle() {
+        val slots = testSlotsNumbered()
+        val current = slots.read { reader ->
+            for (i in 0 until 50) {
+                assertEquals(i, reader.next())
+            }
+            reader.current
+        }
+        slots.write { writer ->
+            writer.current = current
+            writer.beginInsert()
+            writer.skip()
+            writer.set(-1)
+            writer.endInsert()
+        }
+        slots.read { reader ->
+            for (i in 0 until 100) {
+                if (i == 50) assertEquals(-1, reader.next())
+                assertEquals(i, reader.next())
+            }
+        }
+    }
+
+    @Test
+    fun testRemoveAtTheStart() {
+        val slots = testSlotsNumbered()
+        slots.write { writer ->
+            writer.remove(0, 50)
+        }
+        slots.read { reader ->
+            for (i in 50 until 100)
+                assertEquals(i, reader.next())
+        }
+    }
+
+    @Test
+    fun testRemoveAtTheEnd() {
+        val slots = testSlotsNumbered()
+        slots.write { writer ->
+            writer.remove(50, 50)
+        }
+        slots.read { reader ->
+            for (i in 0 until 50)
+                assertEquals(i, reader.next())
+        }
+    }
+
+    @Test
+    fun testRemoveInTheMiddle() {
+        val slots = testSlotsNumbered()
+        slots.write { writer ->
+            writer.remove(25, 50)
+        }
+        slots.read { reader ->
+            for (i in 0 until 25)
+                assertEquals(i, reader.next())
+            for (i in 75 until 100)
+                assertEquals(i, reader.next())
+        }
+    }
+
+    @Test
+    fun testRemoveTwoSlicesBackToFront() {
+        val slots = testSlotsNumbered()
+        slots.write { writer ->
+            writer.remove(70, 10)
+            writer.remove(40, 10)
+        }
+        slots.read { reader ->
+            for (i in 0 until 40)
+                assertEquals(i, reader.next())
+            for (i in 50 until 70)
+                assertEquals(i, reader.next())
+            for (i in 80 until 100)
+                assertEquals(i, reader.next())
+        }
+    }
+
+    @Test
+    fun testRemoveTwoSlicesFrontToBack() {
+        val slots = testSlotsNumbered()
+        slots.write { writer ->
+            writer.remove(40, 10)
+            writer.remove(60, 10) // Actually deletes the 70s as they have slid down 10
+        }
+        slots.read { reader ->
+            for (i in 0 until 40)
+                assertEquals(i, reader.next())
+            for (i in 50 until 70)
+                assertEquals(i, reader.next())
+            for (i in 80 until 100)
+                assertEquals(i, reader.next())
+        }
+    }
+
+    // Anchor tests
+
+    @Test
+    fun testAllocateAnchors() {
+        val slots = testSlotsNumbered()
+        val anchors = slots.write { writer -> (1..7).map { writer.anchor(it * 10) } }
+        slots.read { reader ->
+            for (index in 1..7) {
+                val anchor = anchors[index - 1]
+                assertEquals(index * 10, reader.get(anchor))
+            }
+        }
+    }
+
+    @Test
+    fun testAnchorsTrackInserts() {
+        val slots = testSlotsNumbered()
+        val anchors = slots.write { writer -> (1..7).map { writer.anchor(it * 10) } }
+        slots.write { writer ->
+            writer.current = 40
+            writer.beginInsert()
+            repeat(50) { writer.skip() }
+            writer.endInsert()
+        }
+        slots.read { reader ->
+            for (index in 1..7) {
+                val anchor = anchors[index - 1]
+                assertEquals(index * 10, reader.get(anchor))
+            }
+        }
+    }
+
+    @Test
+    fun testAnchorTracksExactRemovesUpwards() {
+        val slots = testSlotsNumbered()
+        val anchors = slots.write { writer -> (1..7).map { writer.anchor(it * 10) } }
+        slots.write { writer ->
+            for (index in 1..7) {
+                writer.remove(index * 10 - (index - 1), 1)
+                assertEquals(-1, anchors[index - 1].location(slots))
+            }
+        }
+    }
+
+    @Test
+    fun testAnchorTracksExactRemovesDownwards() {
+        val slots = testSlotsNumbered()
+        val anchors = slots.write { writer -> (1..7).map { writer.anchor(it * 10) } }
+        slots.write { writer ->
+            for (index in 7 downTo 1) {
+                writer.remove(index * 10, 1)
+                assertEquals(-1, anchors[index - 1].location(slots))
+            }
+        }
+    }
+
+    @Test
+    fun testAnchorTracksExtactRemovesInnerOuter() {
+        val slots = testSlotsNumbered()
+        val expectedLocations = (1..7).map { it * 10 }.toMutableList()
+        val anchors = slots.write { writer -> expectedLocations.map { writer.anchor(it) } }
+        slots.write { writer ->
+            for (index in listOf(4, 5, 3, 6, 2, 7, 1)) {
+                val location = expectedLocations[index - 1]
+                writer.remove(location, 1)
+                assertEquals(-1, anchors[index - 1].location(slots))
+                for (i in expectedLocations.indices) {
+                    if (expectedLocations[i] > location) expectedLocations[i]--
+                }
+            }
+        }
+    }
+
+    @Test
+    fun testAnchorTracksExactRemovesOuterInner() {
+        val slots = testSlotsNumbered()
+        val expectedLocations = (1..7).map { it * 10 }.toMutableList()
+        val anchors = slots.write { writer -> expectedLocations.map { writer.anchor(it) } }
+        slots.write { writer ->
+            for (index in listOf(1, 7, 2, 6, 3, 5, 4)) {
+                val location = expectedLocations[index - 1]
+                writer.remove(location, 1)
+                assertEquals(-1, anchors[index - 1].location(slots))
+                for (i in expectedLocations.indices) {
+                    if (expectedLocations[i] > location) expectedLocations[i]--
+                }
+            }
+        }
+    }
+
+    @Test
+    fun testAnchorTrackRemoves() {
+        val slots = testSlotsNumbered()
+        val anchors = slots.write { writer -> (1..7).map { writer.anchor(it * 10) } }
+        slots.write { writer ->
+            writer.remove(40, 20)
+        }
+        slots.read { reader ->
+            for (index in 1..7) {
+                val anchor = anchors[index - 1]
+                val expected = (index * 10).let { if (it in 40 until 60) SlotTable.EMPTY else it }
+                assertEquals(expected, reader.get(anchor))
+            }
+        }
+    }
+
+    @Test
+    fun testAnchorMoves() {
+        val slots = SlotTable()
+
+        fun buildSlots(range: List<Int>): Map<Anchor, Any?> {
+            val anchors = mutableListOf<Pair<Anchor, Any?>>()
+            slots.write { writer ->
+                fun item(value: Any?, block: () -> Unit) {
+                    writer.startItem(value)
+                    block()
+                    writer.endItem()
+                }
+
+                fun value(value: Any?) {
+                    writer.update(value)
+                }
+
+                writer.beginInsert()
+                for (i in range) {
+                    item(i) {
+                        value(i * 100)
+                        anchors.add(slots.anchor(writer.current - 1) to i * 100)
+                    }
+                }
+                writer.endInsert()
+            }
+            return anchors.toMap()
+        }
+
+        fun validate(anchors: Map<Anchor, Any?>) {
+            slots.read { reader ->
+                for (anchor in anchors) {
+                    assertEquals(anchor.value, reader.get(slots.anchorLocation(anchor.key)))
+                }
+            }
+        }
+
+        fun moveItems() {
+            slots.write { writer ->
+                writer.skipItem()
+                writer.moveItem(4)
+                writer.skipItem()
+                writer.skipItem()
+                writer.moveItem(1)
+                writer.skipItem()
+                writer.skipItem()
+                writer.moveItem(1)
+            }
+        }
+
+        val expected = listOf(1, 2, 3, 4, 5, 6, 7)
+        val anchors = buildSlots(expected)
+        validate(anchors)
+        moveItems()
+        validate(anchors)
+    }
+
+    @Test
+    fun testRemovingDuplicateAnchorsMidRange() {
+        val slots = testSlotsNumbered()
+
+        val anchors = slots.write { writer -> (0 until 10).map { writer.anchor(30) } }
+        slots.write { it.remove(20, 20) }
+        for (anchor in anchors) {
+            assertEquals(-1, anchor.location(slots))
+        }
+    }
+
+    @Test
+    fun testRemovingDuplicateAnchorsStartRange() {
+        val slots = testSlotsNumbered()
+        val anchors = slots.write { writer -> (0 until 10).map { writer.anchor(30) } }
+        slots.write { it.remove(30, 20) }
+        for (anchor in anchors) {
+            assertEquals(-1, anchor.location(slots))
+        }
+    }
+
+    @Test
+    fun testRemovingDuplicateAnchorsEndRange() {
+        val slots = testSlotsNumbered()
+        val anchors = slots.write { writer -> (0 until 10).map { writer.anchor(30) } }
+        slots.write { it.remove(20, 11) }
+        for (anchor in anchors) {
+            assertEquals(-1, anchor.location(slots))
+        }
+    }
+
+    @Test
+    fun testDuplicateAnchorIdentity() {
+        val slots = testSlotsNumbered()
+        val anchors = slots.write { writer -> (0 until 10).map { writer.anchor(it * 5) } }
+        slots.write { writer ->
+            anchors.forEachIndexed { index, anchor ->
+                assertTrue(anchor === writer.anchor(index * 5))
+            }
+        }
+    }
+
+    // Semantic tests (testing groups and nodes)
+
+    @Test
+    fun testExtractKeys() {
+        val slots = testItems()
+        slots.read { reader ->
+            reader.startGroup()
+            val keys = reader.extractItemKeys()
+            assertEquals(10, keys.size)
+            keys.forEachIndexed { i, keyAndLocation ->
+                assertEquals(i, keyAndLocation.key)
+            }
+        }
+    }
+
+    @Test
+    fun testMoveAnItem() {
+        val slots = testItems()
+        slots.write { writer ->
+            writer.startGroup()
+            writer.moveItem(5)
+        }
+        slots.read { reader ->
+            reader.startGroup()
+            reader.expectItem(5)
+            for (i in 0 until 5) {
+                reader.expectItem(i)
+            }
+            for (i in 6 until 10) {
+                reader.expectItem(i)
+            }
+            reader.endGroup()
+        }
+    }
+
+    @Test
+    fun testRemoveAnItem() {
+        val slots = testItems()
+        slots.write { writer ->
+            writer.startGroup()
+            for (i in 0 until 5) {
+                writer.skipItem()
+            }
+            writer.removeItem()
+            for (i in 6 until 10) {
+                writer.skipItem()
+            }
+            writer.endGroup()
+        }
+
+        slots.read { reader ->
+            reader.startGroup()
+            for (i in 0 until 5) {
+                reader.expectItem(i)
+            }
+            for (i in 6 until 10) {
+                reader.expectItem(i)
+            }
+            reader.endGroup()
+        }
+    }
+
+    @Test
+    fun testCountNodes() {
+        val slots = testItems()
+        slots.read { reader ->
+            reader.startGroup()
+            for (i in 0 until 10) {
+                val count = reader.expectItem(i)
+                assertEquals(i + 1, count)
+            }
+            reader.endGroup()
+        }
+    }
+
+    @Test
+    fun testCountNestedNodes() {
+        val slots = SlotTable()
+        slots.write { writer ->
+            writer.beginInsert()
+            writer.startGroup()
+            writer.startItem(null)
+            repeat(10) {
+                writer.startItem(null)
+                repeat(3) {
+                    writer.startNode()
+                    writer.endNode()
+                }
+                assertEquals(3, writer.endItem())
+            }
+            assertEquals(30, writer.endItem())
+            writer.endGroup()
+            writer.endInsert()
+        }
+
+        slots.read { reader ->
+            reader.startGroup()
+            assertEquals(30, reader.expectItem(null))
+            reader.endGroup()
+        }
+    }
+
+    @Test
+    fun testUpdateNestedNodeCountOnInsert() {
+        val slots = SlotTable()
+        slots.write { writer ->
+            writer.beginInsert()
+            writer.startGroup()
+            writer.startItem(null)
+            repeat(10) {
+                writer.startItem(null)
+                repeat(3) {
+                    writer.startItem(null)
+                    writer.startNode()
+                    writer.endNode()
+                    assertEquals(1, writer.endItem())
+                }
+                assertEquals(3, writer.endItem())
+            }
+            assertEquals(30, writer.endItem())
+            writer.endGroup()
+            writer.endInsert()
+        }
+
+        slots.write { writer ->
+            writer.startGroup()
+            writer.startItem(null)
+
+            repeat(3) {
+                assertEquals(3, writer.skipItem())
+            }
+
+            writer.startItem(null)
+            writer.beginInsert()
+            repeat(2) {
+                writer.startItem(null)
+                writer.startNode()
+                writer.endNode()
+                assertEquals(1, writer.endItem())
+            }
+            writer.endInsert()
+            repeat(3) { writer.skipItem() }
+            assertEquals(5, writer.endItem())
+
+            repeat(6) {
+                assertEquals(3, writer.skipItem())
+            }
+
+            assertEquals(32, writer.endItem())
+            writer.endGroup()
+        }
+    }
+
+    @Test
+    fun testUpdateNestedNodeCountOnRemove() {
+        val slots = SlotTable()
+        slots.write { writer ->
+            writer.beginInsert()
+            writer.startGroup()
+            writer.startItem(null)
+            repeat(10) {
+                writer.startItem(null)
+                repeat(3) {
+                    writer.startItem(null)
+                    writer.startNode()
+                    writer.endNode()
+                    assertEquals(1, writer.endItem())
+                }
+                assertEquals(3, writer.endItem())
+            }
+            assertEquals(30, writer.endItem())
+            writer.endGroup()
+            writer.endInsert()
+        }
+
+        slots.write { writer ->
+            writer.startGroup()
+            writer.startItem(null)
+
+            repeat(3) {
+                assertEquals(3, writer.skipItem())
+            }
+
+            writer.startItem(null)
+
+            repeat(2) { writer.removeItem() }
+            repeat(1) { writer.skipItem() }
+            assertEquals(1, writer.endItem())
+
+            repeat(6) {
+                assertEquals(3, writer.skipItem())
+            }
+
+            assertEquals(28, writer.endItem())
+
+            writer.endGroup()
+        }
+    }
+
+    @Test
+    fun testNodesResetNodeCount() {
+        val slots = SlotTable()
+        slots.write { writer ->
+            writer.beginInsert()
+            writer.startGroup()
+            writer.startItem(null)
+            writer.startNode()
+            repeat(10) {
+                writer.startNode()
+                writer.startItem(null)
+                repeat(3) {
+                    writer.startNode()
+                    writer.endNode()
+                }
+                assertEquals(3, writer.endItem())
+                writer.endNode()
+            }
+            writer.endNode()
+            assertEquals(1, writer.endItem())
+            writer.endGroup()
+            writer.endInsert()
+        }
+    }
+
+    @Test
+    fun testSkipANode() {
+        val slots = SlotTable()
+        slots.write { writer ->
+            writer.beginInsert()
+            writer.startGroup()
+            writer.startItem(null)
+            writer.startNode()
+            repeat(10) {
+                writer.startNode()
+                writer.startItem(null)
+                repeat(3) {
+                    writer.startNode()
+                    writer.endNode()
+                }
+                assertEquals(3, writer.endItem())
+                writer.endNode()
+            }
+            writer.endNode()
+            assertEquals(1, writer.endItem())
+            writer.endGroup()
+            writer.endInsert()
+        }
+
+        slots.read { reader ->
+            reader.startGroup()
+            reader.startItem(null)
+            assertEquals(1, reader.skipNode())
+            reader.endItem()
+            reader.endGroup()
+        }
+    }
+
+    @Test
+    fun testStartEmpty() {
+        val slots = SlotTable()
+        slots.read { reader ->
+            reader.beginEmpty()
+            reader.startGroup()
+            assertEquals(true, reader.inEmpty)
+            assertEquals(SlotTable.EMPTY, reader.next())
+            reader.endGroup()
+            reader.endEmpty()
+        }
+    }
+
+    @Test
+    fun testReportGroupSize() {
+        val slots = SlotTable()
+        slots.write { writer ->
+            writer.beginInsert()
+            writer.startGroup()
+            writer.startItem(null)
+            repeat(10) {
+                writer.startNode()
+                writer.endNode()
+            }
+            writer.endItem()
+            writer.update(42)
+            writer.endGroup()
+            writer.endInsert()
+        }
+
+        slots.read { reader ->
+            reader.startGroup()
+            reader.next()
+            assertEquals(true, reader.isGroup)
+            val size = reader.groupSize
+            val savedCurrent = reader.current
+            reader.skipGroup()
+            assertEquals(size, reader.current - savedCurrent - 1)
+            assertEquals(42, reader.next())
+            assertEquals(true, reader.isGroupEnd)
+            reader.endGroup()
+        }
+    }
+
+    @Test
+    fun testIsGroups() {
+        val slots = SlotTable()
+        slots.write { writer ->
+            writer.beginInsert()
+            writer.startGroup()
+            writer.startGroup()
+            writer.endGroup()
+            writer.startNode()
+            writer.endNode()
+            writer.endGroup()
+            writer.endInsert()
+        }
+
+        slots.read { reader ->
+            reader.startGroup()
+            assertEquals(true, reader.isGroup)
+            reader.startGroup()
+            assertEquals(false, reader.isGroup)
+            assertEquals(true, reader.isGroupEnd)
+            reader.endGroup()
+            assertEquals(true, reader.isNode)
+            assertEquals(false, reader.isGroupEnd)
+            reader.startNode()
+            assertEquals(false, reader.isNode)
+            assertEquals(true, reader.isGroupEnd)
+            reader.endNode()
+            reader.endGroup()
+        }
+
+        slots.write { writer ->
+            writer.startGroup()
+            assertEquals(true, writer.isGroup)
+            writer.startGroup()
+            assertEquals(false, writer.isGroup)
+            writer.endGroup()
+            assertEquals(true, writer.isNode)
+            writer.startNode()
+            assertEquals(false, writer.isNode)
+            writer.endNode()
+            writer.endGroup()
+        }
+    }
+
+    @Test
+    fun testReportUncertainNodeCount() {
+        val slots = SlotTable()
+        slots.read { reader -> reader.reportUncertainNodeCount() }
+    }
+
+    @Test
+    fun testMoveGroup() {
+        val slots = SlotTable()
+
+        val anchors = mutableListOf<Anchor>()
+
+        fun buildSlots() {
+            slots.write { writer ->
+                fun group(block: () -> Unit) {
+                    writer.startGroup()
+                    block()
+                    writer.endGroup()
+                }
+
+                fun item(key: Any?, block: () -> Unit) {
+                    writer.startItem(key)
+                    block()
+                    writer.endItem()
+                }
+
+                fun element(key: Any?, block: () -> Unit) {
+                    writer.update(key)
+                    writer.startNode()
+                    block()
+                    writer.endNode()
+                }
+
+                fun value(value: Any) {
+                    writer.update(value)
+                }
+
+                fun innerItem(i: Any) {
+                    item(i) {
+                        value(i)
+                        value(25)
+                        item(26) {
+                            item(28) {
+                                value(30)
+                                item(31) {
+                                    item(33) {
+                                        group {
+                                            value(36)
+                                            item(37) {
+                                                value(39)
+                                                element(40) {
+                                                    value(42)
+                                                    value(43)
+                                                    element(44) {
+                                                        value(46)
+                                                        value(47)
+                                                    }
+                                                    element(48) {
+                                                        value(50)
+                                                        value(51)
+                                                        value(52)
+                                                        value(53)
+                                                    }
+                                                    element(54) {
+                                                        value(56)
+                                                        value(57)
+                                                        value(58)
+                                                        value(59)
+                                                    }
+                                                    element(60) {
+                                                        value(62)
+                                                        anchors.add(
+                                                            slots.anchor(writer.current - 1)
+                                                        )
+                                                        value(63)
+                                                        value(64)
+                                                        value(65)
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                // Build a slot table to that duplicates the structure of the slot table produced
+                // in the code generation test testMovement()
+                writer.beginInsert()
+                item(0) {
+                    item(2) {
+                        item(4) {
+                            item(6) {
+                                value(8)
+                                item(9) {
+                                    item(11) {
+                                        group {
+                                            value(14)
+                                            item(15) {
+                                                value(17)
+                                                element(18) {
+                                                    value(20)
+                                                    value(21)
+                                                    for (i in 1..5) {
+                                                        innerItem(i)
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                writer.endInsert()
+            }
+        }
+
+        fun validateSlots(range: List<Int>) {
+            slots.read { reader ->
+                fun group(block: () -> Unit) {
+                    reader.startGroup()
+                    block()
+                    reader.endGroup()
+                }
+
+                fun value(value: Any?) {
+                    assertEquals(value, reader.next())
+                }
+
+                fun item(key: Any?, block: () -> Unit) {
+                    reader.startItem(key)
+                    block()
+                    reader.endItem()
+                }
+
+                fun element(key: Any?, block: () -> Unit) {
+                    value(key)
+                    reader.startNode()
+                    block()
+                    reader.endNode()
+                }
+
+                fun innerBlock(i: Any) {
+                    item(i) {
+                        value(i)
+                        value(25)
+                        item(26) {
+                            item(28) {
+                                value(30)
+                                item(31) {
+                                    item(33) {
+                                        group {
+                                            value(36)
+                                            item(37) {
+                                                value(39)
+                                                element(40) {
+                                                    value(42)
+                                                    value(43)
+                                                    element(44) {
+                                                        value(46)
+                                                        value(47)
+                                                    }
+                                                    element(48) {
+                                                        value(50)
+                                                        value(51)
+                                                        value(52)
+                                                        value(53)
+                                                    }
+                                                    element(54) {
+                                                        value(56)
+                                                        value(57)
+                                                        value(58)
+                                                        value(59)
+                                                    }
+                                                    element(60) {
+                                                        value(62)
+                                                        value(63)
+                                                        value(64)
+                                                        value(65)
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                item(0) {
+                    item(2) {
+                        item(4) {
+                            item(6) {
+                                value(8)
+                                item(9) {
+                                    item(11) {
+                                        group {
+                                            value(14)
+                                            item(15) {
+                                                value(17)
+                                                element(18) {
+                                                    value(20)
+                                                    value(21)
+                                                    for (i in range) {
+                                                        innerBlock(i)
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        fun moveItem5Up() {
+            slots.write { writer ->
+                fun group(block: () -> Unit) {
+                    writer.startGroup()
+                    block()
+                    writer.endGroup()
+                }
+
+                fun item(key: Any?, block: () -> Unit) {
+                    writer.startItem(key)
+                    block()
+                    writer.endItem()
+                }
+
+                fun element(key: Any?, block: () -> Unit) {
+                    writer.update(key)
+                    writer.startNode()
+                    block()
+                    writer.endNode()
+                }
+
+                fun value(value: Any) {
+                    writer.update(value)
+                }
+                item(0) {
+                    item(2) {
+                        item(4) {
+                            item(6) {
+                                value(8)
+                                item(9) {
+                                    item(11) {
+                                        group {
+                                            value(14)
+                                            item(15) {
+                                                value(17)
+                                                element(18) {
+                                                    value(20)
+                                                    value(21)
+
+                                                    // Skip three items
+                                                    writer.skipItem()
+                                                    writer.skipItem()
+                                                    writer.skipItem()
+
+                                                    // Move one item up
+                                                    writer.moveItem(1)
+
+                                                    // Skip them
+                                                    writer.skipItem()
+                                                    writer.skipItem()
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        buildSlots()
+        validateSlots((1..5).toList())
+        moveItem5Up()
+        validateSlots(listOf(1, 2, 3, 5, 4))
+
+        // Validate that all the anchors still refer to a slot with value 62
+        slots.read { reader ->
+            for (anchor in anchors) {
+                assertEquals(62, reader.get(slots.anchorLocation(anchor)))
+            }
+        }
+    }
+}
+
+fun testSlotsNumbered(): SlotTable {
+    val items = arrayOfNulls<Any?>(100)
+    repeat(100) {
+        items[it] = it
+    }
+    return SlotTable(items)
+}
+
+private val elementKey = object {}
+// Creates 0 until 10 items each with 10 elements numbered 0...n with 0..n slots
+fun testItems(): SlotTable {
+    val slots = SlotTable()
+    slots.write { writer ->
+        writer.beginInsert()
+        writer.startGroup()
+
+        fun item(key: Any?, block: () -> Unit) {
+            writer.startItem(key)
+            block()
+            writer.endItem()
+        }
+
+        fun element(key: Any?, block: () -> Unit) {
+            item(key) {
+                writer.startNode()
+                block()
+                writer.endNode()
+            }
+        }
+
+        for (key in 0 until 10) {
+            item(key) {
+                for (item in 0..key) {
+                    element(elementKey) {
+                        for (element in 0..key)
+                            writer.update(element)
+                    }
+                }
+            }
+        }
+
+        writer.endGroup()
+        writer.endInsert()
+    }
+
+    return slots
+}
+
+fun SlotReader.startItem(key: Any?) {
+    assertEquals(key, next())
+    startGroup()
+}
+fun SlotReader.endItem(): Int = endGroup()
+
+fun SlotReader.expectItem(key: Any?): Int {
+    assertEquals(key, next())
+    return skipGroup()
+}
+
+fun SlotWriter.startItem(key: Any?) {
+    update(key)
+    startGroup()
+}
+fun SlotWriter.endItem(): Int = endGroup()
diff --git a/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/frames/Address.kt b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/frames/Address.kt
new file mode 100644
index 0000000..2ad011e
--- /dev/null
+++ b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/frames/Address.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2019 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.frames
+
+class Address(street: String, city: String) : Framed {
+    var street: String
+        get() = next.readable(this).street
+        set(value) { next.writable(this).street = value }
+
+    var city: String
+        get() = next.readable(this).city
+        set(value) { next.writable(this).city = value }
+
+    private var next: AddressRecord
+
+    init {
+        next = AddressRecord()
+        next.street = street
+        next.city = city
+    }
+
+    override fun prependFrameRecord(value: Record) {
+        value.next = next
+        next = value as AddressRecord
+    }
+
+    override val firstFrameRecord: AddressRecord get() = next
+}
+
+class AddressRecord : AbstractRecord() {
+    var street: String = ""
+    var city: String = ""
+
+    override fun create(): Record = AddressRecord()
+    override fun assign(value: Record) {
+        val other = value as AddressRecord
+        street = other.street
+        city = other.city
+    }
+}
diff --git a/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/frames/FramesTests.kt b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/frames/FramesTests.kt
new file mode 100644
index 0000000..75def29
--- /dev/null
+++ b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/frames/FramesTests.kt
@@ -0,0 +1,1193 @@
+/*
+ * Copyright 2019 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.frames
+
+import androidx.compose.Stack
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+
+const val OLD_STREET = "123 Any Street"
+const val OLD_CITY = "AnyTown"
+const val NEW_STREET = "456 New Street"
+const val NEW_CITY = "AnyCity"
+
+class FrameTest {
+
+    @Test
+    fun testCreatingAddress() {
+                val address = frame {
+            val address = Address(
+                OLD_STREET,
+                OLD_CITY
+            )
+            assertEquals(OLD_STREET, address.street)
+            assertEquals(OLD_CITY, address.city)
+            address
+        }
+        frame {
+            assertEquals(OLD_STREET, address.street)
+            assertEquals(OLD_CITY, address.city)
+        }
+    }
+
+    @Test
+    fun testModifyingAddress() {
+        val address = frame {
+            Address(
+                OLD_STREET,
+                OLD_CITY
+            )
+        }
+        frame {
+            address.street = NEW_STREET
+        }
+        frame {
+            assertEquals(NEW_STREET, address.street)
+            assertEquals(OLD_CITY, address.city)
+        }
+    }
+
+    @Test
+    fun testIsolation() {
+        val address = frame {
+            Address(
+                OLD_STREET,
+                OLD_CITY
+            )
+        }
+        val f = suspended {
+            address.street = NEW_STREET
+        }
+        frame {
+            assertEquals(OLD_STREET, address.street)
+        }
+        restored(f) {
+            assertEquals(NEW_STREET, address.street)
+        }
+        frame {
+            assertEquals(NEW_STREET, address.street)
+        }
+    }
+
+    @Test
+    fun testRecordReuse() {
+        val address = frame {
+            Address(
+                OLD_STREET,
+                OLD_CITY
+            )
+        }
+        assertEquals(1, address.firstFrameRecord.length)
+        frame { address.street = NEW_STREET }
+        assertEquals(2, address.firstFrameRecord.length)
+        frame { address.street = "other street" }
+        assertEquals(2, address.firstFrameRecord.length)
+    }
+
+    @Test
+    fun testAborted() {
+        val address = frame {
+            Address(
+                OLD_STREET,
+                OLD_CITY
+            )
+        }
+        aborted {
+            address.street = NEW_STREET
+            assertEquals(NEW_STREET, address.street)
+        }
+        frame {
+            assertEquals(OLD_STREET, address.street)
+        }
+    }
+
+    @Test
+    fun testReuseAborted() {
+        val address = frame {
+            Address(
+                OLD_STREET,
+                OLD_CITY
+            )
+        }
+        assertEquals(1, address.firstFrameRecord.length)
+        aborted { address.street = NEW_STREET }
+        assertEquals(2, address.firstFrameRecord.length)
+        frame { address.street = "other street" }
+        assertEquals(2, address.firstFrameRecord.length)
+    }
+
+    @Test
+    fun testSpeculation() {
+        val address = frame {
+            Address(
+                OLD_STREET,
+                OLD_CITY
+            )
+        }
+        speculation {
+            address.street = NEW_STREET
+            assertEquals(NEW_STREET, address.street)
+        }
+        frame {
+            assertEquals(OLD_STREET, address.street)
+        }
+    }
+
+    @Test
+    fun testSpeculationIsolation() {
+        val address = frame {
+            Address(
+                OLD_STREET,
+                OLD_CITY
+            )
+        }
+        speculate()
+        address.street = NEW_STREET
+        val speculation = suspend()
+        frame {
+            assertEquals(OLD_STREET, address.street)
+        }
+        restore(speculation)
+        assertEquals(NEW_STREET, address.street)
+        abortHandler()
+        frame {
+            assertEquals(OLD_STREET, address.street)
+        }
+    }
+
+    @Test
+    fun testReuseSpeculation() {
+        val address = frame {
+            Address(
+                OLD_STREET,
+                OLD_CITY
+            )
+        }
+        assertEquals(1, address.firstFrameRecord.length)
+        speculation { address.street = NEW_STREET }
+        assertEquals(2, address.firstFrameRecord.length)
+        frame { address.street = "other street" }
+        assertEquals(2, address.firstFrameRecord.length)
+    }
+
+    @Test
+    fun testCommitAbortInteraction() {
+        val address = frame {
+            Address(
+                OLD_STREET,
+                OLD_CITY
+            )
+        }
+        val frame1 = suspended {
+            address.street = "From frame1"
+        }
+        val frame2 = suspended {
+            address.street = "From frame2"
+        }
+
+        // New frames should see the old value
+        frame {
+            assertEquals(
+                OLD_STREET,
+                address.street
+            )
+        }
+
+        // Aborting frame2 and committing frame1 should result in frame1
+        abortHandler(frame2)
+
+        // New frames should still see the old value
+        frame {
+            assertEquals(
+                OLD_STREET,
+                address.street
+            )
+        }
+
+        // Commit frame1, new frames should see frame1's value
+        commit(frame1)
+        frame { assertEquals("From frame1", address.street) }
+    }
+
+    @Test
+    fun testCollisionAB() {
+        val address = frame {
+            Address(
+                OLD_STREET,
+                OLD_CITY
+            )
+        }
+        expectThrow<FrameAborted> {
+            val frame1 = suspended {
+                address.street = "From frame1"
+            }
+            val frame2 = suspended {
+                address.street = "From frame2"
+            }
+
+            commit(frame1)
+
+            // This should throw
+            commit(frame2)
+        }
+
+        // New frames should see the value from the committed frame1
+        frame {
+            assertEquals("From frame1", address.street)
+        }
+    }
+
+    @Test
+    fun testCollisionBA() {
+        val address = frame {
+            Address(
+                OLD_STREET,
+                OLD_CITY
+            )
+        }
+        expectThrow<FrameAborted> {
+            val frame1 = suspended {
+                address.street = "From frame1"
+            }
+            val frame2 = suspended {
+                address.street = "From frame2"
+            }
+
+            commit(frame2)
+
+            // This should throw
+            commit(frame1)
+        }
+
+        // New frames should see the value from the committed frame2
+        frame {
+            assertEquals("From frame2", address.street)
+        }
+    }
+
+    @Test
+    fun testManyChangesInASingleFrame() {
+        val changeCount = 1000
+        val addresses = frame {
+            (0..changeCount).map {
+                Address(
+                    OLD_STREET,
+                    OLD_CITY
+                )
+            }
+        }
+        val frame1 = suspended {
+            for (i in 0..changeCount) {
+                addresses[i].street = "From index $i"
+            }
+            for (i in 0..changeCount) {
+                assertEquals("From index $i", addresses[i].street)
+            }
+        }
+        frame {
+            for (i in 0..changeCount) {
+                assertEquals(OLD_STREET, addresses[i].street)
+            }
+        }
+        commit(frame1)
+        frame {
+            for (i in 0..changeCount) {
+                assertEquals("From index $i", addresses[i].street)
+            }
+        }
+    }
+
+    @Test
+    fun testManySimultaneousFrames() {
+        val frameCount = 1000
+        val frames = Stack<Frame>()
+        val addresses = frame {
+            (0..frameCount).map {
+                Address(
+                    OLD_STREET,
+                    OLD_CITY
+                )
+            }
+        }
+        for (i in 0..frameCount) {
+            frames.push(suspended { addresses[i].street = "From index $i" })
+        }
+        for (i in 0..frameCount) {
+            commit(frames.pop())
+        }
+        for (i in 0..frameCount) {
+            frame {
+                assertEquals(
+                    "From index $i",
+                    addresses[i].street
+                )
+            }
+        }
+    }
+
+    @Test
+    fun testRaw() {
+        val count = 1000
+        val addresses = (0..count).map { AddressRaw(OLD_STREET) }
+        for (i in 0..count) {
+            addresses[i].street = "From index $i"
+            assertEquals("From index $i", addresses[i].street)
+        }
+        for (i in 0..count) {
+            assertEquals("From index $i", addresses[i].street)
+        }
+    }
+
+    @Test
+    fun testProp() {
+        val count = 10000
+        val addresses = (0..count).map { AddressProp(OLD_STREET) }
+        for (i in 0..count) {
+            addresses[i].street = "From index $i"
+            assertEquals("From index $i", addresses[i].street)
+        }
+        for (i in 0..count) {
+            assertEquals("From index $i", addresses[i].street)
+        }
+    }
+
+    @Test
+    fun testFrameObserver_ObserveRead_Single() {
+        val address = frame {
+            Address(
+                OLD_STREET,
+                OLD_CITY
+            )
+        }
+        var read: Address? = null
+        observeFrame({ obj ->
+            read = obj as Address
+        }) {
+            assertEquals(OLD_STREET, address.street)
+        }
+        assertEquals(address, read)
+    }
+
+    @Test
+    fun testFrameObserver_addReadObserver_Single() {
+        val address = frame {
+            Address(
+                OLD_STREET,
+                OLD_CITY
+            )
+        }
+        var read: Address? = null
+        var otherRead: Address? = null
+        val frame = open({ obj -> read = obj as Address })
+        try {
+            frame.observeReads({ obj -> otherRead = obj as Address }) {
+                assertEquals(OLD_STREET, address.street)
+            }
+            assertEquals(1, frame.readObservers.size)
+        } finally {
+            commitHandler()
+        }
+        assertEquals(address, read)
+        assertEquals(address, otherRead)
+    }
+
+    @Test
+    fun testFrameObserver_ObserveCommit_Single() {
+        val address = frame {
+            Address(
+                OLD_STREET,
+                OLD_CITY
+            )
+        }
+        var committed: Set<Any>? = null
+        observeCommit({ framed: Set<Any> -> committed = framed }) {
+            frame {
+                address.street = NEW_STREET
+            }
+        }
+        assertTrue(committed?.contains(address) ?: false)
+    }
+
+    @Test
+    fun testFrameObserver_OberveRead_Multiple() {
+        val addressToRead = frame {
+            List(100) {
+                Address(
+                    OLD_STREET,
+                    OLD_CITY
+                )
+            }
+        }
+        val addressToIgnore = frame {
+            List(100) {
+                Address(
+                    OLD_STREET,
+                    OLD_CITY
+                )
+            }
+        }
+        val readAddresses = HashSet<Address>()
+        observeFrame({ obj -> readAddresses.add(obj as Address) }) {
+            for (address in addressToRead) {
+                assertEquals(OLD_STREET, address.street)
+            }
+        }
+        for (address in addressToRead) {
+            assertTrue(
+                readAddresses.contains(address),
+                "Ensure a read callback was called for the address"
+                )
+        }
+        for (address in addressToIgnore) {
+            assertFalse(
+                readAddresses.contains(address),
+                "Ensure a read callback was not called for the address"
+                )
+        }
+    }
+
+    @Test
+    fun testFrameObserver_ObserveCommit_Multiple() {
+        val addressToWrite = frame {
+            List(100) {
+                Address(
+                    OLD_STREET,
+                    OLD_CITY
+                )
+            }
+        }
+        val addressToIgnore = frame {
+            List(100) {
+                Address(
+                    OLD_STREET,
+                    OLD_CITY
+                )
+            }
+        }
+        var committedAddresses = null as Set<Any>?
+        observeCommit({ framed -> committedAddresses = framed }) {
+            frame {
+                for (address in addressToWrite) {
+                    address.street = NEW_STREET
+                }
+            }
+        }
+        for (address in addressToWrite) {
+            assertTrue(
+                committedAddresses?.contains(address) ?: false,
+                "Ensure written address is in the set of committed objects"
+                )
+        }
+        for (address in addressToIgnore) {
+            assertFalse(
+                committedAddresses?.contains(address) ?: false,
+                "Ensure ignored addresses are not in the set of committed objects"
+                )
+        }
+    }
+
+    @Test
+    fun testModelList_Isolated() {
+        val addresses = frame {
+            modelListOf(*(Array(100) {
+                Address(
+                    OLD_STREET,
+                    OLD_CITY
+                )
+            }))
+        }
+
+        fun validateOriginal() {
+            assertFalse(wasModified(addresses))
+            assertEquals(100, addresses.size)
+
+            // Iterate list
+            for (address in addresses) {
+                assertEquals(OLD_STREET, address.street)
+            }
+            assertFalse(wasModified(addresses))
+        }
+
+        fun validateNew() {
+            assertEquals(101, addresses.size)
+
+            // Iterate list
+            for (i in 0 until 100) {
+                assertEquals(OLD_STREET, addresses[i].street)
+            }
+
+            assertEquals(NEW_STREET, addresses[100].street)
+        }
+
+        frame { validateOriginal() }
+
+        val frame1 = suspended {
+            // Insert into the list
+            addresses.add(
+                Address(
+                    NEW_STREET,
+                    NEW_CITY
+                )
+            )
+
+            validateNew()
+        }
+
+        frame { validateOriginal() }
+
+        restored(frame1) {
+            validateNew()
+        }
+    }
+
+    @Test
+    fun testModelList_ReadDoesNotModify() {
+        val count = 10
+        val addresses = frame {
+            modelListOf(*(Array(count) {
+                Address(
+                    OLD_STREET,
+                    OLD_CITY
+                )
+            }))
+        }
+
+        // size should not modify
+        frame {
+            assertEquals(count, addresses.size)
+            assertFalse(wasModified(addresses))
+        }
+
+        // get should not modify
+        frame {
+            val address = addresses[0]
+            assertEquals(OLD_STREET, address.street)
+            assertFalse(wasModified(addresses))
+            assertFalse(wasModified(address))
+        }
+
+        // Iteration should not modify
+        frame {
+            for (address in addresses) {
+                assertEquals(OLD_STREET, address.street)
+                assertFalse(wasModified(address))
+            }
+            assertFalse(wasModified(addresses))
+        }
+
+        // contains should not modify
+        frame {
+            val address = addresses[1]
+            assertTrue(addresses.contains(address))
+            assertFalse(wasModified(addresses))
+        }
+
+        // containsAll should not modify
+        frame {
+            val sublist = listOf(addresses[1], addresses[2])
+            assertTrue(addresses.containsAll(sublist))
+            assertFalse(wasModified(addresses))
+        }
+
+        // indexOf of should not modify
+        frame {
+            val address = addresses[5]
+            assertEquals(5, addresses.indexOf(address))
+            assertFalse(wasModified(addresses))
+        }
+
+        // IsEmpty should not modify
+        frame {
+            assertFalse(addresses.isEmpty())
+            assertTrue(addresses.isNotEmpty())
+            assertFalse(wasModified(addresses))
+        }
+
+        // lastIndexOf should not modify
+        frame {
+            val address = addresses[5]
+            assertEquals(5, addresses.lastIndexOf(address))
+            assertFalse(wasModified(addresses))
+        }
+
+        // listIterator should not modify
+        frame {
+            for (address in addresses.listIterator()) {
+                assertEquals(OLD_STREET, address.street)
+            }
+            assertFalse(wasModified(addresses))
+            for (address in addresses.listIterator(5)) {
+                assertEquals(OLD_STREET, address.street)
+            }
+            assertFalse(wasModified(addresses))
+        }
+    }
+
+    @Test
+    fun testModelList_MutateThrows() {
+        val count = 10
+        val addresses = frame {
+            modelListOf(*(Array(count) {
+                Address(
+                    OLD_STREET,
+                    OLD_CITY
+                )
+            }))
+        }
+
+        // Expect iterator.remove to throw
+        frame {
+            val iterator = addresses.iterator()
+            assertTrue(iterator.hasNext())
+            iterator.next()
+            expectError {
+                iterator.remove()
+            }
+            assertFalse(wasModified(addresses))
+        }
+
+        // Expect listIterator.remove to throw
+        frame {
+            val iterator = addresses.listIterator()
+            assertTrue(iterator.hasNext())
+            iterator.next()
+            expectError {
+                iterator.remove()
+            }
+            assertFalse(wasModified(addresses))
+        }
+
+        // Expect listIterator.set to throw
+        frame {
+            val iterator = addresses.listIterator()
+            assertTrue(iterator.hasNext())
+            iterator.next()
+            expectError {
+                iterator.set(
+                    Address(
+                        NEW_STREET,
+                        NEW_CITY
+                    )
+                )
+            }
+            assertFalse(wasModified(addresses))
+        }
+
+        // Expect listIterator.add to throw
+        frame {
+            val iterator = addresses.listIterator()
+            assertTrue(iterator.hasNext())
+            iterator.next()
+            expectError {
+                iterator.add(
+                    Address(
+                        NEW_STREET,
+                        NEW_CITY
+                    )
+                )
+            }
+            assertFalse(wasModified(addresses))
+        }
+    }
+
+    @Test
+    fun testModelList_MutatingModifies() {
+        val count = 10
+        val addresses = frame {
+            modelListOf(*(Array(count) {
+                Address(
+                    OLD_STREET,
+                    OLD_CITY
+                )
+            }))
+        }
+
+        fun validate(block: () -> Unit) {
+            aborted {
+                assertFalse(wasModified(addresses))
+                block()
+                assertTrue(wasModified(addresses))
+            }
+            frame {
+                assertEquals(addresses.size, count)
+                for (address in addresses) {
+                    assertEquals(address.street, OLD_STREET)
+                    assertEquals(address.city, OLD_CITY)
+                }
+            }
+        }
+
+        // Expect add to modify
+        validate { addresses.add(
+            Address(
+                NEW_STREET,
+                OLD_CITY
+            )
+        ) }
+        validate { addresses.add(5,
+            Address(
+                NEW_STREET,
+                OLD_CITY
+            )
+        ) }
+
+        // Expect addAll to modify
+        validate {
+            addresses.addAll(listOf(
+                Address(
+                    NEW_STREET,
+                    NEW_CITY
+                ),
+                Address(
+                    NEW_STREET,
+                    NEW_CITY
+                )
+            ))
+        }
+        validate {
+            addresses.addAll(
+                5,
+                listOf(
+                    Address(
+                        NEW_STREET,
+                        NEW_CITY
+                    ),
+                    Address(
+                        NEW_STREET,
+                        NEW_CITY
+                    )
+                )
+            )
+        }
+
+        // Expect clear to modify
+        validate { addresses.clear() }
+
+        // Expect remove to modify
+        validate {
+            val address = addresses[5]
+            addresses.remove(address)
+        }
+
+        // Expect removeAll to modify
+        validate { addresses.removeAll(listOf(addresses[5], addresses[6])) }
+
+        // Expect removeAt to modify
+        validate { addresses.removeAt(5) }
+
+        // Expect retainAll to modify
+        validate { addresses.retainAll(listOf(addresses[5], addresses[6])) }
+
+        // Expect set to modify
+        validate { addresses[5] = Address(
+            NEW_STREET,
+            NEW_CITY
+        )
+        }
+
+        // Expect subList to modify
+        validate { addresses.subList(5, 6) }
+
+        // Expecte asMutable to modify
+        validate { addresses.asMutable() }
+    }
+
+    @Test
+    fun testModelMap_Isolated() {
+        val map = frame {
+            modelMapOf(
+                1 to "a",
+                2 to "b",
+                3 to "c",
+                4 to "d"
+            )
+        }
+
+        fun validateOld() {
+            assertEquals(4, map.size)
+            assertTrue(map.contains(1))
+            assertTrue(map.contains(2))
+            assertTrue(map.contains(3))
+            assertTrue(map.contains(4))
+            assertEquals(map[1], "a")
+            assertEquals(map[2], "b")
+            assertEquals(map[3], "c")
+            assertEquals(map[4], "d")
+        }
+
+        fun validateNew() {
+            assertEquals(5, map.size)
+            assertTrue(map.contains(1))
+            assertTrue(map.contains(2))
+            assertTrue(map.contains(3))
+            assertTrue(map.contains(4))
+            assertTrue(map.contains(5))
+            assertEquals(map[1], "a")
+            assertEquals(map[2], "b")
+            assertEquals(map[3], "c")
+            assertEquals(map[4], "d")
+            assertEquals(map[5], "e")
+        }
+
+        frame { validateOld() }
+
+        val frame1 = suspended {
+            validateOld()
+
+            map[5] = "e"
+
+            validateNew()
+        }
+
+        frame { validateOld() }
+        restored(frame1) { validateNew() }
+        frame { validateNew() }
+    }
+
+    @Test
+    @Suppress("USELESS_IS_CHECK")
+    fun testModelMap_ReadingDoesntModify() {
+        val map = frame {
+            modelMapOf(
+                1 to "a",
+                2 to "b",
+                3 to "c",
+                4 to "d"
+            )
+        }
+
+        fun validateOld() {
+            assertEquals(4, map.size)
+            assertTrue(map.contains(1))
+            assertTrue(map.contains(2))
+            assertTrue(map.contains(3))
+            assertTrue(map.contains(4))
+            assertEquals(map[1], "a")
+            assertEquals(map[2], "b")
+            assertEquals(map[3], "c")
+            assertEquals(map[4], "d")
+        }
+
+        fun validate(block: () -> Unit) {
+            frame {
+                validateOld()
+                block()
+                assertFalse(wasModified(map))
+                validateOld()
+            }
+        }
+
+        // size should not modify
+        validate { assertEquals(4, map.size) }
+
+        // contains should not modify
+        validate { assertTrue(map.contains(1)) }
+
+        // containsKey should not modify
+        validate { assertTrue(map.containsKey(1)) }
+
+        // containsValue should not modify
+        validate { assertTrue(map.containsValue("a")) }
+
+        // get should not modify
+        validate { assertEquals("a", map[1]) }
+
+        // isEmpty should not modify
+        validate { assertFalse(map.isEmpty()) }
+        validate { assertTrue(map.isNotEmpty()) }
+
+        // iterating entries should not modify
+        validate {
+            for (entry in map) {
+                assertTrue(entry.value is String)
+                assertTrue(entry.key is Int)
+            }
+            for (entry in map.entries) {
+                assertTrue(entry.value is String)
+                assertTrue(entry.key is Int)
+            }
+        }
+
+        // iterating keys should not modify
+        validate {
+            for (key in map.keys) {
+                assertTrue(key is Int)
+            }
+        }
+
+        // iterating values should not modify
+        validate {
+            for (value in map.values) {
+                assertTrue(value is String)
+            }
+        }
+    }
+
+    @Test
+    fun testModelMap_Mutation() {
+        val map = frame {
+            modelMapOf(
+                1 to "a",
+                2 to "b",
+                3 to "c",
+                4 to "d"
+            )
+        }
+
+        fun validateOld() {
+            assertEquals(4, map.size)
+            assertTrue(map.contains(1))
+            assertTrue(map.contains(2))
+            assertTrue(map.contains(3))
+            assertTrue(map.contains(4))
+            assertEquals(map[1], "a")
+            assertEquals(map[2], "b")
+            assertEquals(map[3], "c")
+            assertEquals(map[4], "d")
+        }
+
+        fun validate(block: () -> Unit) {
+            aborted {
+                assertFalse(wasModified(map))
+                validateOld()
+                block()
+                assertTrue(wasModified(map))
+            }
+        }
+
+        // clear should modify
+        validate { map.clear() }
+
+        // put should modify
+        validate { map[5] = "e" }
+
+        // putAll should modify
+        validate { map.putAll(mapOf(5 to "e", 6 to "f")) }
+
+        // remove should modify
+        validate { map.remove(3) }
+    }
+
+    @Test
+    fun testModelMap_MutateThrows() {
+        val map = frame {
+            modelMapOf(
+                1 to "a",
+                2 to "b",
+                3 to "c",
+                4 to "d"
+            )
+        }
+
+        fun validateOld() {
+            assertEquals(4, map.size)
+            assertTrue(map.contains(1))
+            assertTrue(map.contains(2))
+            assertTrue(map.contains(3))
+            assertTrue(map.contains(4))
+            assertEquals(map[1], "a")
+            assertEquals(map[2], "b")
+            assertEquals(map[3], "c")
+            assertEquals(map[4], "d")
+        }
+
+        fun validate(block: () -> Unit) {
+            frame {
+                assertFalse(wasModified(map))
+                validateOld()
+                expectError {
+                    block()
+                }
+                assertFalse(wasModified(map))
+            }
+        }
+
+        // Expect mutating through entries to throw
+        validate { map.entries.add(map.entries.first()) }
+        validate {
+            map.entries.addAll(listOf(map.entries.first(), map.entries.drop(1).first()))
+        }
+        validate { map.entries.clear() }
+        validate { map.entries.remove(map.entries.first()) }
+        validate {
+            map.entries.removeAll(listOf(map.entries.first(), map.entries.drop(1).first()))
+        }
+        validate {
+            map.entries.retainAll(listOf(map.entries.first(), map.entries.drop(1).first()))
+        }
+        validate {
+            val iterator = map.entries.iterator()
+            iterator.next()
+            iterator.remove()
+        }
+
+        // Expect mutating through keys to throw
+        validate { map.keys.add(map.keys.first()) }
+        validate { map.keys.addAll(listOf(map.keys.first(), map.keys.drop(1).first())) }
+        validate { map.keys.clear() }
+        validate { map.keys.remove(map.keys.first()) }
+        validate { map.keys.removeAll(listOf(map.keys.first(), map.keys.drop(1).first())) }
+        validate { map.keys.retainAll(listOf(map.keys.first(), map.keys.drop(1).first())) }
+        validate {
+            val iterator = map.keys.iterator()
+            iterator.next()
+            iterator.remove()
+        }
+
+        // Expect mutating through values to throw
+        validate { map.values.add(map.values.first()) }
+        validate { map.values.addAll(listOf(map.values.first(), map.values.drop(1).first())) }
+        validate { map.values.clear() }
+        validate { map.values.remove(map.values.first()) }
+        validate {
+            map.values.removeAll(listOf(map.values.first(), map.values.drop(1).first()))
+        }
+        validate {
+            map.values.retainAll(listOf(map.values.first(), map.values.drop(1).first()))
+        }
+        validate {
+            val iterator = map.values.iterator()
+            iterator.next()
+            iterator.remove()
+        }
+    }
+}
+
+fun expectError(block: () -> Unit) {
+    var thrown = false
+    try {
+        block()
+    } catch (e: IllegalStateException) {
+        thrown = true
+    }
+    assertTrue(thrown)
+}
+
+// Helpers for the above tests
+
+inline fun <T> frame(crossinline block: () -> T): T {
+    open(false)
+    try {
+        return block()
+    } catch (e: Exception) {
+        abortHandler()
+        throw e
+    } finally {
+        commitHandler()
+    }
+}
+
+inline fun <T> observeFrame(noinline observer: FrameReadObserver, crossinline block: () -> T): T {
+    open(observer)
+    try {
+        return block()
+    } catch (e: Exception) {
+        abortHandler()
+        throw e
+    } finally {
+        commitHandler()
+    }
+}
+
+inline fun <T> observeCommit(
+    noinline observer: FrameCommitObserver,
+    crossinline block: () -> T
+): T {
+    val unregister = registerCommitObserver(observer)
+    try {
+        return block()
+    } finally {
+        unregister()
+    }
+}
+
+inline fun suspended(crossinline block: () -> Unit): Frame {
+    open(false)
+    try {
+        block()
+        return suspend()
+    } catch (e: Exception) {
+        abortHandler()
+        throw e
+    }
+}
+
+inline fun <T> restored(frame: Frame, crossinline block: () -> T): T {
+    restore(frame)
+    try {
+        return block()
+    } catch (e: Exception) {
+        abortHandler()
+        throw e
+    } finally {
+        commitHandler()
+    }
+}
+
+inline fun aborted(crossinline block: () -> Unit) {
+    open(false)
+    try {
+        block()
+    } finally {
+        abortHandler()
+    }
+}
+
+inline fun speculation(crossinline block: () -> Unit) {
+    speculate()
+    try {
+        block()
+    } finally {
+        abortHandler()
+    }
+}
+
+inline fun <reified T : Throwable> expectThrow(
+    crossinline block: () -> Unit
+) {
+    var thrown = false
+    try {
+        block()
+    } catch (e: Throwable) {
+        assertTrue(e is T)
+        thrown = true
+    }
+    assertTrue(thrown)
+}
+
+val Record.length: Int
+    get() {
+        var current: Record? = this
+        var len = 0
+        while (current != null) {
+            len++
+            current = current.next
+        }
+        return len
+    }
+
+class AddressRaw(var street: String)
+
+class AddressProp(streetValue: String) {
+    var _street = streetValue
+
+    var street: String
+        get() = _street
+        set(value) { _street = value }
+}
diff --git a/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/ComposeContact.kt b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/ComposeContact.kt
similarity index 100%
rename from compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/ComposeContact.kt
rename to compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/ComposeContact.kt
diff --git a/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/ComposePoints.kt b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/ComposePoints.kt
similarity index 100%
rename from compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/ComposePoints.kt
rename to compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/ComposePoints.kt
diff --git a/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/ComposeReport.kt b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/ComposeReport.kt
similarity index 100%
rename from compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/ComposeReport.kt
rename to compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/ComposeReport.kt
diff --git a/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/Contact.kt b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/Contact.kt
similarity index 100%
rename from compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/Contact.kt
rename to compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/Contact.kt
diff --git a/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/ContactModel.kt b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/ContactModel.kt
similarity index 100%
rename from compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/ContactModel.kt
rename to compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/ContactModel.kt
diff --git a/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/MockViewValidator.kt b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/MockViewValidator.kt
new file mode 100644
index 0000000..ccac015
--- /dev/null
+++ b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/MockViewValidator.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2019 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.mock
+
+import kotlin.test.assertEquals
+
+interface MockViewValidator {
+    val view: View
+    fun next(): Boolean
+}
+
+class MockViewListValidator(private val views: List<View>) :
+    MockViewValidator {
+    override lateinit var view: View
+
+    override fun next(): Boolean {
+        if (iterator.hasNext()) {
+            view = iterator.next()
+            return true
+        }
+        return false
+    }
+
+    private val iterator by lazy { views.iterator() }
+
+    fun validate(block: (MockViewValidator.() -> Unit)?) {
+        if (block != null) {
+            this.block()
+            val hasNext = next()
+            assertEquals(false, hasNext, "Expected children but none found")
+        } else {
+            assertEquals(0, views.size, "Not expecting children but some found")
+        }
+    }
+}
+
+fun MockViewValidator.view(name: String, block: (MockViewValidator.() -> Unit)? = null) {
+    val hasNext = next()
+    assertEquals(true, hasNext)
+    assertEquals(name, view.name)
+    MockViewListValidator(view.children).validate(block)
+}
+
+fun <T> MockViewValidator.repeat(of: Iterable<T>, block: MockViewValidator.(value: T) -> Unit) {
+    for (value in of) {
+        block(value)
+    }
+}
+
+fun MockViewValidator.linear() = view("linear", null)
+fun MockViewValidator.linear(block: MockViewValidator.() -> Unit) = view("linear", block)
+fun MockViewValidator.box(block: MockViewValidator.() -> Unit) = view("box", block)
+fun MockViewValidator.text(value: String) {
+    view("text")
+    assertEquals(value, view.attributes["text"])
+}
+fun MockViewValidator.edit(value: String) {
+    view("edit")
+    assertEquals(value, view.attributes["value"])
+}
+
+fun MockViewValidator.selectBox(selected: Boolean, block: MockViewValidator.() -> Unit) {
+    if (selected) {
+        box {
+            block()
+        }
+    } else {
+        block()
+    }
+}
+
+fun MockViewValidator.skip(times: Int = 1) {
+    repeat(times) {
+        val hasNext = next()
+        assertEquals(true, hasNext)
+    }
+}
+
+fun validate(root: View, block: MockViewValidator.() -> Unit) {
+    MockViewListValidator(root.children).validate(block)
+}
diff --git a/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/Point.kt b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/Point.kt
similarity index 100%
rename from compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/Point.kt
rename to compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/Point.kt
diff --git a/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/Report.kt b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/Report.kt
similarity index 100%
rename from compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/Report.kt
rename to compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/Report.kt
diff --git a/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/View.kt b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/View.kt
similarity index 100%
rename from compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/View.kt
rename to compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/View.kt
diff --git a/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/ViewComposer.kt b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/ViewComposer.kt
new file mode 100644
index 0000000..d3afbde
--- /dev/null
+++ b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/ViewComposer.kt
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2019 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.mock
+
+import androidx.compose.Applier
+import androidx.compose.ApplyAdapter
+import androidx.compose.Composer
+import androidx.compose.Recomposer
+import androidx.compose.SlotTable
+import androidx.compose.cache
+import androidx.compose.remember
+
+interface MockViewComposition {
+    val cc: Composer<View>
+}
+
+abstract class ViewComponent : MockViewComposition {
+    private var recomposer: ((sync: Boolean) -> Unit)? = null
+    private lateinit var composer: Composer<View>
+    @PublishedApi
+    internal fun setComposer(value: Composer<View>) {
+        composer = value
+    }
+
+    override val cc: Composer<View> get() = composer
+
+    fun recompose() {
+        recomposer?.let { it(false) }
+    }
+
+    operator fun invoke() {
+        val cc = cc as MockViewComposer
+        val callback = cc.startJoin(false) { compose() }
+        compose()
+        cc.doneJoin(false)
+        recomposer = callback
+    }
+
+    abstract fun compose()
+}
+
+typealias Compose = MockViewComposition.() -> Unit
+
+@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
+object ViewApplierAdapter :
+    ApplyAdapter<View> {
+    override fun View.start(instance: View) {}
+    override fun View.insertAt(index: Int, instance: View) = addAt(index, instance)
+    override fun View.removeAt(index: Int, count: Int) = removeAt(index, count)
+    override fun View.move(from: Int, to: Int, count: Int) = moveAt(from, to, count)
+    override fun View.end(instance: View, parent: View) {}
+}
+
+class MockViewComposer(
+    val root: View
+) : Composer<View>(
+    SlotTable(),
+    Applier(root, ViewApplierAdapter), object : Recomposer() {
+        override fun scheduleChangesDispatch() {
+        }
+
+        override fun hasPendingChanges(): Boolean = false
+    }) {
+    private val rootComposer: MockViewComposition by lazy {
+        object : MockViewComposition {
+            override val cc: Composer<View> get() = this@MockViewComposer
+        }
+    }
+
+    fun compose(composition: MockViewComposition.() -> Unit) {
+        composeRoot {
+            rootComposer.composition()
+        }
+    }
+}
+
+/* inline */ fun <N, /* reified */ V> Composer<N>.applyNeeded(value: V): Boolean =
+    changed(value) && !inserting
+
+@Suppress("NOTHING_TO_INLINE")
+inline fun <V> MockViewComposition.remember(
+    /*crossinline*/
+    noinline block: () -> V
+): V = cc.remember(block)
+
+inline fun <V, reified P1> MockViewComposition.remember(
+    p1: P1,
+    /*crossinline*/
+    noinline block: () -> V
+) = cc.remember(p1, block)
+
+inline fun <V, reified P1, reified P2> MockViewComposition.remember(
+    p1: P1,
+    p2: P2,
+    /*crossinline*/
+    noinline block: () -> V
+) = cc.remember(p1, p2, block)
+
+inline fun <V, reified P1, reified P2, reified P3> MockViewComposition.remember(
+    p1: P1,
+    p2: P2,
+    p3: P3,
+    /*crossinline*/
+    noinline block: () -> V
+) = cc.remember(p1, p2, p3, block)
+
+inline fun <V, reified P1, reified P2, reified P3, reified P4> MockViewComposition.remember(
+    p1: P1,
+    p2: P2,
+    p3: P3,
+    p4: P4,
+    /*crossinline*/
+    noinline block: () -> V
+) = cc.remember(p1, p2, p3, p4, block)
+
+@Suppress("NOTHING_TO_INLINE")
+inline fun <V> MockViewComposition.remember(
+    vararg args: Any,
+    /*crossinline*/
+    noinline block: () -> V
+): V = cc.remember(*args, block = block)
+
+inline fun <reified P1> MockViewComposition.memoize(
+    key: Any,
+    p1: P1,
+    block: MockViewComposition.(p1: P1) -> Unit
+) {
+    cc.startGroup(key)
+    if (!cc.changed(p1)) {
+        cc.nextSlot()
+        cc.skipValue()
+        cc.skipGroup()
+    } else {
+        cc.startGroup(key)
+        block(p1)
+        cc.endGroup()
+    }
+    cc.endGroup()
+}
+
+inline fun <V : View> MockViewComposition.emit(
+    key: Any,
+    noinline factory: () -> V,
+    block: MockViewComposition.() -> Unit
+) {
+    cc.startNode(key)
+    cc.emitNode(factory)
+    block()
+    cc.endNode()
+}
+
+inline fun <V : View, reified A1> MockViewComposition.emit(
+    key: Any,
+    noinline factory: () -> V,
+    a1: A1,
+    noinline set1: V.(A1) -> Unit
+) {
+    cc.startNode(key)
+    cc.emitNode(factory)
+    if (cc.changed(a1)) {
+        cc.apply(a1, set1)
+    }
+    cc.endNode()
+}
+
+val invocation = Any()
+
+inline fun MockViewComposition.call(
+    key: Any,
+    invalid: Composer<View>.() -> Boolean,
+    block: () -> Unit
+) = with(cc) {
+    startGroup(key)
+    if (invalid() || inserting) {
+        startGroup(invocation)
+        block()
+        endGroup()
+    } else {
+        (cc as Composer<*>).skipGroup(invocation)
+    }
+    endGroup()
+}
+
+inline fun <T : ViewComponent> MockViewComposition.call(
+    key: Any,
+    ctor: () -> T,
+    invalid: ComponentUpdater<T>.() -> Unit,
+    block: (f: T) -> Unit
+) = with(cc) {
+    startGroup(key)
+    val f = cache(true, ctor).apply { setComposer(this@with) }
+    val updater = object : ComponentUpdater<T> {
+        override val cc: Composer<View> = this@with
+        override var changed: Boolean = false
+        override val component = f
+    }
+    updater.invalid()
+    if (updater.changed || inserting) {
+        startGroup(invocation)
+        block(f)
+        endGroup()
+    } else {
+        nextSlot()
+        skipValue()
+        skipGroup()
+    }
+    endGroup()
+}
+
+fun MockViewComposition.join(
+    key: Any,
+    block: (invalidate: (sync: Boolean) -> Unit) -> Unit
+) {
+    val myCC = cc as MockViewComposer
+    myCC.startGroup(key)
+    val invalidate = myCC.startJoin(false, block)
+    block(invalidate)
+    myCC.doneJoin(false)
+    myCC.endGroup()
+}
+
+interface ComponentUpdater<C> : MockViewComposition {
+    val component: C
+    var changed: Boolean
+}
+
+inline fun <C, reified V> ComponentUpdater<C>.set(value: V, noinline block: C.(V) -> Unit) {
+    if (cc.changed(value)) {
+        cc.apply<V, C>(value) { component.block(it) }
+        component.block(value)
+        changed = true
+    }
+}
+
+inline fun <C, reified V> ComponentUpdater<C>.update(value: V, noinline block: C.(V) -> Unit) {
+    if (cc.applyNeeded(value)) {
+        cc.apply<V, C>(value) { component.block(it) }
+        component.block(value)
+        changed = true
+    }
+}
diff --git a/compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/Views.kt b/compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/Views.kt
similarity index 100%
rename from compose/compose-runtime/integration-tests/src/main/java/androidx/compose/mock/Views.kt
rename to compose/compose-runtime/src/commonTest/kotlin/androidx/compose/mock/Views.kt
diff --git a/content/api/api_lint.ignore b/content/api/api_lint.ignore
index 4bd59a5b..86b268d 100644
--- a/content/api/api_lint.ignore
+++ b/content/api/api_lint.ignore
@@ -7,3 +7,13 @@
     Inconsistent extra value; expected `androidx.contentpager.content.extra.SUGGESTED_LIMIT`, was `android-support:extra-suggested-limit`
 ActionValue: androidx.contentpager.content.ContentPager#EXTRA_TOTAL_COUNT:
     Inconsistent extra value; expected `androidx.contentpager.content.extra.TOTAL_COUNT`, was `android.content.extra.TOTAL_COUNT`
+
+
+MissingNullability: androidx.contentpager.content.ContentPager#ContentPager(android.content.ContentResolver, androidx.contentpager.content.ContentPager.QueryRunner) parameter #0:
+    Missing nullability on parameter `resolver` in method `ContentPager`
+MissingNullability: androidx.contentpager.content.ContentPager#ContentPager(android.content.ContentResolver, androidx.contentpager.content.ContentPager.QueryRunner) parameter #1:
+    Missing nullability on parameter `queryRunner` in method `ContentPager`
+MissingNullability: androidx.contentpager.content.Query#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.contentpager.content.Query#toString():
+    Missing nullability on method `toString` return
diff --git a/coordinatorlayout/api/api_lint.ignore b/coordinatorlayout/api/api_lint.ignore
index 129ea6f..6b6b053 100644
--- a/coordinatorlayout/api/api_lint.ignore
+++ b/coordinatorlayout/api/api_lint.ignore
@@ -1,4 +1,100 @@
 // Baseline format: 1.0
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#checkLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `checkLayoutParams`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#drawChild(android.graphics.Canvas, android.view.View, long) parameter #0:
+    Missing nullability on parameter `canvas` in method `drawChild`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#drawChild(android.graphics.Canvas, android.view.View, long) parameter #1:
+    Missing nullability on parameter `child` in method `drawChild`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#generateLayoutParams(android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#generateLayoutParams(android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#generateLayoutParams(android.view.ViewGroup.LayoutParams):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `generateLayoutParams`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `c` in method `onDraw`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onInterceptTouchEvent`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onMeasureChild(android.view.View, int, int, int, int) parameter #0:
+    Missing nullability on parameter `child` in method `onMeasureChild`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onNestedFling(android.view.View, float, float, boolean) parameter #0:
+    Missing nullability on parameter `target` in method `onNestedFling`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onNestedPreFling(android.view.View, float, float) parameter #0:
+    Missing nullability on parameter `target` in method `onNestedPreFling`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onNestedPreScroll(android.view.View, int, int, int[]) parameter #0:
+    Missing nullability on parameter `target` in method `onNestedPreScroll`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onNestedPreScroll(android.view.View, int, int, int[]) parameter #3:
+    Missing nullability on parameter `consumed` in method `onNestedPreScroll`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onNestedPreScroll(android.view.View, int, int, int[], int) parameter #0:
+    Missing nullability on parameter `target` in method `onNestedPreScroll`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onNestedPreScroll(android.view.View, int, int, int[], int) parameter #3:
+    Missing nullability on parameter `consumed` in method `onNestedPreScroll`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onNestedScroll(android.view.View, int, int, int, int) parameter #0:
+    Missing nullability on parameter `target` in method `onNestedScroll`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onNestedScroll(android.view.View, int, int, int, int, int) parameter #0:
+    Missing nullability on parameter `target` in method `onNestedScroll`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onNestedScrollAccepted(android.view.View, android.view.View, int) parameter #0:
+    Missing nullability on parameter `child` in method `onNestedScrollAccepted`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onNestedScrollAccepted(android.view.View, android.view.View, int) parameter #1:
+    Missing nullability on parameter `target` in method `onNestedScrollAccepted`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onNestedScrollAccepted(android.view.View, android.view.View, int, int) parameter #0:
+    Missing nullability on parameter `child` in method `onNestedScrollAccepted`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onNestedScrollAccepted(android.view.View, android.view.View, int, int) parameter #1:
+    Missing nullability on parameter `target` in method `onNestedScrollAccepted`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onStartNestedScroll(android.view.View, android.view.View, int) parameter #0:
+    Missing nullability on parameter `child` in method `onStartNestedScroll`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onStartNestedScroll(android.view.View, android.view.View, int) parameter #1:
+    Missing nullability on parameter `target` in method `onStartNestedScroll`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onStartNestedScroll(android.view.View, android.view.View, int, int) parameter #0:
+    Missing nullability on parameter `child` in method `onStartNestedScroll`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onStartNestedScroll(android.view.View, android.view.View, int, int) parameter #1:
+    Missing nullability on parameter `target` in method `onStartNestedScroll`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onStopNestedScroll(android.view.View) parameter #0:
+    Missing nullability on parameter `target` in method `onStopNestedScroll`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onStopNestedScroll(android.view.View, int) parameter #0:
+    Missing nullability on parameter `target` in method `onStopNestedScroll`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onTouchEvent`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#requestChildRectangleOnScreen(android.view.View, android.graphics.Rect, boolean) parameter #0:
+    Missing nullability on parameter `child` in method `requestChildRectangleOnScreen`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#requestChildRectangleOnScreen(android.view.View, android.graphics.Rect, boolean) parameter #1:
+    Missing nullability on parameter `rectangle` in method `requestChildRectangleOnScreen`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#setOnHierarchyChangeListener(android.view.ViewGroup.OnHierarchyChangeListener) parameter #0:
+    Missing nullability on parameter `onHierarchyChangeListener` in method `setOnHierarchyChangeListener`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#verifyDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `who` in method `verifyDrawable`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout.Behavior#Behavior(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `Behavior`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout.Behavior#Behavior(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `Behavior`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout.DefaultBehavior#value():
+    Missing nullability on method `value` return
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout.LayoutParams#LayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `LayoutParams`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout.LayoutParams#LayoutParams(android.view.ViewGroup.MarginLayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `LayoutParams`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout.LayoutParams#LayoutParams(androidx.coordinatorlayout.widget.CoordinatorLayout.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `LayoutParams`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout.SavedState#CREATOR:
+    Missing nullability on field `CREATOR` in class `class androidx.coordinatorlayout.widget.CoordinatorLayout.SavedState`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout.SavedState#SavedState(android.os.Parcel, ClassLoader) parameter #0:
+    Missing nullability on parameter `source` in method `SavedState`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout.SavedState#SavedState(android.os.Parcel, ClassLoader) parameter #1:
+    Missing nullability on parameter `loader` in method `SavedState`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout.SavedState#SavedState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `superState` in method `SavedState`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout.SavedState#writeToParcel(android.os.Parcel, int) parameter #0:
+    Missing nullability on parameter `dest` in method `writeToParcel`
+
+
 ParcelCreator: androidx.coordinatorlayout.widget.CoordinatorLayout.SavedState:
     Parcelable requires `public int describeContents()`; missing in androidx.coordinatorlayout.widget.CoordinatorLayout.SavedState
 
diff --git a/core/core-ktx/api/1.2.0-alpha04.txt b/core/core-ktx/api/1.2.0-alpha04.txt
new file mode 100644
index 0000000..38408b4
--- /dev/null
+++ b/core/core-ktx/api/1.2.0-alpha04.txt
@@ -0,0 +1,652 @@
+// Signature format: 3.0
+package androidx.core.animation {
+
+  public final class AnimatorKt {
+    ctor public AnimatorKt();
+    method public static inline android.animation.Animator.AnimatorListener addListener(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onEnd = {}, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onStart = {}, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onCancel = {}, 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, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onResume = {}, 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 {
+    ctor public ContentValuesKt();
+    method public static android.content.ContentValues contentValuesOf(kotlin.Pair<java.lang.String,?>... pairs);
+  }
+
+  public final class ContextKt {
+    ctor public ContextKt();
+    method public static inline <reified T> T! getSystemService(android.content.Context);
+    method public static inline void withStyledAttributes(android.content.Context, android.util.AttributeSet? set = null, int[] attrs, @AttrRes int defStyleAttr = 0, @StyleRes int defStyleRes = 0, 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 {
+    ctor public SharedPreferencesKt();
+    method public static inline void edit(android.content.SharedPreferences, boolean commit = false, kotlin.jvm.functions.Function1<? super android.content.SharedPreferences.Editor,kotlin.Unit> action);
+  }
+
+}
+
+package androidx.core.content.res {
+
+  public final class TypedArrayKt {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public SQLiteDatabaseKt();
+    method public static inline <T> T! transaction(android.database.sqlite.SQLiteDatabase, boolean exclusive = true, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
+  }
+
+}
+
+package androidx.core.graphics {
+
+  public final class BitmapKt {
+    ctor public 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, android.graphics.Bitmap.Config config = android.graphics.Bitmap.Config.ARGB_8888);
+    method @RequiresApi(26) public static inline android.graphics.Bitmap createBitmap(int width, int height, android.graphics.Bitmap.Config config = android.graphics.Bitmap.Config.ARGB_8888, boolean hasAlpha = true, android.graphics.ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.SRGB));
+    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, boolean filter = true);
+    method public static inline operator void set(android.graphics.Bitmap, int x, int y, @ColorInt int color);
+  }
+
+  public final class CanvasKt {
+    ctor public 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, android.graphics.Matrix matrix = android.graphics.Matrix(), kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withRotation(android.graphics.Canvas, float degrees = 0.0f, float pivotX = 0.0f, float pivotY = 0.0f, 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, float x = 1.0f, float y = 1.0f, float pivotX = 0.0f, float pivotY = 0.0f, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withSkew(android.graphics.Canvas, float x = 0.0f, float y = 0.0f, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withTranslation(android.graphics.Canvas, float x = 0.0f, float y = 0.0f, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+  }
+
+  public final class ColorKt {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public MatrixKt();
+    method public static android.graphics.Matrix rotationMatrix(float degrees, float px = 0.0f, float py = 0.0f);
+    method public static android.graphics.Matrix scaleMatrix(float sx = 1.0f, float sy = 1.0f);
+    method public static inline operator android.graphics.Matrix times(android.graphics.Matrix, android.graphics.Matrix m);
+    method public static android.graphics.Matrix translationMatrix(float tx = 0.0f, float ty = 0.0f);
+    method public static inline float[] values(android.graphics.Matrix);
+  }
+
+  public final class PaintKt {
+    ctor public PaintKt();
+    method public static inline boolean setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat? blendModeCompat);
+  }
+
+  public final class PathKt {
+    ctor public 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, float error = 0.5f);
+    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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public BitmapDrawableKt();
+    method public static inline android.graphics.drawable.BitmapDrawable toDrawable(android.graphics.Bitmap, android.content.res.Resources resources);
+  }
+
+  public final class ColorDrawableKt {
+    ctor public 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 {
+    ctor public DrawableKt();
+    method public static android.graphics.Bitmap toBitmap(android.graphics.drawable.Drawable, @Px int width = intrinsicWidth, @Px int height = intrinsicHeight, android.graphics.Bitmap.Config? config = null);
+    method public static void updateBounds(android.graphics.drawable.Drawable, @Px int left = android.graphics.Rect.left, @Px int top = android.graphics.Rect.top, @Px int right = android.graphics.Rect.right, @Px int bottom = android.graphics.Rect.bottom);
+  }
+
+  public final class IconKt {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public BundleKt();
+    method public static android.os.Bundle bundleOf(kotlin.Pair<java.lang.String,?>... pairs);
+  }
+
+  public final class HandlerKt {
+    ctor public HandlerKt();
+    method public static inline Runnable postAtTime(android.os.Handler, long uptimeMillis, Object? token = null, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+    method public static inline Runnable postDelayed(android.os.Handler, long delayInMillis, Object? token = null, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+  }
+
+  public final class PersistableBundleKt {
+    ctor public PersistableBundleKt();
+    method @RequiresApi(21) public static android.os.PersistableBundle persistableBundleOf(kotlin.Pair<java.lang.String,?>... pairs);
+  }
+
+  public final class TraceKt {
+    ctor public TraceKt();
+    method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
+}
+
+package androidx.core.text {
+
+  public final class CharSequenceKt {
+    ctor public CharSequenceKt();
+    method public static inline boolean isDigitsOnly(CharSequence);
+    method public static inline int trimmedLength(CharSequence);
+  }
+
+  public final class HtmlKt {
+    ctor public HtmlKt();
+    method public static inline android.text.Spanned parseAsHtml(String, int flags = 0, android.text.Html.ImageGetter? imageGetter = null, android.text.Html.TagHandler? tagHandler = null);
+    method public static inline String toHtml(android.text.Spanned, int option = 0);
+  }
+
+  public final class LocaleKt {
+    ctor public LocaleKt();
+    method @RequiresApi(17) public static inline int getLayoutDirection(java.util.Locale);
+  }
+
+  public final class SpannableStringBuilderKt {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public SpannedStringKt();
+    method public static inline <reified T> T![] getSpans(android.text.Spanned, int start = 0, int end = length);
+    method public static inline android.text.Spanned toSpanned(CharSequence);
+  }
+
+  public final class StringKt {
+    ctor public StringKt();
+    method public static inline String htmlEncode(String);
+  }
+
+}
+
+package androidx.core.transition {
+
+  public final class TransitionKt {
+    ctor public TransitionKt();
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener addListener(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onEnd = {}, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onStart = {}, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onCancel = {}, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onResume = {}, 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 AtomicFileKt {
+    ctor public AtomicFileKt();
+    method @RequiresApi(17) public static inline byte[] readBytes(android.util.AtomicFile);
+    method @RequiresApi(17) public static String readText(android.util.AtomicFile, java.nio.charset.Charset charset = Charsets.UTF_8);
+    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, java.nio.charset.Charset charset = Charsets.UTF_8);
+  }
+
+  public final class HalfKt {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public LruCacheKt();
+    method public static inline <K, V> android.util.LruCache<K,V> lruCache(int maxSize, kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Integer> sizeOf = { _, _ -> 1 }, kotlin.jvm.functions.Function1<? super K,? extends V> create = { (java.lang.Object)null }, kotlin.jvm.functions.Function4<? super java.lang.Boolean,? super K,? super V,? super V,kotlin.Unit> onEntryRemoved = { _, _, _, _ ->  });
+  }
+
+  public final class PairKt {
+    ctor public PairKt();
+    method public static inline operator <F, S> F! component1(android.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> kotlin.Pair<F,S> toKotlinPair(android.util.Pair<F,S>);
+  }
+
+  public final class RangeKt {
+    ctor public 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 SizeKt {
+    ctor public 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 @RequiresApi(21) public static inline operator int component2(android.util.Size);
+    method @RequiresApi(21) public static inline operator float component2(android.util.SizeF);
+  }
+
+  public final class SparseArrayKt {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 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, @Px int left = android.view.ViewGroup.MarginLayoutParams.leftMargin, @Px int top = android.view.ViewGroup.MarginLayoutParams.topMargin, @Px int right = android.view.ViewGroup.MarginLayoutParams.rightMargin, @Px int bottom = android.view.ViewGroup.MarginLayoutParams.bottomMargin);
+    method @RequiresApi(17) public static inline void updateMarginsRelative(android.view.ViewGroup.MarginLayoutParams, @Px int start = marginStart, @Px int top = android.view.ViewGroup.MarginLayoutParams.topMargin, @Px int end = marginEnd, @Px int bottom = android.view.ViewGroup.MarginLayoutParams.bottomMargin);
+  }
+
+  public final class ViewKt {
+    ctor public 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, android.graphics.Bitmap.Config config = android.graphics.Bitmap.Config.ARGB_8888);
+    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 value);
+    method public static inline void setInvisible(android.view.View, boolean value);
+    method public static inline void setPadding(android.view.View, @Px int size);
+    method public static inline void setVisible(android.view.View, boolean value);
+    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 updateLayoutParamsTyped(android.view.View, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
+    method public static inline void updatePadding(android.view.View, @Px int left = paddingLeft, @Px int top = paddingTop, @Px int right = paddingRight, @Px int bottom = paddingBottom);
+    method @RequiresApi(17) public static inline void updatePaddingRelative(android.view.View, @Px int start = paddingStart, @Px int top = paddingTop, @Px int end = paddingEnd, @Px int bottom = paddingBottom);
+  }
+
+}
+
+package androidx.core.widget {
+
+  public final class TextViewKt {
+    ctor public TextViewKt();
+    method public static inline android.text.TextWatcher addTextChangedListener(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> beforeTextChanged = { _, _, _, _ ->  }, kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> onTextChanged = { _, _, _, _ ->  }, 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/api_lint.ignore b/core/core-ktx/api/api_lint.ignore
index 642bfa7..f3b7fc84 100644
--- a/core/core-ktx/api/api_lint.ignore
+++ b/core/core-ktx/api/api_lint.ignore
@@ -23,6 +23,12 @@
     Method ViewGroupKt.iterator appears to be throwing java.lang.IndexOutOfBoundsException; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
 
 
+MissingNullability: androidx.core.graphics.ColorKt#convertTo(android.graphics.Color, android.graphics.ColorSpace):
+    Missing nullability on method `convertTo` return
+MissingNullability: androidx.core.graphics.ColorKt#convertTo(android.graphics.Color, android.graphics.ColorSpace.Named):
+    Missing nullability on method `convertTo` return
+
+
 PairedRegistration: androidx.core.animation.AnimatorKt#addListener(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit>, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit>, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit>, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit>):
     Found addListener but not removeListener in androidx.core.animation.AnimatorKt
 PairedRegistration: androidx.core.animation.AnimatorKt#addPauseListener(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit>, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit>):
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/core/core-ktx/api/res-1.2.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to core/core-ktx/api/res-1.2.0-alpha04.txt
diff --git a/core/core-ktx/api/restricted_1.2.0-alpha04.txt b/core/core-ktx/api/restricted_1.2.0-alpha04.txt
new file mode 100644
index 0000000..38408b4
--- /dev/null
+++ b/core/core-ktx/api/restricted_1.2.0-alpha04.txt
@@ -0,0 +1,652 @@
+// Signature format: 3.0
+package androidx.core.animation {
+
+  public final class AnimatorKt {
+    ctor public AnimatorKt();
+    method public static inline android.animation.Animator.AnimatorListener addListener(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onEnd = {}, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onStart = {}, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onCancel = {}, 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, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onResume = {}, 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 {
+    ctor public ContentValuesKt();
+    method public static android.content.ContentValues contentValuesOf(kotlin.Pair<java.lang.String,?>... pairs);
+  }
+
+  public final class ContextKt {
+    ctor public ContextKt();
+    method public static inline <reified T> T! getSystemService(android.content.Context);
+    method public static inline void withStyledAttributes(android.content.Context, android.util.AttributeSet? set = null, int[] attrs, @AttrRes int defStyleAttr = 0, @StyleRes int defStyleRes = 0, 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 {
+    ctor public SharedPreferencesKt();
+    method public static inline void edit(android.content.SharedPreferences, boolean commit = false, kotlin.jvm.functions.Function1<? super android.content.SharedPreferences.Editor,kotlin.Unit> action);
+  }
+
+}
+
+package androidx.core.content.res {
+
+  public final class TypedArrayKt {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public SQLiteDatabaseKt();
+    method public static inline <T> T! transaction(android.database.sqlite.SQLiteDatabase, boolean exclusive = true, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
+  }
+
+}
+
+package androidx.core.graphics {
+
+  public final class BitmapKt {
+    ctor public 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, android.graphics.Bitmap.Config config = android.graphics.Bitmap.Config.ARGB_8888);
+    method @RequiresApi(26) public static inline android.graphics.Bitmap createBitmap(int width, int height, android.graphics.Bitmap.Config config = android.graphics.Bitmap.Config.ARGB_8888, boolean hasAlpha = true, android.graphics.ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.SRGB));
+    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, boolean filter = true);
+    method public static inline operator void set(android.graphics.Bitmap, int x, int y, @ColorInt int color);
+  }
+
+  public final class CanvasKt {
+    ctor public 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, android.graphics.Matrix matrix = android.graphics.Matrix(), kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withRotation(android.graphics.Canvas, float degrees = 0.0f, float pivotX = 0.0f, float pivotY = 0.0f, 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, float x = 1.0f, float y = 1.0f, float pivotX = 0.0f, float pivotY = 0.0f, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withSkew(android.graphics.Canvas, float x = 0.0f, float y = 0.0f, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withTranslation(android.graphics.Canvas, float x = 0.0f, float y = 0.0f, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+  }
+
+  public final class ColorKt {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public MatrixKt();
+    method public static android.graphics.Matrix rotationMatrix(float degrees, float px = 0.0f, float py = 0.0f);
+    method public static android.graphics.Matrix scaleMatrix(float sx = 1.0f, float sy = 1.0f);
+    method public static inline operator android.graphics.Matrix times(android.graphics.Matrix, android.graphics.Matrix m);
+    method public static android.graphics.Matrix translationMatrix(float tx = 0.0f, float ty = 0.0f);
+    method public static inline float[] values(android.graphics.Matrix);
+  }
+
+  public final class PaintKt {
+    ctor public PaintKt();
+    method public static inline boolean setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat? blendModeCompat);
+  }
+
+  public final class PathKt {
+    ctor public 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, float error = 0.5f);
+    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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public BitmapDrawableKt();
+    method public static inline android.graphics.drawable.BitmapDrawable toDrawable(android.graphics.Bitmap, android.content.res.Resources resources);
+  }
+
+  public final class ColorDrawableKt {
+    ctor public 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 {
+    ctor public DrawableKt();
+    method public static android.graphics.Bitmap toBitmap(android.graphics.drawable.Drawable, @Px int width = intrinsicWidth, @Px int height = intrinsicHeight, android.graphics.Bitmap.Config? config = null);
+    method public static void updateBounds(android.graphics.drawable.Drawable, @Px int left = android.graphics.Rect.left, @Px int top = android.graphics.Rect.top, @Px int right = android.graphics.Rect.right, @Px int bottom = android.graphics.Rect.bottom);
+  }
+
+  public final class IconKt {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public BundleKt();
+    method public static android.os.Bundle bundleOf(kotlin.Pair<java.lang.String,?>... pairs);
+  }
+
+  public final class HandlerKt {
+    ctor public HandlerKt();
+    method public static inline Runnable postAtTime(android.os.Handler, long uptimeMillis, Object? token = null, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+    method public static inline Runnable postDelayed(android.os.Handler, long delayInMillis, Object? token = null, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+  }
+
+  public final class PersistableBundleKt {
+    ctor public PersistableBundleKt();
+    method @RequiresApi(21) public static android.os.PersistableBundle persistableBundleOf(kotlin.Pair<java.lang.String,?>... pairs);
+  }
+
+  public final class TraceKt {
+    ctor public TraceKt();
+    method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
+}
+
+package androidx.core.text {
+
+  public final class CharSequenceKt {
+    ctor public CharSequenceKt();
+    method public static inline boolean isDigitsOnly(CharSequence);
+    method public static inline int trimmedLength(CharSequence);
+  }
+
+  public final class HtmlKt {
+    ctor public HtmlKt();
+    method public static inline android.text.Spanned parseAsHtml(String, int flags = 0, android.text.Html.ImageGetter? imageGetter = null, android.text.Html.TagHandler? tagHandler = null);
+    method public static inline String toHtml(android.text.Spanned, int option = 0);
+  }
+
+  public final class LocaleKt {
+    ctor public LocaleKt();
+    method @RequiresApi(17) public static inline int getLayoutDirection(java.util.Locale);
+  }
+
+  public final class SpannableStringBuilderKt {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public SpannedStringKt();
+    method public static inline <reified T> T![] getSpans(android.text.Spanned, int start = 0, int end = length);
+    method public static inline android.text.Spanned toSpanned(CharSequence);
+  }
+
+  public final class StringKt {
+    ctor public StringKt();
+    method public static inline String htmlEncode(String);
+  }
+
+}
+
+package androidx.core.transition {
+
+  public final class TransitionKt {
+    ctor public TransitionKt();
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener addListener(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onEnd = {}, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onStart = {}, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onCancel = {}, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onResume = {}, 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 AtomicFileKt {
+    ctor public AtomicFileKt();
+    method @RequiresApi(17) public static inline byte[] readBytes(android.util.AtomicFile);
+    method @RequiresApi(17) public static String readText(android.util.AtomicFile, java.nio.charset.Charset charset = Charsets.UTF_8);
+    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, java.nio.charset.Charset charset = Charsets.UTF_8);
+  }
+
+  public final class HalfKt {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public LruCacheKt();
+    method public static inline <K, V> android.util.LruCache<K,V> lruCache(int maxSize, kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Integer> sizeOf = { _, _ -> 1 }, kotlin.jvm.functions.Function1<? super K,? extends V> create = { (java.lang.Object)null }, kotlin.jvm.functions.Function4<? super java.lang.Boolean,? super K,? super V,? super V,kotlin.Unit> onEntryRemoved = { _, _, _, _ ->  });
+  }
+
+  public final class PairKt {
+    ctor public PairKt();
+    method public static inline operator <F, S> F! component1(android.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> kotlin.Pair<F,S> toKotlinPair(android.util.Pair<F,S>);
+  }
+
+  public final class RangeKt {
+    ctor public 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 SizeKt {
+    ctor public 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 @RequiresApi(21) public static inline operator int component2(android.util.Size);
+    method @RequiresApi(21) public static inline operator float component2(android.util.SizeF);
+  }
+
+  public final class SparseArrayKt {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 {
+    ctor public 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 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, @Px int left = android.view.ViewGroup.MarginLayoutParams.leftMargin, @Px int top = android.view.ViewGroup.MarginLayoutParams.topMargin, @Px int right = android.view.ViewGroup.MarginLayoutParams.rightMargin, @Px int bottom = android.view.ViewGroup.MarginLayoutParams.bottomMargin);
+    method @RequiresApi(17) public static inline void updateMarginsRelative(android.view.ViewGroup.MarginLayoutParams, @Px int start = marginStart, @Px int top = android.view.ViewGroup.MarginLayoutParams.topMargin, @Px int end = marginEnd, @Px int bottom = android.view.ViewGroup.MarginLayoutParams.bottomMargin);
+  }
+
+  public final class ViewKt {
+    ctor public 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, android.graphics.Bitmap.Config config = android.graphics.Bitmap.Config.ARGB_8888);
+    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 value);
+    method public static inline void setInvisible(android.view.View, boolean value);
+    method public static inline void setPadding(android.view.View, @Px int size);
+    method public static inline void setVisible(android.view.View, boolean value);
+    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 updateLayoutParamsTyped(android.view.View, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
+    method public static inline void updatePadding(android.view.View, @Px int left = paddingLeft, @Px int top = paddingTop, @Px int right = paddingRight, @Px int bottom = paddingBottom);
+    method @RequiresApi(17) public static inline void updatePaddingRelative(android.view.View, @Px int start = paddingStart, @Px int top = paddingTop, @Px int end = paddingEnd, @Px int bottom = paddingBottom);
+  }
+
+}
+
+package androidx.core.widget {
+
+  public final class TextViewKt {
+    ctor public TextViewKt();
+    method public static inline android.text.TextWatcher addTextChangedListener(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> beforeTextChanged = { _, _, _, _ ->  }, kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> onTextChanged = { _, _, _, _ ->  }, 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/src/androidTest/java/androidx/core/net/UriTest.kt b/core/core-ktx/src/androidTest/java/androidx/core/net/UriTest.kt
index cff386e..600318f 100644
--- a/core/core-ktx/src/androidTest/java/androidx/core/net/UriTest.kt
+++ b/core/core-ktx/src/androidTest/java/androidx/core/net/UriTest.kt
@@ -46,4 +46,15 @@
             uri.toFile()
         }.hasMessageThat().isEqualTo("Uri lacks 'file' scheme: $uri")
     }
+
+    @Test fun fileFromUriWithNullPath() {
+        val uri = Uri.Builder()
+            .scheme("file")
+            .authority("example.com")
+            .path(null)
+            .build()
+        assertThrows<IllegalArgumentException> {
+            uri.toFile()
+        }.hasMessageThat().isEqualTo("Uri path is null: $uri")
+    }
 }
diff --git a/core/core-ktx/src/main/java/androidx/core/net/Uri.kt b/core/core-ktx/src/main/java/androidx/core/net/Uri.kt
index f1f9b1d..2aa1667 100644
--- a/core/core-ktx/src/main/java/androidx/core/net/Uri.kt
+++ b/core/core-ktx/src/main/java/androidx/core/net/Uri.kt
@@ -38,5 +38,5 @@
 /** Creates a [File] from the given [Uri]. */
 fun Uri.toFile(): File {
     require(scheme == "file") { "Uri lacks 'file' scheme: $this" }
-    return File(path!!)
+    return File(requireNotNull(path) { "Uri path is null: $this" })
 }
diff --git a/core/core/api/1.2.0-alpha03.txt b/core/core/api/1.2.0-alpha03.txt
index fe4b834..d39053e 100644
--- a/core/core/api/1.2.0-alpha03.txt
+++ b/core/core/api/1.2.0-alpha03.txt
@@ -1610,7 +1610,7 @@
   }
 
   public interface Predicate<T> {
-    method public boolean test(T?);
+    method public boolean test(T!);
   }
 
   public interface Supplier<T> {
diff --git a/core/core/api/1.2.0-alpha04.ignore b/core/core/api/1.2.0-alpha04.ignore
new file mode 100644
index 0000000..b0c3ef0
--- /dev/null
+++ b/core/core/api/1.2.0-alpha04.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+ChangedStatic: androidx.core.content.pm.ShortcutManagerCompat#removeDynamicShortcuts(android.content.Context, java.util.List<java.lang.String>):
+    Method androidx.core.content.pm.ShortcutManagerCompat.removeDynamicShortcuts has changed 'static' qualifier
diff --git a/core/core/api/1.2.0-alpha04.txt b/core/core/api/1.2.0-alpha04.txt
new file mode 100644
index 0000000..d39053e
--- /dev/null
+++ b/core/core/api/1.2.0-alpha04.txt
@@ -0,0 +1,3062 @@
+// Signature format: 3.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 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 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 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
+  }
+
+  public abstract class JobIntentService extends android.app.Service {
+    ctor public JobIntentService();
+    method public static void enqueueWork(android.content.Context, Class<?>, int, android.content.Intent);
+    method public static void enqueueWork(android.content.Context, android.content.ComponentName, int, android.content.Intent);
+    method public boolean isStopped();
+    method public android.os.IBinder! onBind(android.content.Intent);
+    method protected abstract void onHandleWork(android.content.Intent);
+    method public boolean onStopCurrentWork();
+    method public void setInterruptIfStopped(boolean);
+  }
+
+  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 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 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 @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 String! getShortcutId(android.app.Notification!);
+    method public static String! getSortKey(android.app.Notification!);
+    method public static long getTimeoutAfter(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_MESSAGE = "msg";
+    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_SYSTEM = "sys";
+    field public static final String CATEGORY_TRANSPORT = "transport";
+    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_COMPACT_ACTIONS = "android.compactActions";
+    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_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_PEOPLE = "android.people";
+    field public static final String EXTRA_PICTURE = "android.picture";
+    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_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 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 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!);
+    method public android.app.PendingIntent! getActionIntent();
+    method public boolean getAllowGeneratedReplies();
+    method public androidx.core.app.RemoteInput![]! getDataOnlyRemoteInputs();
+    method public android.os.Bundle! getExtras();
+    method public int getIcon();
+    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 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 public int icon;
+    field public CharSequence! title;
+  }
+
+  public static final class NotificationCompat.Action.Builder {
+    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 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 public androidx.core.app.NotificationCompat.BigPictureStyle! setSummaryText(CharSequence!);
+  }
+
+  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 @RequiresApi(29) 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 boolean isNotificationSuppressed();
+    method @RequiresApi(29) public static android.app.Notification.BubbleMetadata? toPlatform(androidx.core.app.NotificationCompat.BubbleMetadata?);
+  }
+
+  public static final class NotificationCompat.BubbleMetadata.Builder {
+    ctor public NotificationCompat.BubbleMetadata.Builder();
+    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 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 public androidx.core.app.NotificationCompat.Builder! addPerson(String!);
+    method public android.app.Notification! build();
+    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 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! 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! 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! setShortcutId(String!);
+    method public androidx.core.app.NotificationCompat.Builder! setShowWhen(boolean);
+    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 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 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 public androidx.core.app.NotificationCompat.CarExtender! setUnreadConversation(androidx.core.app.NotificationCompat.CarExtender.UnreadConversation!);
+  }
+
+  public static class NotificationCompat.CarExtender.UnreadConversation {
+    method public long getLatestTimestamp();
+    method public String![]! getMessages();
+    method public String! getParticipant();
+    method public String![]! getParticipants();
+    method public android.app.PendingIntent! getReadPendingIntent();
+    method public androidx.core.app.RemoteInput! getRemoteInput();
+    method public android.app.PendingIntent! getReplyPendingIntent();
+  }
+
+  public static class NotificationCompat.CarExtender.UnreadConversation.Builder {
+    ctor public NotificationCompat.CarExtender.UnreadConversation.Builder(String!);
+    method public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder! addMessage(String!);
+    method public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation! build();
+    method public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder! setLatestTimestamp(long);
+    method public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder! setReadPendingIntent(android.app.PendingIntent!);
+    method 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 @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!>! 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 createNotificationChannelGroup(android.app.NotificationChannelGroup);
+    method public void createNotificationChannelGroups(java.util.List<android.app.NotificationChannelGroup!>);
+    method public void createNotificationChannels(java.util.List<android.app.NotificationChannel!>);
+    method public void deleteNotificationChannel(String);
+    method public void deleteNotificationChannelGroup(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.NotificationChannelGroup? getNotificationChannelGroup(String);
+    method public java.util.List<android.app.NotificationChannelGroup!> getNotificationChannelGroups();
+    method public java.util.List<android.app.NotificationChannel!> getNotificationChannels();
+    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 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 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 public static void configureMenuItem(android.view.MenuItem, androidx.core.app.ShareCompat.IntentBuilder);
+    method 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 {
+    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 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 {
+    method 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 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 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();
+    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 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 makeMainSelectorActivity(String, String);
+    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";
+  }
+
+  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 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();
+  }
+
+}
+
+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);
+  }
+
+  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 String getId();
+    method public android.content.Intent getIntent();
+    method public android.content.Intent![] getIntents();
+    method public CharSequence? getLongLabel();
+    method public CharSequence getShortLabel();
+    method @RequiresApi(25) public android.content.pm.ShortcutInfo! toShortcutInfo();
+  }
+
+  public static class ShortcutInfoCompat.Builder {
+    ctor public ShortcutInfoCompat.Builder(android.content.Context, 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 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 setLongLabel(CharSequence);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLived();
+    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 setShortLabel(CharSequence);
+  }
+
+  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 java.util.List<androidx.core.content.pm.ShortcutInfoCompat!> getDynamicShortcuts(android.content.Context);
+    method public static int getMaxShortcutCountPerActivity(android.content.Context);
+    method public static boolean isRequestPinShortcutSupported(android.content.Context);
+    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 boolean requestPinShortcut(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat, android.content.IntentSender?);
+    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";
+  }
+
+}
+
+package androidx.core.content.res {
+
+  public final class ConfigurationHelper {
+    method public static int getDensityDpi(android.content.res.Resources);
+  }
+
+  public final class ResourcesCompat {
+    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;
+  }
+
+  public abstract static class ResourcesCompat.FontCallback {
+    ctor public ResourcesCompat.FontCallback();
+    method public abstract void onFontRetrievalFailed(int);
+    method public abstract void onFontRetrieved(android.graphics.Typeface);
+  }
+
+}
+
+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 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=androidx.core.graphics.ColorUtils.XYZ_WHITE_REFERENCE_X) double, @FloatRange(from=0.0f, to=androidx.core.graphics.ColorUtils.XYZ_WHITE_REFERENCE_Y) double, @FloatRange(from=0.0f, to=androidx.core.graphics.ColorUtils.XYZ_WHITE_REFERENCE_Z) double);
+    method public static void XYZToLAB(@FloatRange(from=0.0f, to=androidx.core.graphics.ColorUtils.XYZ_WHITE_REFERENCE_X) double, @FloatRange(from=0.0f, to=androidx.core.graphics.ColorUtils.XYZ_WHITE_REFERENCE_Y) double, @FloatRange(from=0.0f, to=androidx.core.graphics.ColorUtils.XYZ_WHITE_REFERENCE_Z) 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 of(int, int, int, int);
+    method public static androidx.core.graphics.Insets of(android.graphics.Rect);
+    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 extends androidx.versionedparcelable.CustomVersionedParcelable {
+    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! 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 @IdRes 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 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 @RequiresApi(23) public android.graphics.drawable.Icon! toIcon();
+    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
+  }
+
+  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 final 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 final class LocationManagerCompat {
+    method public static boolean isLocationEnabled(android.location.LocationManager);
+  }
+
+}
+
+package androidx.core.math {
+
+  public class MathUtils {
+    method public static float clamp(float, float, float);
+    method public static double clamp(double, double, double);
+    method public static int clamp(int, int, int);
+  }
+
+}
+
+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 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 public static boolean isAtLeastN();
+    method @Deprecated public static boolean isAtLeastNMR1();
+    method @Deprecated public static boolean isAtLeastO();
+    method @Deprecated public static boolean isAtLeastOMR1();
+    method @Deprecated public static boolean isAtLeastP();
+    method @Deprecated public static boolean isAtLeastQ();
+  }
+
+  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 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 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 TraceCompat {
+    method public static void beginAsyncSection(String, int);
+    method public static void beginSection(String);
+    method public static void endAsyncSection(String, int);
+    method public static void endSection();
+    method public static boolean isEnabled();
+    method public static void setCounter(String, int);
+  }
+
+  public class UserManagerCompat {
+    method public static boolean isUserUnlocked(android.content.Context);
+  }
+
+}
+
+package androidx.core.provider {
+
+  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.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?);
+  }
+
+  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 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 DisplayCutoutCompat {
+    ctor public DisplayCutoutCompat(android.graphics.Rect!, java.util.List<android.graphics.Rect!>!);
+    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();
+  }
+
+  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 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 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 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 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! 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 @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 @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 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 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 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 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 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 @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 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 @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 <T extends android.view.View> T requireViewById(android.view.Window, @IdRes int);
+    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 class WindowInsetsCompat {
+    ctor public WindowInsetsCompat(androidx.core.view.WindowInsetsCompat!);
+    method public androidx.core.view.WindowInsetsCompat! consumeDisplayCutout();
+    method public androidx.core.view.WindowInsetsCompat! consumeStableInsets();
+    method public androidx.core.view.WindowInsetsCompat! consumeSystemWindowInsets();
+    method public androidx.core.view.DisplayCutoutCompat? getDisplayCutout();
+    method public androidx.core.graphics.Insets getMandatorySystemGestureInsets();
+    method public int getStableInsetBottom();
+    method public int getStableInsetLeft();
+    method public int getStableInsetRight();
+    method public int getStableInsetTop();
+    method public androidx.core.graphics.Insets getStableInsets();
+    method public androidx.core.graphics.Insets getSystemGestureInsets();
+    method public int getSystemWindowInsetBottom();
+    method public int getSystemWindowInsetLeft();
+    method public int getSystemWindowInsetRight();
+    method public int getSystemWindowInsetTop();
+    method public androidx.core.graphics.Insets getSystemWindowInsets();
+    method public androidx.core.graphics.Insets getTappableElementInsets();
+    method public boolean hasInsets();
+    method public boolean hasStableInsets();
+    method public boolean hasSystemWindowInsets();
+    method public boolean isConsumed();
+    method public boolean isRound();
+    method public androidx.core.view.WindowInsetsCompat! replaceSystemWindowInsets(int, int, int, int);
+    method 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);
+  }
+
+}
+
+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_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 @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! 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 @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 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_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_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_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 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 void setContentMimeTypes(android.view.inputmethod.EditorInfo, String![]?);
+    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 public static android.view.inputmethod.InputConnection createWrapper(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, androidx.core.view.inputmethod.InputConnectionCompat.OnCommitContentListener);
+    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 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 @Deprecated public boolean draw(android.graphics.Canvas!);
+    method @Deprecated public void finish();
+    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 @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 smoothScrollTo(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, @Px @IntRange(from=0) int);
+    method public static void setLastBaselineToBottomHeight(android.widget.TextView, @Px @IntRange(from=0) int);
+    method public static void setLineHeight(android.widget.TextView, @Px @IntRange(from=0) 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/api_lint.ignore b/core/core/api/api_lint.ignore
index e607711..c35f8ae0 100644
--- a/core/core/api/api_lint.ignore
+++ b/core/core/api/api_lint.ignore
@@ -163,6 +163,1912 @@
     Listeners should be an interface, or otherwise renamed Callback: OneShotPreDrawListener
 
 
+MissingNullability: androidx.core.app.ActivityCompat#invalidateOptionsMenu(android.app.Activity) parameter #0:
+    Missing nullability on parameter `activity` in method `invalidateOptionsMenu`
+MissingNullability: androidx.core.app.ActivityCompat#requestDragAndDropPermissions(android.app.Activity, android.view.DragEvent) parameter #0:
+    Missing nullability on parameter `activity` in method `requestDragAndDropPermissions`
+MissingNullability: androidx.core.app.ActivityCompat#requestDragAndDropPermissions(android.app.Activity, android.view.DragEvent) parameter #1:
+    Missing nullability on parameter `dragEvent` in method `requestDragAndDropPermissions`
+MissingNullability: androidx.core.app.ActivityOptionsCompat#makeSceneTransitionAnimation(android.app.Activity, androidx.core.util.Pair<android.view.View,java.lang.String>...) parameter #1:
+    Missing nullability on parameter `sharedElements` in method `makeSceneTransitionAnimation`
+MissingNullability: androidx.core.app.JobIntentService#onBind(android.content.Intent):
+    Missing nullability on method `onBind` return
+MissingNullability: androidx.core.app.NotificationCompat#getAction(android.app.Notification, int):
+    Missing nullability on method `getAction` return
+MissingNullability: androidx.core.app.NotificationCompat#getAction(android.app.Notification, int) parameter #0:
+    Missing nullability on parameter `notification` in method `getAction`
+MissingNullability: androidx.core.app.NotificationCompat#getActionCount(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `getActionCount`
+MissingNullability: androidx.core.app.NotificationCompat#getAllowSystemGeneratedContextualActions(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `getAllowSystemGeneratedContextualActions`
+MissingNullability: androidx.core.app.NotificationCompat#getBadgeIconType(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `getBadgeIconType`
+MissingNullability: androidx.core.app.NotificationCompat#getCategory(android.app.Notification):
+    Missing nullability on method `getCategory` return
+MissingNullability: androidx.core.app.NotificationCompat#getCategory(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `getCategory`
+MissingNullability: androidx.core.app.NotificationCompat#getChannelId(android.app.Notification):
+    Missing nullability on method `getChannelId` return
+MissingNullability: androidx.core.app.NotificationCompat#getChannelId(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `getChannelId`
+MissingNullability: androidx.core.app.NotificationCompat#getContentTitle(android.app.Notification):
+    Missing nullability on method `getContentTitle` return
+MissingNullability: androidx.core.app.NotificationCompat#getContentTitle(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `getContentTitle`
+MissingNullability: androidx.core.app.NotificationCompat#getExtras(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `getExtras`
+MissingNullability: androidx.core.app.NotificationCompat#getGroup(android.app.Notification):
+    Missing nullability on method `getGroup` return
+MissingNullability: androidx.core.app.NotificationCompat#getGroup(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `getGroup`
+MissingNullability: androidx.core.app.NotificationCompat#getGroupAlertBehavior(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `getGroupAlertBehavior`
+MissingNullability: androidx.core.app.NotificationCompat#getInvisibleActions(android.app.Notification):
+    Missing nullability on method `getInvisibleActions` return
+MissingNullability: androidx.core.app.NotificationCompat#getInvisibleActions(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `getInvisibleActions`
+MissingNullability: androidx.core.app.NotificationCompat#getLocalOnly(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `getLocalOnly`
+MissingNullability: androidx.core.app.NotificationCompat#getShortcutId(android.app.Notification):
+    Missing nullability on method `getShortcutId` return
+MissingNullability: androidx.core.app.NotificationCompat#getShortcutId(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `getShortcutId`
+MissingNullability: androidx.core.app.NotificationCompat#getSortKey(android.app.Notification):
+    Missing nullability on method `getSortKey` return
+MissingNullability: androidx.core.app.NotificationCompat#getSortKey(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `getSortKey`
+MissingNullability: androidx.core.app.NotificationCompat#getTimeoutAfter(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `getTimeoutAfter`
+MissingNullability: androidx.core.app.NotificationCompat#isGroupSummary(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `isGroupSummary`
+MissingNullability: androidx.core.app.NotificationCompat.Action#Action(int, CharSequence, android.app.PendingIntent) parameter #1:
+    Missing nullability on parameter `title` in method `Action`
+MissingNullability: androidx.core.app.NotificationCompat.Action#Action(int, CharSequence, android.app.PendingIntent) parameter #2:
+    Missing nullability on parameter `intent` in method `Action`
+MissingNullability: androidx.core.app.NotificationCompat.Action#actionIntent:
+    Missing nullability on field `actionIntent` in class `class androidx.core.app.NotificationCompat.Action`
+MissingNullability: androidx.core.app.NotificationCompat.Action#getActionIntent():
+    Missing nullability on method `getActionIntent` return
+MissingNullability: androidx.core.app.NotificationCompat.Action#getDataOnlyRemoteInputs():
+    Missing nullability on method `getDataOnlyRemoteInputs` return
+MissingNullability: androidx.core.app.NotificationCompat.Action#getExtras():
+    Missing nullability on method `getExtras` return
+MissingNullability: androidx.core.app.NotificationCompat.Action#getRemoteInputs():
+    Missing nullability on method `getRemoteInputs` return
+MissingNullability: androidx.core.app.NotificationCompat.Action#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.core.app.NotificationCompat.Action#title:
+    Missing nullability on field `title` in class `class androidx.core.app.NotificationCompat.Action`
+MissingNullability: androidx.core.app.NotificationCompat.Action.Builder#Builder(androidx.core.app.NotificationCompat.Action) parameter #0:
+    Missing nullability on parameter `action` in method `Builder`
+MissingNullability: androidx.core.app.NotificationCompat.Action.Builder#Builder(int, CharSequence, android.app.PendingIntent) parameter #1:
+    Missing nullability on parameter `title` in method `Builder`
+MissingNullability: androidx.core.app.NotificationCompat.Action.Builder#Builder(int, CharSequence, android.app.PendingIntent) parameter #2:
+    Missing nullability on parameter `intent` in method `Builder`
+MissingNullability: androidx.core.app.NotificationCompat.Action.Builder#addExtras(android.os.Bundle):
+    Missing nullability on method `addExtras` return
+MissingNullability: androidx.core.app.NotificationCompat.Action.Builder#addExtras(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `extras` in method `addExtras`
+MissingNullability: androidx.core.app.NotificationCompat.Action.Builder#addRemoteInput(androidx.core.app.RemoteInput):
+    Missing nullability on method `addRemoteInput` return
+MissingNullability: androidx.core.app.NotificationCompat.Action.Builder#addRemoteInput(androidx.core.app.RemoteInput) parameter #0:
+    Missing nullability on parameter `remoteInput` in method `addRemoteInput`
+MissingNullability: androidx.core.app.NotificationCompat.Action.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.core.app.NotificationCompat.Action.Builder#extend(androidx.core.app.NotificationCompat.Action.Extender):
+    Missing nullability on method `extend` return
+MissingNullability: androidx.core.app.NotificationCompat.Action.Builder#extend(androidx.core.app.NotificationCompat.Action.Extender) parameter #0:
+    Missing nullability on parameter `extender` in method `extend`
+MissingNullability: androidx.core.app.NotificationCompat.Action.Builder#getExtras():
+    Missing nullability on method `getExtras` return
+MissingNullability: androidx.core.app.NotificationCompat.Action.Builder#setAllowGeneratedReplies(boolean):
+    Missing nullability on method `setAllowGeneratedReplies` return
+MissingNullability: androidx.core.app.NotificationCompat.Action.Builder#setSemanticAction(int):
+    Missing nullability on method `setSemanticAction` return
+MissingNullability: androidx.core.app.NotificationCompat.Action.Builder#setShowsUserInterface(boolean):
+    Missing nullability on method `setShowsUserInterface` return
+MissingNullability: androidx.core.app.NotificationCompat.Action.Extender#extend(androidx.core.app.NotificationCompat.Action.Builder):
+    Missing nullability on method `extend` return
+MissingNullability: androidx.core.app.NotificationCompat.Action.Extender#extend(androidx.core.app.NotificationCompat.Action.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `extend`
+MissingNullability: androidx.core.app.NotificationCompat.Action.WearableExtender#WearableExtender(androidx.core.app.NotificationCompat.Action) parameter #0:
+    Missing nullability on parameter `action` in method `WearableExtender`
+MissingNullability: androidx.core.app.NotificationCompat.Action.WearableExtender#clone():
+    Missing nullability on method `clone` return
+MissingNullability: androidx.core.app.NotificationCompat.Action.WearableExtender#extend(androidx.core.app.NotificationCompat.Action.Builder):
+    Missing nullability on method `extend` return
+MissingNullability: androidx.core.app.NotificationCompat.Action.WearableExtender#extend(androidx.core.app.NotificationCompat.Action.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `extend`
+MissingNullability: androidx.core.app.NotificationCompat.Action.WearableExtender#setAvailableOffline(boolean):
+    Missing nullability on method `setAvailableOffline` return
+MissingNullability: androidx.core.app.NotificationCompat.Action.WearableExtender#setCancelLabel(CharSequence) parameter #0:
+    Missing nullability on parameter `label` in method `setCancelLabel`
+MissingNullability: androidx.core.app.NotificationCompat.Action.WearableExtender#setConfirmLabel(CharSequence) parameter #0:
+    Missing nullability on parameter `label` in method `setConfirmLabel`
+MissingNullability: androidx.core.app.NotificationCompat.Action.WearableExtender#setHintDisplayActionInline(boolean):
+    Missing nullability on method `setHintDisplayActionInline` return
+MissingNullability: androidx.core.app.NotificationCompat.Action.WearableExtender#setHintLaunchesActivity(boolean):
+    Missing nullability on method `setHintLaunchesActivity` return
+MissingNullability: androidx.core.app.NotificationCompat.Action.WearableExtender#setInProgressLabel(CharSequence) parameter #0:
+    Missing nullability on parameter `label` in method `setInProgressLabel`
+MissingNullability: androidx.core.app.NotificationCompat.BigPictureStyle#BigPictureStyle(androidx.core.app.NotificationCompat.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `BigPictureStyle`
+MissingNullability: androidx.core.app.NotificationCompat.BigPictureStyle#bigLargeIcon(android.graphics.Bitmap):
+    Missing nullability on method `bigLargeIcon` return
+MissingNullability: androidx.core.app.NotificationCompat.BigPictureStyle#bigLargeIcon(android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `b` in method `bigLargeIcon`
+MissingNullability: androidx.core.app.NotificationCompat.BigPictureStyle#bigPicture(android.graphics.Bitmap):
+    Missing nullability on method `bigPicture` return
+MissingNullability: androidx.core.app.NotificationCompat.BigPictureStyle#bigPicture(android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `b` in method `bigPicture`
+MissingNullability: androidx.core.app.NotificationCompat.BigPictureStyle#setBigContentTitle(CharSequence):
+    Missing nullability on method `setBigContentTitle` return
+MissingNullability: androidx.core.app.NotificationCompat.BigPictureStyle#setBigContentTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setBigContentTitle`
+MissingNullability: androidx.core.app.NotificationCompat.BigPictureStyle#setSummaryText(CharSequence):
+    Missing nullability on method `setSummaryText` return
+MissingNullability: androidx.core.app.NotificationCompat.BigPictureStyle#setSummaryText(CharSequence) parameter #0:
+    Missing nullability on parameter `cs` in method `setSummaryText`
+MissingNullability: androidx.core.app.NotificationCompat.BigTextStyle#BigTextStyle(androidx.core.app.NotificationCompat.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `BigTextStyle`
+MissingNullability: androidx.core.app.NotificationCompat.BigTextStyle#bigText(CharSequence):
+    Missing nullability on method `bigText` return
+MissingNullability: androidx.core.app.NotificationCompat.BigTextStyle#bigText(CharSequence) parameter #0:
+    Missing nullability on parameter `cs` in method `bigText`
+MissingNullability: androidx.core.app.NotificationCompat.BigTextStyle#setBigContentTitle(CharSequence):
+    Missing nullability on method `setBigContentTitle` return
+MissingNullability: androidx.core.app.NotificationCompat.BigTextStyle#setBigContentTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setBigContentTitle`
+MissingNullability: androidx.core.app.NotificationCompat.BigTextStyle#setSummaryText(CharSequence):
+    Missing nullability on method `setSummaryText` return
+MissingNullability: androidx.core.app.NotificationCompat.BigTextStyle#setSummaryText(CharSequence) parameter #0:
+    Missing nullability on parameter `cs` in method `setSummaryText`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#Builder(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `Builder`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#addAction(androidx.core.app.NotificationCompat.Action):
+    Missing nullability on method `addAction` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#addAction(androidx.core.app.NotificationCompat.Action) parameter #0:
+    Missing nullability on parameter `action` in method `addAction`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#addAction(int, CharSequence, android.app.PendingIntent):
+    Missing nullability on method `addAction` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#addAction(int, CharSequence, android.app.PendingIntent) parameter #1:
+    Missing nullability on parameter `title` in method `addAction`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#addAction(int, CharSequence, android.app.PendingIntent) parameter #2:
+    Missing nullability on parameter `intent` in method `addAction`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#addExtras(android.os.Bundle):
+    Missing nullability on method `addExtras` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#addExtras(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `extras` in method `addExtras`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#addInvisibleAction(androidx.core.app.NotificationCompat.Action):
+    Missing nullability on method `addInvisibleAction` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#addInvisibleAction(androidx.core.app.NotificationCompat.Action) parameter #0:
+    Missing nullability on parameter `action` in method `addInvisibleAction`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#addInvisibleAction(int, CharSequence, android.app.PendingIntent):
+    Missing nullability on method `addInvisibleAction` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#addInvisibleAction(int, CharSequence, android.app.PendingIntent) parameter #1:
+    Missing nullability on parameter `title` in method `addInvisibleAction`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#addInvisibleAction(int, CharSequence, android.app.PendingIntent) parameter #2:
+    Missing nullability on parameter `intent` in method `addInvisibleAction`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#addPerson(String):
+    Missing nullability on method `addPerson` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#addPerson(String) parameter #0:
+    Missing nullability on parameter `uri` in method `addPerson`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#extend(androidx.core.app.NotificationCompat.Extender):
+    Missing nullability on method `extend` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#extend(androidx.core.app.NotificationCompat.Extender) parameter #0:
+    Missing nullability on parameter `extender` in method `extend`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#getExtras():
+    Missing nullability on method `getExtras` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#limitCharSequenceLength(CharSequence):
+    Missing nullability on method `limitCharSequenceLength` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#limitCharSequenceLength(CharSequence) parameter #0:
+    Missing nullability on parameter `cs` in method `limitCharSequenceLength`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setAutoCancel(boolean):
+    Missing nullability on method `setAutoCancel` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setBadgeIconType(int):
+    Missing nullability on method `setBadgeIconType` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setCategory(String):
+    Missing nullability on method `setCategory` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setCategory(String) parameter #0:
+    Missing nullability on parameter `category` in method `setCategory`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setChannelId(String):
+    Missing nullability on method `setChannelId` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setColor(int):
+    Missing nullability on method `setColor` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setColorized(boolean):
+    Missing nullability on method `setColorized` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setContent(android.widget.RemoteViews):
+    Missing nullability on method `setContent` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setContent(android.widget.RemoteViews) parameter #0:
+    Missing nullability on parameter `views` in method `setContent`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setContentInfo(CharSequence):
+    Missing nullability on method `setContentInfo` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setContentInfo(CharSequence) parameter #0:
+    Missing nullability on parameter `info` in method `setContentInfo`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setContentIntent(android.app.PendingIntent):
+    Missing nullability on method `setContentIntent` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setContentIntent(android.app.PendingIntent) parameter #0:
+    Missing nullability on parameter `intent` in method `setContentIntent`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setContentText(CharSequence):
+    Missing nullability on method `setContentText` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setContentText(CharSequence) parameter #0:
+    Missing nullability on parameter `text` in method `setContentText`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setContentTitle(CharSequence):
+    Missing nullability on method `setContentTitle` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setContentTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setContentTitle`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setCustomBigContentView(android.widget.RemoteViews):
+    Missing nullability on method `setCustomBigContentView` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setCustomBigContentView(android.widget.RemoteViews) parameter #0:
+    Missing nullability on parameter `contentView` in method `setCustomBigContentView`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setCustomContentView(android.widget.RemoteViews):
+    Missing nullability on method `setCustomContentView` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setCustomContentView(android.widget.RemoteViews) parameter #0:
+    Missing nullability on parameter `contentView` in method `setCustomContentView`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setCustomHeadsUpContentView(android.widget.RemoteViews):
+    Missing nullability on method `setCustomHeadsUpContentView` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setCustomHeadsUpContentView(android.widget.RemoteViews) parameter #0:
+    Missing nullability on parameter `contentView` in method `setCustomHeadsUpContentView`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setDefaults(int):
+    Missing nullability on method `setDefaults` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setDeleteIntent(android.app.PendingIntent):
+    Missing nullability on method `setDeleteIntent` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setDeleteIntent(android.app.PendingIntent) parameter #0:
+    Missing nullability on parameter `intent` in method `setDeleteIntent`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setExtras(android.os.Bundle):
+    Missing nullability on method `setExtras` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setExtras(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `extras` in method `setExtras`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setFullScreenIntent(android.app.PendingIntent, boolean):
+    Missing nullability on method `setFullScreenIntent` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setFullScreenIntent(android.app.PendingIntent, boolean) parameter #0:
+    Missing nullability on parameter `intent` in method `setFullScreenIntent`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setGroup(String):
+    Missing nullability on method `setGroup` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setGroup(String) parameter #0:
+    Missing nullability on parameter `groupKey` in method `setGroup`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setGroupAlertBehavior(int):
+    Missing nullability on method `setGroupAlertBehavior` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setGroupSummary(boolean):
+    Missing nullability on method `setGroupSummary` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setLargeIcon(android.graphics.Bitmap):
+    Missing nullability on method `setLargeIcon` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setLargeIcon(android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `icon` in method `setLargeIcon`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setLights(int, int, int):
+    Missing nullability on method `setLights` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setLocalOnly(boolean):
+    Missing nullability on method `setLocalOnly` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setNumber(int):
+    Missing nullability on method `setNumber` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setOngoing(boolean):
+    Missing nullability on method `setOngoing` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setOnlyAlertOnce(boolean):
+    Missing nullability on method `setOnlyAlertOnce` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setPriority(int):
+    Missing nullability on method `setPriority` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setProgress(int, int, boolean):
+    Missing nullability on method `setProgress` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setPublicVersion(android.app.Notification):
+    Missing nullability on method `setPublicVersion` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setPublicVersion(android.app.Notification) parameter #0:
+    Missing nullability on parameter `n` in method `setPublicVersion`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setRemoteInputHistory(CharSequence[]):
+    Missing nullability on method `setRemoteInputHistory` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setRemoteInputHistory(CharSequence[]) parameter #0:
+    Missing nullability on parameter `text` in method `setRemoteInputHistory`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setShortcutId(String):
+    Missing nullability on method `setShortcutId` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setShortcutId(String) parameter #0:
+    Missing nullability on parameter `shortcutId` in method `setShortcutId`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setShowWhen(boolean):
+    Missing nullability on method `setShowWhen` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setSmallIcon(int):
+    Missing nullability on method `setSmallIcon` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setSmallIcon(int, int):
+    Missing nullability on method `setSmallIcon` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setSortKey(String):
+    Missing nullability on method `setSortKey` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setSortKey(String) parameter #0:
+    Missing nullability on parameter `sortKey` in method `setSortKey`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setSound(android.net.Uri):
+    Missing nullability on method `setSound` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setSound(android.net.Uri) parameter #0:
+    Missing nullability on parameter `sound` in method `setSound`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setSound(android.net.Uri, int):
+    Missing nullability on method `setSound` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setSound(android.net.Uri, int) parameter #0:
+    Missing nullability on parameter `sound` in method `setSound`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setStyle(androidx.core.app.NotificationCompat.Style):
+    Missing nullability on method `setStyle` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setStyle(androidx.core.app.NotificationCompat.Style) parameter #0:
+    Missing nullability on parameter `style` in method `setStyle`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setSubText(CharSequence):
+    Missing nullability on method `setSubText` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setSubText(CharSequence) parameter #0:
+    Missing nullability on parameter `text` in method `setSubText`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setTicker(CharSequence):
+    Missing nullability on method `setTicker` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setTicker(CharSequence) parameter #0:
+    Missing nullability on parameter `tickerText` in method `setTicker`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setTicker(CharSequence, android.widget.RemoteViews):
+    Missing nullability on method `setTicker` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setTicker(CharSequence, android.widget.RemoteViews) parameter #0:
+    Missing nullability on parameter `tickerText` in method `setTicker`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setTicker(CharSequence, android.widget.RemoteViews) parameter #1:
+    Missing nullability on parameter `views` in method `setTicker`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setTimeoutAfter(long):
+    Missing nullability on method `setTimeoutAfter` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setUsesChronometer(boolean):
+    Missing nullability on method `setUsesChronometer` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setVibrate(long[]):
+    Missing nullability on method `setVibrate` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setVibrate(long[]) parameter #0:
+    Missing nullability on parameter `pattern` in method `setVibrate`
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setVisibility(int):
+    Missing nullability on method `setVisibility` return
+MissingNullability: androidx.core.app.NotificationCompat.Builder#setWhen(long):
+    Missing nullability on method `setWhen` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender#CarExtender(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `CarExtender`
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender#extend(androidx.core.app.NotificationCompat.Builder):
+    Missing nullability on method `extend` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender#extend(androidx.core.app.NotificationCompat.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `extend`
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender#getLargeIcon():
+    Missing nullability on method `getLargeIcon` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender#getUnreadConversation():
+    Missing nullability on method `getUnreadConversation` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender#setColor(int):
+    Missing nullability on method `setColor` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender#setLargeIcon(android.graphics.Bitmap):
+    Missing nullability on method `setLargeIcon` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender#setLargeIcon(android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `largeIcon` in method `setLargeIcon`
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender#setUnreadConversation(androidx.core.app.NotificationCompat.CarExtender.UnreadConversation):
+    Missing nullability on method `setUnreadConversation` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender#setUnreadConversation(androidx.core.app.NotificationCompat.CarExtender.UnreadConversation) parameter #0:
+    Missing nullability on parameter `unreadConversation` in method `setUnreadConversation`
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender.UnreadConversation#getMessages():
+    Missing nullability on method `getMessages` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender.UnreadConversation#getParticipant():
+    Missing nullability on method `getParticipant` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender.UnreadConversation#getParticipants():
+    Missing nullability on method `getParticipants` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender.UnreadConversation#getReadPendingIntent():
+    Missing nullability on method `getReadPendingIntent` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender.UnreadConversation#getRemoteInput():
+    Missing nullability on method `getRemoteInput` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender.UnreadConversation#getReplyPendingIntent():
+    Missing nullability on method `getReplyPendingIntent` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder#Builder(String) parameter #0:
+    Missing nullability on parameter `name` in method `Builder`
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder#addMessage(String):
+    Missing nullability on method `addMessage` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder#addMessage(String) parameter #0:
+    Missing nullability on parameter `message` in method `addMessage`
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder#setLatestTimestamp(long):
+    Missing nullability on method `setLatestTimestamp` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder#setReadPendingIntent(android.app.PendingIntent):
+    Missing nullability on method `setReadPendingIntent` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder#setReadPendingIntent(android.app.PendingIntent) parameter #0:
+    Missing nullability on parameter `pendingIntent` in method `setReadPendingIntent`
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder#setReplyAction(android.app.PendingIntent, androidx.core.app.RemoteInput):
+    Missing nullability on method `setReplyAction` return
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder#setReplyAction(android.app.PendingIntent, androidx.core.app.RemoteInput) parameter #0:
+    Missing nullability on parameter `pendingIntent` in method `setReplyAction`
+MissingNullability: androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder#setReplyAction(android.app.PendingIntent, androidx.core.app.RemoteInput) parameter #1:
+    Missing nullability on parameter `remoteInput` in method `setReplyAction`
+MissingNullability: androidx.core.app.NotificationCompat.Extender#extend(androidx.core.app.NotificationCompat.Builder):
+    Missing nullability on method `extend` return
+MissingNullability: androidx.core.app.NotificationCompat.Extender#extend(androidx.core.app.NotificationCompat.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `extend`
+MissingNullability: androidx.core.app.NotificationCompat.InboxStyle#InboxStyle(androidx.core.app.NotificationCompat.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `InboxStyle`
+MissingNullability: androidx.core.app.NotificationCompat.InboxStyle#addLine(CharSequence):
+    Missing nullability on method `addLine` return
+MissingNullability: androidx.core.app.NotificationCompat.InboxStyle#addLine(CharSequence) parameter #0:
+    Missing nullability on parameter `cs` in method `addLine`
+MissingNullability: androidx.core.app.NotificationCompat.InboxStyle#setBigContentTitle(CharSequence):
+    Missing nullability on method `setBigContentTitle` return
+MissingNullability: androidx.core.app.NotificationCompat.InboxStyle#setBigContentTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setBigContentTitle`
+MissingNullability: androidx.core.app.NotificationCompat.InboxStyle#setSummaryText(CharSequence):
+    Missing nullability on method `setSummaryText` return
+MissingNullability: androidx.core.app.NotificationCompat.InboxStyle#setSummaryText(CharSequence) parameter #0:
+    Missing nullability on parameter `cs` in method `setSummaryText`
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle#addCompatExtras(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `extras` in method `addCompatExtras`
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle#addMessage(CharSequence, long, CharSequence) parameter #0:
+    Missing nullability on parameter `text` in method `addMessage`
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle#addMessage(CharSequence, long, CharSequence) parameter #2:
+    Missing nullability on parameter `sender` in method `addMessage`
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle#addMessage(CharSequence, long, androidx.core.app.Person):
+    Missing nullability on method `addMessage` return
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle#addMessage(CharSequence, long, androidx.core.app.Person) parameter #0:
+    Missing nullability on parameter `text` in method `addMessage`
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle#addMessage(CharSequence, long, androidx.core.app.Person) parameter #2:
+    Missing nullability on parameter `person` in method `addMessage`
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle#addMessage(androidx.core.app.NotificationCompat.MessagingStyle.Message):
+    Missing nullability on method `addMessage` return
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle#addMessage(androidx.core.app.NotificationCompat.MessagingStyle.Message) parameter #0:
+    Missing nullability on parameter `message` in method `addMessage`
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle#extractMessagingStyleFromNotification(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `extractMessagingStyleFromNotification`
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle#getMessages():
+    Missing nullability on method `getMessages` return
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle#getUser():
+    Missing nullability on method `getUser` return
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle#setConversationTitle(CharSequence):
+    Missing nullability on method `setConversationTitle` return
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle#setGroupConversation(boolean):
+    Missing nullability on method `setGroupConversation` return
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle.Message#Message(CharSequence, long, CharSequence) parameter #0:
+    Missing nullability on parameter `text` in method `Message`
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle.Message#Message(CharSequence, long, CharSequence) parameter #2:
+    Missing nullability on parameter `sender` in method `Message`
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle.Message#Message(CharSequence, long, androidx.core.app.Person) parameter #0:
+    Missing nullability on parameter `text` in method `Message`
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle.Message#setData(String, android.net.Uri):
+    Missing nullability on method `setData` return
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle.Message#setData(String, android.net.Uri) parameter #0:
+    Missing nullability on parameter `dataMimeType` in method `setData`
+MissingNullability: androidx.core.app.NotificationCompat.MessagingStyle.Message#setData(String, android.net.Uri) parameter #1:
+    Missing nullability on parameter `dataUri` in method `setData`
+MissingNullability: androidx.core.app.NotificationCompat.Style#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.core.app.NotificationCompat.Style#setBuilder(androidx.core.app.NotificationCompat.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `setBuilder`
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#WearableExtender(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `WearableExtender`
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#addAction(androidx.core.app.NotificationCompat.Action):
+    Missing nullability on method `addAction` return
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#addAction(androidx.core.app.NotificationCompat.Action) parameter #0:
+    Missing nullability on parameter `action` in method `addAction`
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#addActions(java.util.List<androidx.core.app.NotificationCompat.Action>):
+    Missing nullability on method `addActions` return
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#addActions(java.util.List<androidx.core.app.NotificationCompat.Action>) parameter #0:
+    Missing nullability on parameter `actions` in method `addActions`
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#addPage(android.app.Notification) parameter #0:
+    Missing nullability on parameter `page` in method `addPage`
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#addPages(java.util.List<android.app.Notification>) parameter #0:
+    Missing nullability on parameter `pages` in method `addPages`
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#clearActions():
+    Missing nullability on method `clearActions` return
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#clone():
+    Missing nullability on method `clone` return
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#extend(androidx.core.app.NotificationCompat.Builder):
+    Missing nullability on method `extend` return
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#extend(androidx.core.app.NotificationCompat.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `extend`
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#getActions():
+    Missing nullability on method `getActions` return
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#getBridgeTag():
+    Missing nullability on method `getBridgeTag` return
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#getDismissalId():
+    Missing nullability on method `getDismissalId` return
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#setBackground(android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `background` in method `setBackground`
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#setBridgeTag(String):
+    Missing nullability on method `setBridgeTag` return
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#setBridgeTag(String) parameter #0:
+    Missing nullability on parameter `bridgeTag` in method `setBridgeTag`
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#setContentAction(int):
+    Missing nullability on method `setContentAction` return
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#setContentIntentAvailableOffline(boolean):
+    Missing nullability on method `setContentIntentAvailableOffline` return
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#setDismissalId(String):
+    Missing nullability on method `setDismissalId` return
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#setDismissalId(String) parameter #0:
+    Missing nullability on parameter `dismissalId` in method `setDismissalId`
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#setDisplayIntent(android.app.PendingIntent) parameter #0:
+    Missing nullability on parameter `intent` in method `setDisplayIntent`
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#setHintContentIntentLaunchesActivity(boolean):
+    Missing nullability on method `setHintContentIntentLaunchesActivity` return
+MissingNullability: androidx.core.app.NotificationCompat.WearableExtender#setStartScrollBottom(boolean):
+    Missing nullability on method `setStartScrollBottom` return
+MissingNullability: androidx.core.app.NotificationCompatSideChannelService#cancel(String, int, String) parameter #0:
+    Missing nullability on parameter `packageName` in method `cancel`
+MissingNullability: androidx.core.app.NotificationCompatSideChannelService#cancel(String, int, String) parameter #2:
+    Missing nullability on parameter `tag` in method `cancel`
+MissingNullability: androidx.core.app.NotificationCompatSideChannelService#cancelAll(String) parameter #0:
+    Missing nullability on parameter `packageName` in method `cancelAll`
+MissingNullability: androidx.core.app.NotificationCompatSideChannelService#notify(String, int, String, android.app.Notification) parameter #0:
+    Missing nullability on parameter `packageName` in method `notify`
+MissingNullability: androidx.core.app.NotificationCompatSideChannelService#notify(String, int, String, android.app.Notification) parameter #2:
+    Missing nullability on parameter `tag` in method `notify`
+MissingNullability: androidx.core.app.NotificationCompatSideChannelService#notify(String, int, String, android.app.Notification) parameter #3:
+    Missing nullability on parameter `notification` in method `notify`
+MissingNullability: androidx.core.app.NotificationCompatSideChannelService#onBind(android.content.Intent):
+    Missing nullability on method `onBind` return
+MissingNullability: androidx.core.app.NotificationCompatSideChannelService#onBind(android.content.Intent) parameter #0:
+    Missing nullability on parameter `intent` in method `onBind`
+MissingNullability: androidx.core.app.RemoteInput#addDataResultToIntent(androidx.core.app.RemoteInput, android.content.Intent, java.util.Map<java.lang.String,android.net.Uri>) parameter #0:
+    Missing nullability on parameter `remoteInput` in method `addDataResultToIntent`
+MissingNullability: androidx.core.app.RemoteInput#addDataResultToIntent(androidx.core.app.RemoteInput, android.content.Intent, java.util.Map<java.lang.String,android.net.Uri>) parameter #1:
+    Missing nullability on parameter `intent` in method `addDataResultToIntent`
+MissingNullability: androidx.core.app.RemoteInput#addDataResultToIntent(androidx.core.app.RemoteInput, android.content.Intent, java.util.Map<java.lang.String,android.net.Uri>) parameter #2:
+    Missing nullability on parameter `results` in method `addDataResultToIntent`
+MissingNullability: androidx.core.app.RemoteInput#addResultsToIntent(androidx.core.app.RemoteInput[], android.content.Intent, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `remoteInputs` in method `addResultsToIntent`
+MissingNullability: androidx.core.app.RemoteInput#addResultsToIntent(androidx.core.app.RemoteInput[], android.content.Intent, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `intent` in method `addResultsToIntent`
+MissingNullability: androidx.core.app.RemoteInput#addResultsToIntent(androidx.core.app.RemoteInput[], android.content.Intent, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `results` in method `addResultsToIntent`
+MissingNullability: androidx.core.app.RemoteInput#getAllowedDataTypes():
+    Missing nullability on method `getAllowedDataTypes` return
+MissingNullability: androidx.core.app.RemoteInput#getChoices():
+    Missing nullability on method `getChoices` return
+MissingNullability: androidx.core.app.RemoteInput#getDataResultsFromIntent(android.content.Intent, String):
+    Missing nullability on method `getDataResultsFromIntent` return
+MissingNullability: androidx.core.app.RemoteInput#getDataResultsFromIntent(android.content.Intent, String) parameter #0:
+    Missing nullability on parameter `intent` in method `getDataResultsFromIntent`
+MissingNullability: androidx.core.app.RemoteInput#getDataResultsFromIntent(android.content.Intent, String) parameter #1:
+    Missing nullability on parameter `remoteInputResultKey` in method `getDataResultsFromIntent`
+MissingNullability: androidx.core.app.RemoteInput#getExtras():
+    Missing nullability on method `getExtras` return
+MissingNullability: androidx.core.app.RemoteInput#getLabel():
+    Missing nullability on method `getLabel` return
+MissingNullability: androidx.core.app.RemoteInput#getResultKey():
+    Missing nullability on method `getResultKey` return
+MissingNullability: androidx.core.app.RemoteInput#getResultsFromIntent(android.content.Intent):
+    Missing nullability on method `getResultsFromIntent` return
+MissingNullability: androidx.core.app.RemoteInput#getResultsFromIntent(android.content.Intent) parameter #0:
+    Missing nullability on parameter `intent` in method `getResultsFromIntent`
+MissingNullability: androidx.core.app.SharedElementCallback#onCaptureSharedElementSnapshot(android.view.View, android.graphics.Matrix, android.graphics.RectF):
+    Missing nullability on method `onCaptureSharedElementSnapshot` return
+MissingNullability: androidx.core.app.SharedElementCallback#onCaptureSharedElementSnapshot(android.view.View, android.graphics.Matrix, android.graphics.RectF) parameter #0:
+    Missing nullability on parameter `sharedElement` in method `onCaptureSharedElementSnapshot`
+MissingNullability: androidx.core.app.SharedElementCallback#onCaptureSharedElementSnapshot(android.view.View, android.graphics.Matrix, android.graphics.RectF) parameter #1:
+    Missing nullability on parameter `viewToGlobalMatrix` in method `onCaptureSharedElementSnapshot`
+MissingNullability: androidx.core.app.SharedElementCallback#onCaptureSharedElementSnapshot(android.view.View, android.graphics.Matrix, android.graphics.RectF) parameter #2:
+    Missing nullability on parameter `screenBounds` in method `onCaptureSharedElementSnapshot`
+MissingNullability: androidx.core.app.SharedElementCallback#onCreateSnapshotView(android.content.Context, android.os.Parcelable):
+    Missing nullability on method `onCreateSnapshotView` return
+MissingNullability: androidx.core.app.SharedElementCallback#onCreateSnapshotView(android.content.Context, android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `context` in method `onCreateSnapshotView`
+MissingNullability: androidx.core.app.SharedElementCallback#onCreateSnapshotView(android.content.Context, android.os.Parcelable) parameter #1:
+    Missing nullability on parameter `snapshot` in method `onCreateSnapshotView`
+MissingNullability: androidx.core.app.SharedElementCallback#onMapSharedElements(java.util.List<java.lang.String>, java.util.Map<java.lang.String,android.view.View>) parameter #0:
+    Missing nullability on parameter `names` in method `onMapSharedElements`
+MissingNullability: androidx.core.app.SharedElementCallback#onMapSharedElements(java.util.List<java.lang.String>, java.util.Map<java.lang.String,android.view.View>) parameter #1:
+    Missing nullability on parameter `sharedElements` in method `onMapSharedElements`
+MissingNullability: androidx.core.app.SharedElementCallback#onRejectSharedElements(java.util.List<android.view.View>) parameter #0:
+    Missing nullability on parameter `rejectedSharedElements` in method `onRejectSharedElements`
+MissingNullability: androidx.core.app.SharedElementCallback#onSharedElementEnd(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>) parameter #0:
+    Missing nullability on parameter `sharedElementNames` in method `onSharedElementEnd`
+MissingNullability: androidx.core.app.SharedElementCallback#onSharedElementEnd(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>) parameter #1:
+    Missing nullability on parameter `sharedElements` in method `onSharedElementEnd`
+MissingNullability: androidx.core.app.SharedElementCallback#onSharedElementEnd(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>) parameter #2:
+    Missing nullability on parameter `sharedElementSnapshots` in method `onSharedElementEnd`
+MissingNullability: androidx.core.app.SharedElementCallback#onSharedElementStart(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>) parameter #0:
+    Missing nullability on parameter `sharedElementNames` in method `onSharedElementStart`
+MissingNullability: androidx.core.app.SharedElementCallback#onSharedElementStart(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>) parameter #1:
+    Missing nullability on parameter `sharedElements` in method `onSharedElementStart`
+MissingNullability: androidx.core.app.SharedElementCallback#onSharedElementStart(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>) parameter #2:
+    Missing nullability on parameter `sharedElementSnapshots` in method `onSharedElementStart`
+MissingNullability: androidx.core.app.SharedElementCallback#onSharedElementsArrived(java.util.List<java.lang.String>, java.util.List<android.view.View>, androidx.core.app.SharedElementCallback.OnSharedElementsReadyListener) parameter #0:
+    Missing nullability on parameter `sharedElementNames` in method `onSharedElementsArrived`
+MissingNullability: androidx.core.app.SharedElementCallback#onSharedElementsArrived(java.util.List<java.lang.String>, java.util.List<android.view.View>, androidx.core.app.SharedElementCallback.OnSharedElementsReadyListener) parameter #1:
+    Missing nullability on parameter `sharedElements` in method `onSharedElementsArrived`
+MissingNullability: androidx.core.app.SharedElementCallback#onSharedElementsArrived(java.util.List<java.lang.String>, java.util.List<android.view.View>, androidx.core.app.SharedElementCallback.OnSharedElementsReadyListener) parameter #2:
+    Missing nullability on parameter `listener` in method `onSharedElementsArrived`
+MissingNullability: androidx.core.app.TaskStackBuilder#addParentStack(android.content.ComponentName):
+    Missing nullability on method `addParentStack` return
+MissingNullability: androidx.core.app.TaskStackBuilder#addParentStack(android.content.ComponentName) parameter #0:
+    Missing nullability on parameter `sourceActivityName` in method `addParentStack`
+MissingNullability: androidx.core.app.TaskStackBuilder#from(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `from`
+MissingNullability: androidx.core.content.ContentResolverCompat#query(android.content.ContentResolver, android.net.Uri, String[], String, String[], String, androidx.core.os.CancellationSignal):
+    Missing nullability on method `query` return
+MissingNullability: androidx.core.content.ContentResolverCompat#query(android.content.ContentResolver, android.net.Uri, String[], String, String[], String, androidx.core.os.CancellationSignal) parameter #0:
+    Missing nullability on parameter `resolver` in method `query`
+MissingNullability: androidx.core.content.ContentResolverCompat#query(android.content.ContentResolver, android.net.Uri, String[], String, String[], String, androidx.core.os.CancellationSignal) parameter #1:
+    Missing nullability on parameter `uri` in method `query`
+MissingNullability: androidx.core.content.ContentResolverCompat#query(android.content.ContentResolver, android.net.Uri, String[], String, String[], String, androidx.core.os.CancellationSignal) parameter #2:
+    Missing nullability on parameter `projection` in method `query`
+MissingNullability: androidx.core.content.ContentResolverCompat#query(android.content.ContentResolver, android.net.Uri, String[], String, String[], String, androidx.core.os.CancellationSignal) parameter #3:
+    Missing nullability on parameter `selection` in method `query`
+MissingNullability: androidx.core.content.ContentResolverCompat#query(android.content.ContentResolver, android.net.Uri, String[], String, String[], String, androidx.core.os.CancellationSignal) parameter #4:
+    Missing nullability on parameter `selectionArgs` in method `query`
+MissingNullability: androidx.core.content.ContentResolverCompat#query(android.content.ContentResolver, android.net.Uri, String[], String, String[], String, androidx.core.os.CancellationSignal) parameter #5:
+    Missing nullability on parameter `sortOrder` in method `query`
+MissingNullability: androidx.core.content.ContentResolverCompat#query(android.content.ContentResolver, android.net.Uri, String[], String, String[], String, androidx.core.os.CancellationSignal) parameter #6:
+    Missing nullability on parameter `cancellationSignal` in method `query`
+MissingNullability: androidx.core.content.ContextCompat#getCodeCacheDir(android.content.Context):
+    Missing nullability on method `getCodeCacheDir` return
+MissingNullability: androidx.core.content.ContextCompat#getMainExecutor(android.content.Context):
+    Missing nullability on method `getMainExecutor` return
+MissingNullability: androidx.core.content.ContextCompat#getMainExecutor(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `getMainExecutor`
+MissingNullability: androidx.core.content.FileProvider#getType(android.net.Uri):
+    Missing nullability on method `getType` return
+MissingNullability: androidx.core.content.FileProvider#getUriForFile(android.content.Context, String, java.io.File):
+    Missing nullability on method `getUriForFile` return
+MissingNullability: androidx.core.content.FileProvider#insert(android.net.Uri, android.content.ContentValues):
+    Missing nullability on method `insert` return
+MissingNullability: androidx.core.content.FileProvider#insert(android.net.Uri, android.content.ContentValues) parameter #1:
+    Missing nullability on parameter `values` in method `insert`
+MissingNullability: androidx.core.content.FileProvider#openFile(android.net.Uri, String):
+    Missing nullability on method `openFile` return
+MissingNullability: androidx.core.content.FileProvider#query(android.net.Uri, String[], String, String[], String):
+    Missing nullability on method `query` return
+MissingNullability: androidx.core.content.FileProvider#update(android.net.Uri, android.content.ContentValues, String, String[]) parameter #1:
+    Missing nullability on parameter `values` in method `update`
+MissingNullability: androidx.core.content.pm.ShortcutInfoCompat#toShortcutInfo():
+    Missing nullability on method `toShortcutInfo` return
+MissingNullability: androidx.core.content.pm.ShortcutInfoCompat.Builder#setIcon(androidx.core.graphics.drawable.IconCompat) parameter #0:
+    Missing nullability on parameter `icon` in method `setIcon`
+MissingNullability: androidx.core.database.DatabaseUtilsCompat#appendSelectionArgs(String[], String[]) parameter #0:
+    Missing nullability on parameter `originalValues` in method `appendSelectionArgs`
+MissingNullability: androidx.core.database.DatabaseUtilsCompat#appendSelectionArgs(String[], String[]) parameter #1:
+    Missing nullability on parameter `newValues` in method `appendSelectionArgs`
+MissingNullability: androidx.core.database.DatabaseUtilsCompat#concatenateWhere(String, String) parameter #0:
+    Missing nullability on parameter `a` in method `concatenateWhere`
+MissingNullability: androidx.core.database.DatabaseUtilsCompat#concatenateWhere(String, String) parameter #1:
+    Missing nullability on parameter `b` in method `concatenateWhere`
+MissingNullability: androidx.core.graphics.Insets#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.core.graphics.Insets#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.core.graphics.PathSegment#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.core.graphics.PathSegment#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.core.graphics.drawable.DrawableCompat#getColorFilter(android.graphics.drawable.Drawable):
+    Missing nullability on method `getColorFilter` return
+MissingNullability: androidx.core.graphics.drawable.DrawableCompat#wrap(android.graphics.drawable.Drawable):
+    Missing nullability on method `wrap` return
+MissingNullability: androidx.core.graphics.drawable.IconCompat#createWithAdaptiveBitmap(android.graphics.Bitmap):
+    Missing nullability on method `createWithAdaptiveBitmap` return
+MissingNullability: androidx.core.graphics.drawable.IconCompat#createWithAdaptiveBitmap(android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `bits` in method `createWithAdaptiveBitmap`
+MissingNullability: androidx.core.graphics.drawable.IconCompat#createWithBitmap(android.graphics.Bitmap):
+    Missing nullability on method `createWithBitmap` return
+MissingNullability: androidx.core.graphics.drawable.IconCompat#createWithBitmap(android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `bits` in method `createWithBitmap`
+MissingNullability: androidx.core.graphics.drawable.IconCompat#createWithContentUri(String):
+    Missing nullability on method `createWithContentUri` return
+MissingNullability: androidx.core.graphics.drawable.IconCompat#createWithContentUri(String) parameter #0:
+    Missing nullability on parameter `uri` in method `createWithContentUri`
+MissingNullability: androidx.core.graphics.drawable.IconCompat#createWithContentUri(android.net.Uri):
+    Missing nullability on method `createWithContentUri` return
+MissingNullability: androidx.core.graphics.drawable.IconCompat#createWithContentUri(android.net.Uri) parameter #0:
+    Missing nullability on parameter `uri` in method `createWithContentUri`
+MissingNullability: androidx.core.graphics.drawable.IconCompat#createWithData(byte[], int, int):
+    Missing nullability on method `createWithData` return
+MissingNullability: androidx.core.graphics.drawable.IconCompat#createWithData(byte[], int, int) parameter #0:
+    Missing nullability on parameter `data` in method `createWithData`
+MissingNullability: androidx.core.graphics.drawable.IconCompat#createWithResource(android.content.Context, int):
+    Missing nullability on method `createWithResource` return
+MissingNullability: androidx.core.graphics.drawable.IconCompat#createWithResource(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `createWithResource`
+MissingNullability: androidx.core.graphics.drawable.IconCompat#loadDrawable(android.content.Context):
+    Missing nullability on method `loadDrawable` return
+MissingNullability: androidx.core.graphics.drawable.IconCompat#loadDrawable(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `loadDrawable`
+MissingNullability: androidx.core.graphics.drawable.IconCompat#setTint(int):
+    Missing nullability on method `setTint` return
+MissingNullability: androidx.core.graphics.drawable.IconCompat#setTintList(android.content.res.ColorStateList):
+    Missing nullability on method `setTintList` return
+MissingNullability: androidx.core.graphics.drawable.IconCompat#setTintList(android.content.res.ColorStateList) parameter #0:
+    Missing nullability on parameter `tintList` in method `setTintList`
+MissingNullability: androidx.core.graphics.drawable.IconCompat#setTintMode(android.graphics.PorterDuff.Mode):
+    Missing nullability on method `setTintMode` return
+MissingNullability: androidx.core.graphics.drawable.IconCompat#setTintMode(android.graphics.PorterDuff.Mode) parameter #0:
+    Missing nullability on parameter `mode` in method `setTintMode`
+MissingNullability: androidx.core.graphics.drawable.IconCompat#toBundle():
+    Missing nullability on method `toBundle` return
+MissingNullability: androidx.core.graphics.drawable.IconCompat#toIcon():
+    Missing nullability on method `toIcon` return
+MissingNullability: androidx.core.graphics.drawable.RoundedBitmapDrawable#getColorFilter():
+    Missing nullability on method `getColorFilter` return
+MissingNullability: androidx.core.graphics.drawable.RoundedBitmapDrawable#onBoundsChange(android.graphics.Rect) parameter #0:
+    Missing nullability on parameter `bounds` in method `onBoundsChange`
+MissingNullability: androidx.core.graphics.drawable.RoundedBitmapDrawable#setColorFilter(android.graphics.ColorFilter) parameter #0:
+    Missing nullability on parameter `cf` in method `setColorFilter`
+MissingNullability: androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationCallback#onAuthenticationError(int, CharSequence) parameter #1:
+    Missing nullability on parameter `errString` in method `onAuthenticationError`
+MissingNullability: androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationCallback#onAuthenticationHelp(int, CharSequence) parameter #1:
+    Missing nullability on parameter `helpString` in method `onAuthenticationHelp`
+MissingNullability: androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationCallback#onAuthenticationSucceeded(androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationResult) parameter #0:
+    Missing nullability on parameter `result` in method `onAuthenticationSucceeded`
+MissingNullability: androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationResult#AuthenticationResult(androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject) parameter #0:
+    Missing nullability on parameter `crypto` in method `AuthenticationResult`
+MissingNullability: androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationResult#getCryptoObject():
+    Missing nullability on method `getCryptoObject` return
+MissingNullability: androidx.core.net.TrafficStatsCompat#tagSocket(java.net.Socket) parameter #0:
+    Missing nullability on parameter `socket` in method `tagSocket`
+MissingNullability: androidx.core.net.TrafficStatsCompat#untagSocket(java.net.Socket) parameter #0:
+    Missing nullability on parameter `socket` in method `untagSocket`
+MissingNullability: androidx.core.os.EnvironmentCompat#getStorageState(java.io.File):
+    Missing nullability on method `getStorageState` return
+MissingNullability: androidx.core.os.LocaleListCompat#equals(Object) parameter #0:
+    Missing nullability on parameter `other` in method `equals`
+MissingNullability: androidx.core.os.LocaleListCompat#get(int):
+    Missing nullability on method `get` return
+MissingNullability: androidx.core.os.LocaleListCompat#indexOf(java.util.Locale) parameter #0:
+    Missing nullability on parameter `locale` in method `indexOf`
+MissingNullability: androidx.core.os.LocaleListCompat#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.core.os.LocaleListCompat#wrap(Object) parameter #0:
+    Missing nullability on parameter `localeList` in method `wrap`
+MissingNullability: androidx.core.os.ParcelableCompat#newCreator(androidx.core.os.ParcelableCompatCreatorCallbacks<T>) parameter #0:
+    Missing nullability on parameter `callbacks` in method `newCreator`
+MissingNullability: androidx.core.os.ParcelableCompatCreatorCallbacks#createFromParcel(android.os.Parcel, ClassLoader) parameter #0:
+    Missing nullability on parameter `in` in method `createFromParcel`
+MissingNullability: androidx.core.os.ParcelableCompatCreatorCallbacks#createFromParcel(android.os.Parcel, ClassLoader) parameter #1:
+    Missing nullability on parameter `loader` in method `createFromParcel`
+MissingNullability: androidx.core.provider.FontRequest#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.core.provider.FontsContractCompat.FontFamilyResult#getFonts():
+    Missing nullability on method `getFonts` return
+MissingNullability: androidx.core.provider.FontsContractCompat.FontRequestCallback#onTypefaceRetrieved(android.graphics.Typeface) parameter #0:
+    Missing nullability on parameter `typeface` in method `onTypefaceRetrieved`
+MissingNullability: androidx.core.text.BidiFormatter#getInstance():
+    Missing nullability on method `getInstance` return
+MissingNullability: androidx.core.text.BidiFormatter#getInstance(boolean):
+    Missing nullability on method `getInstance` return
+MissingNullability: androidx.core.text.BidiFormatter#getInstance(java.util.Locale):
+    Missing nullability on method `getInstance` return
+MissingNullability: androidx.core.text.BidiFormatter#getInstance(java.util.Locale) parameter #0:
+    Missing nullability on parameter `locale` in method `getInstance`
+MissingNullability: androidx.core.text.BidiFormatter#isRtl(CharSequence) parameter #0:
+    Missing nullability on parameter `str` in method `isRtl`
+MissingNullability: androidx.core.text.BidiFormatter#isRtl(String) parameter #0:
+    Missing nullability on parameter `str` in method `isRtl`
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(CharSequence):
+    Missing nullability on method `unicodeWrap` return
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(CharSequence) parameter #0:
+    Missing nullability on parameter `str` in method `unicodeWrap`
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(CharSequence, androidx.core.text.TextDirectionHeuristicCompat):
+    Missing nullability on method `unicodeWrap` return
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(CharSequence, androidx.core.text.TextDirectionHeuristicCompat) parameter #0:
+    Missing nullability on parameter `str` in method `unicodeWrap`
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(CharSequence, androidx.core.text.TextDirectionHeuristicCompat) parameter #1:
+    Missing nullability on parameter `heuristic` in method `unicodeWrap`
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(CharSequence, androidx.core.text.TextDirectionHeuristicCompat, boolean):
+    Missing nullability on method `unicodeWrap` return
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(CharSequence, androidx.core.text.TextDirectionHeuristicCompat, boolean) parameter #0:
+    Missing nullability on parameter `str` in method `unicodeWrap`
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(CharSequence, androidx.core.text.TextDirectionHeuristicCompat, boolean) parameter #1:
+    Missing nullability on parameter `heuristic` in method `unicodeWrap`
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(CharSequence, boolean):
+    Missing nullability on method `unicodeWrap` return
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(CharSequence, boolean) parameter #0:
+    Missing nullability on parameter `str` in method `unicodeWrap`
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(String):
+    Missing nullability on method `unicodeWrap` return
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(String) parameter #0:
+    Missing nullability on parameter `str` in method `unicodeWrap`
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(String, androidx.core.text.TextDirectionHeuristicCompat):
+    Missing nullability on method `unicodeWrap` return
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(String, androidx.core.text.TextDirectionHeuristicCompat) parameter #0:
+    Missing nullability on parameter `str` in method `unicodeWrap`
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(String, androidx.core.text.TextDirectionHeuristicCompat) parameter #1:
+    Missing nullability on parameter `heuristic` in method `unicodeWrap`
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(String, androidx.core.text.TextDirectionHeuristicCompat, boolean):
+    Missing nullability on method `unicodeWrap` return
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(String, androidx.core.text.TextDirectionHeuristicCompat, boolean) parameter #0:
+    Missing nullability on parameter `str` in method `unicodeWrap`
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(String, androidx.core.text.TextDirectionHeuristicCompat, boolean) parameter #1:
+    Missing nullability on parameter `heuristic` in method `unicodeWrap`
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(String, boolean):
+    Missing nullability on method `unicodeWrap` return
+MissingNullability: androidx.core.text.BidiFormatter#unicodeWrap(String, boolean) parameter #0:
+    Missing nullability on parameter `str` in method `unicodeWrap`
+MissingNullability: androidx.core.text.BidiFormatter.Builder#Builder(java.util.Locale) parameter #0:
+    Missing nullability on parameter `locale` in method `Builder`
+MissingNullability: androidx.core.text.BidiFormatter.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.core.text.BidiFormatter.Builder#setTextDirectionHeuristic(androidx.core.text.TextDirectionHeuristicCompat):
+    Missing nullability on method `setTextDirectionHeuristic` return
+MissingNullability: androidx.core.text.BidiFormatter.Builder#setTextDirectionHeuristic(androidx.core.text.TextDirectionHeuristicCompat) parameter #0:
+    Missing nullability on parameter `heuristic` in method `setTextDirectionHeuristic`
+MissingNullability: androidx.core.text.BidiFormatter.Builder#stereoReset(boolean):
+    Missing nullability on method `stereoReset` return
+MissingNullability: androidx.core.text.ICUCompat#maximizeAndGetScript(java.util.Locale) parameter #0:
+    Missing nullability on parameter `locale` in method `maximizeAndGetScript`
+MissingNullability: androidx.core.text.PrecomputedTextCompat#create(CharSequence, androidx.core.text.PrecomputedTextCompat.Params):
+    Missing nullability on method `create` return
+MissingNullability: androidx.core.text.PrecomputedTextCompat#getSpanEnd(Object) parameter #0:
+    Missing nullability on parameter `tag` in method `getSpanEnd`
+MissingNullability: androidx.core.text.PrecomputedTextCompat#getSpanFlags(Object) parameter #0:
+    Missing nullability on parameter `tag` in method `getSpanFlags`
+MissingNullability: androidx.core.text.PrecomputedTextCompat#getSpanStart(Object) parameter #0:
+    Missing nullability on parameter `tag` in method `getSpanStart`
+MissingNullability: androidx.core.text.PrecomputedTextCompat#getSpans(int, int, Class<T>) parameter #2:
+    Missing nullability on parameter `type` in method `getSpans`
+MissingNullability: androidx.core.text.PrecomputedTextCompat#getTextFuture(CharSequence, androidx.core.text.PrecomputedTextCompat.Params, java.util.concurrent.Executor):
+    Missing nullability on method `getTextFuture` return
+MissingNullability: androidx.core.text.PrecomputedTextCompat#nextSpanTransition(int, int, Class) parameter #2:
+    Missing nullability on parameter `type` in method `nextSpanTransition`
+MissingNullability: androidx.core.text.PrecomputedTextCompat#removeSpan(Object) parameter #0:
+    Missing nullability on parameter `what` in method `removeSpan`
+MissingNullability: androidx.core.text.PrecomputedTextCompat#setSpan(Object, int, int, int) parameter #0:
+    Missing nullability on parameter `what` in method `setSpan`
+MissingNullability: androidx.core.text.PrecomputedTextCompat#subSequence(int, int):
+    Missing nullability on method `subSequence` return
+MissingNullability: androidx.core.text.PrecomputedTextCompat.Params#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.core.text.PrecomputedTextCompat.Params.Builder#setBreakStrategy(int):
+    Missing nullability on method `setBreakStrategy` return
+MissingNullability: androidx.core.text.PrecomputedTextCompat.Params.Builder#setHyphenationFrequency(int):
+    Missing nullability on method `setHyphenationFrequency` return
+MissingNullability: androidx.core.text.PrecomputedTextCompat.Params.Builder#setTextDirection(android.text.TextDirectionHeuristic):
+    Missing nullability on method `setTextDirection` return
+MissingNullability: androidx.core.text.TextDirectionHeuristicCompat#isRtl(CharSequence, int, int) parameter #0:
+    Missing nullability on parameter `cs` in method `isRtl`
+MissingNullability: androidx.core.text.TextDirectionHeuristicCompat#isRtl(char[], int, int) parameter #0:
+    Missing nullability on parameter `array` in method `isRtl`
+MissingNullability: androidx.core.text.TextDirectionHeuristicsCompat#ANYRTL_LTR:
+    Missing nullability on field `ANYRTL_LTR` in class `class androidx.core.text.TextDirectionHeuristicsCompat`
+MissingNullability: androidx.core.text.TextDirectionHeuristicsCompat#FIRSTSTRONG_LTR:
+    Missing nullability on field `FIRSTSTRONG_LTR` in class `class androidx.core.text.TextDirectionHeuristicsCompat`
+MissingNullability: androidx.core.text.TextDirectionHeuristicsCompat#FIRSTSTRONG_RTL:
+    Missing nullability on field `FIRSTSTRONG_RTL` in class `class androidx.core.text.TextDirectionHeuristicsCompat`
+MissingNullability: androidx.core.text.TextDirectionHeuristicsCompat#LOCALE:
+    Missing nullability on field `LOCALE` in class `class androidx.core.text.TextDirectionHeuristicsCompat`
+MissingNullability: androidx.core.text.TextDirectionHeuristicsCompat#LTR:
+    Missing nullability on field `LTR` in class `class androidx.core.text.TextDirectionHeuristicsCompat`
+MissingNullability: androidx.core.text.TextDirectionHeuristicsCompat#RTL:
+    Missing nullability on field `RTL` in class `class androidx.core.text.TextDirectionHeuristicsCompat`
+MissingNullability: androidx.core.util.Pair#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.core.util.PatternsCompat#DOMAIN_NAME:
+    Missing nullability on field `DOMAIN_NAME` in class `class androidx.core.util.PatternsCompat`
+MissingNullability: androidx.core.util.PatternsCompat#EMAIL_ADDRESS:
+    Missing nullability on field `EMAIL_ADDRESS` in class `class androidx.core.util.PatternsCompat`
+MissingNullability: androidx.core.util.PatternsCompat#IP_ADDRESS:
+    Missing nullability on field `IP_ADDRESS` in class `class androidx.core.util.PatternsCompat`
+MissingNullability: androidx.core.util.PatternsCompat#WEB_URL:
+    Missing nullability on field `WEB_URL` in class `class androidx.core.util.PatternsCompat`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#dispatchPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `host` in method `dispatchPopulateAccessibilityEvent`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#dispatchPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #1:
+    Missing nullability on parameter `event` in method `dispatchPopulateAccessibilityEvent`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#getAccessibilityNodeProvider(android.view.View):
+    Missing nullability on method `getAccessibilityNodeProvider` return
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#getAccessibilityNodeProvider(android.view.View) parameter #0:
+    Missing nullability on parameter `host` in method `getAccessibilityNodeProvider`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `host` in method `onInitializeAccessibilityEvent`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onInitializeAccessibilityEvent`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #0:
+    Missing nullability on parameter `host` in method `onInitializeAccessibilityNodeInfo`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #1:
+    Missing nullability on parameter `info` in method `onInitializeAccessibilityNodeInfo`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `host` in method `onPopulateAccessibilityEvent`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onPopulateAccessibilityEvent`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `host` in method `onRequestSendAccessibilityEvent`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent) parameter #1:
+    Missing nullability on parameter `child` in method `onRequestSendAccessibilityEvent`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent) parameter #2:
+    Missing nullability on parameter `event` in method `onRequestSendAccessibilityEvent`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#performAccessibilityAction(android.view.View, int, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `host` in method `performAccessibilityAction`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#performAccessibilityAction(android.view.View, int, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `args` in method `performAccessibilityAction`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#sendAccessibilityEvent(android.view.View, int) parameter #0:
+    Missing nullability on parameter `host` in method `sendAccessibilityEvent`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#sendAccessibilityEventUnchecked(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `host` in method `sendAccessibilityEventUnchecked`
+MissingNullability: androidx.core.view.AccessibilityDelegateCompat#sendAccessibilityEventUnchecked(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #1:
+    Missing nullability on parameter `event` in method `sendAccessibilityEventUnchecked`
+MissingNullability: androidx.core.view.ActionProvider#ActionProvider(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `ActionProvider`
+MissingNullability: androidx.core.view.ActionProvider#getContext():
+    Missing nullability on method `getContext` return
+MissingNullability: androidx.core.view.ActionProvider#onCreateActionView():
+    Missing nullability on method `onCreateActionView` return
+MissingNullability: androidx.core.view.ActionProvider#onCreateActionView(android.view.MenuItem):
+    Missing nullability on method `onCreateActionView` return
+MissingNullability: androidx.core.view.ActionProvider#onCreateActionView(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `forItem` in method `onCreateActionView`
+MissingNullability: androidx.core.view.ActionProvider#onPrepareSubMenu(android.view.SubMenu) parameter #0:
+    Missing nullability on parameter `subMenu` in method `onPrepareSubMenu`
+MissingNullability: androidx.core.view.ActionProvider#setVisibilityListener(androidx.core.view.ActionProvider.VisibilityListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setVisibilityListener`
+MissingNullability: androidx.core.view.DisplayCutoutCompat#DisplayCutoutCompat(android.graphics.Rect, java.util.List<android.graphics.Rect>) parameter #0:
+    Missing nullability on parameter `safeInsets` in method `DisplayCutoutCompat`
+MissingNullability: androidx.core.view.DisplayCutoutCompat#DisplayCutoutCompat(android.graphics.Rect, java.util.List<android.graphics.Rect>) parameter #1:
+    Missing nullability on parameter `boundingRects` in method `DisplayCutoutCompat`
+MissingNullability: androidx.core.view.DisplayCutoutCompat#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.core.view.DisplayCutoutCompat#getBoundingRects():
+    Missing nullability on method `getBoundingRects` return
+MissingNullability: androidx.core.view.DisplayCutoutCompat#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.core.view.DragStartHelper#DragStartHelper(android.view.View, androidx.core.view.DragStartHelper.OnDragStartListener) parameter #0:
+    Missing nullability on parameter `view` in method `DragStartHelper`
+MissingNullability: androidx.core.view.DragStartHelper#DragStartHelper(android.view.View, androidx.core.view.DragStartHelper.OnDragStartListener) parameter #1:
+    Missing nullability on parameter `listener` in method `DragStartHelper`
+MissingNullability: androidx.core.view.DragStartHelper#getTouchPosition(android.graphics.Point) parameter #0:
+    Missing nullability on parameter `point` in method `getTouchPosition`
+MissingNullability: androidx.core.view.DragStartHelper#onLongClick(android.view.View) parameter #0:
+    Missing nullability on parameter `v` in method `onLongClick`
+MissingNullability: androidx.core.view.DragStartHelper#onTouch(android.view.View, android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `v` in method `onTouch`
+MissingNullability: androidx.core.view.DragStartHelper#onTouch(android.view.View, android.view.MotionEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onTouch`
+MissingNullability: androidx.core.view.DragStartHelper.OnDragStartListener#onDragStart(android.view.View, androidx.core.view.DragStartHelper) parameter #0:
+    Missing nullability on parameter `v` in method `onDragStart`
+MissingNullability: androidx.core.view.DragStartHelper.OnDragStartListener#onDragStart(android.view.View, androidx.core.view.DragStartHelper) parameter #1:
+    Missing nullability on parameter `helper` in method `onDragStart`
+MissingNullability: androidx.core.view.GestureDetectorCompat#GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener) parameter #0:
+    Missing nullability on parameter `context` in method `GestureDetectorCompat`
+MissingNullability: androidx.core.view.GestureDetectorCompat#GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener) parameter #1:
+    Missing nullability on parameter `listener` in method `GestureDetectorCompat`
+MissingNullability: androidx.core.view.GestureDetectorCompat#GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler) parameter #0:
+    Missing nullability on parameter `context` in method `GestureDetectorCompat`
+MissingNullability: androidx.core.view.GestureDetectorCompat#GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler) parameter #1:
+    Missing nullability on parameter `listener` in method `GestureDetectorCompat`
+MissingNullability: androidx.core.view.GestureDetectorCompat#GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler) parameter #2:
+    Missing nullability on parameter `handler` in method `GestureDetectorCompat`
+MissingNullability: androidx.core.view.GestureDetectorCompat#onTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `event` in method `onTouchEvent`
+MissingNullability: androidx.core.view.GestureDetectorCompat#setOnDoubleTapListener(android.view.GestureDetector.OnDoubleTapListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnDoubleTapListener`
+MissingNullability: androidx.core.view.GravityCompat#apply(int, int, int, android.graphics.Rect, android.graphics.Rect, int) parameter #3:
+    Missing nullability on parameter `container` in method `apply`
+MissingNullability: androidx.core.view.GravityCompat#apply(int, int, int, android.graphics.Rect, android.graphics.Rect, int) parameter #4:
+    Missing nullability on parameter `outRect` in method `apply`
+MissingNullability: androidx.core.view.GravityCompat#apply(int, int, int, android.graphics.Rect, int, int, android.graphics.Rect, int) parameter #3:
+    Missing nullability on parameter `container` in method `apply`
+MissingNullability: androidx.core.view.GravityCompat#apply(int, int, int, android.graphics.Rect, int, int, android.graphics.Rect, int) parameter #6:
+    Missing nullability on parameter `outRect` in method `apply`
+MissingNullability: androidx.core.view.GravityCompat#applyDisplay(int, android.graphics.Rect, android.graphics.Rect, int) parameter #1:
+    Missing nullability on parameter `display` in method `applyDisplay`
+MissingNullability: androidx.core.view.GravityCompat#applyDisplay(int, android.graphics.Rect, android.graphics.Rect, int) parameter #2:
+    Missing nullability on parameter `inoutObj` in method `applyDisplay`
+MissingNullability: androidx.core.view.LayoutInflaterCompat#getFactory(android.view.LayoutInflater) parameter #0:
+    Missing nullability on parameter `inflater` in method `getFactory`
+MissingNullability: androidx.core.view.LayoutInflaterFactory#onCreateView(android.view.View, String, android.content.Context, android.util.AttributeSet):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.core.view.LayoutInflaterFactory#onCreateView(android.view.View, String, android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `parent` in method `onCreateView`
+MissingNullability: androidx.core.view.LayoutInflaterFactory#onCreateView(android.view.View, String, android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `name` in method `onCreateView`
+MissingNullability: androidx.core.view.LayoutInflaterFactory#onCreateView(android.view.View, String, android.content.Context, android.util.AttributeSet) parameter #2:
+    Missing nullability on parameter `context` in method `onCreateView`
+MissingNullability: androidx.core.view.LayoutInflaterFactory#onCreateView(android.view.View, String, android.content.Context, android.util.AttributeSet) parameter #3:
+    Missing nullability on parameter `attrs` in method `onCreateView`
+MissingNullability: androidx.core.view.MarginLayoutParamsCompat#getLayoutDirection(android.view.ViewGroup.MarginLayoutParams) parameter #0:
+    Missing nullability on parameter `lp` in method `getLayoutDirection`
+MissingNullability: androidx.core.view.MarginLayoutParamsCompat#getMarginEnd(android.view.ViewGroup.MarginLayoutParams) parameter #0:
+    Missing nullability on parameter `lp` in method `getMarginEnd`
+MissingNullability: androidx.core.view.MarginLayoutParamsCompat#getMarginStart(android.view.ViewGroup.MarginLayoutParams) parameter #0:
+    Missing nullability on parameter `lp` in method `getMarginStart`
+MissingNullability: androidx.core.view.MarginLayoutParamsCompat#isMarginRelative(android.view.ViewGroup.MarginLayoutParams) parameter #0:
+    Missing nullability on parameter `lp` in method `isMarginRelative`
+MissingNullability: androidx.core.view.MarginLayoutParamsCompat#resolveLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int) parameter #0:
+    Missing nullability on parameter `lp` in method `resolveLayoutDirection`
+MissingNullability: androidx.core.view.MarginLayoutParamsCompat#setLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int) parameter #0:
+    Missing nullability on parameter `lp` in method `setLayoutDirection`
+MissingNullability: androidx.core.view.MarginLayoutParamsCompat#setMarginEnd(android.view.ViewGroup.MarginLayoutParams, int) parameter #0:
+    Missing nullability on parameter `lp` in method `setMarginEnd`
+MissingNullability: androidx.core.view.MarginLayoutParamsCompat#setMarginStart(android.view.ViewGroup.MarginLayoutParams, int) parameter #0:
+    Missing nullability on parameter `lp` in method `setMarginStart`
+MissingNullability: androidx.core.view.MenuCompat#setGroupDividerEnabled(android.view.Menu, boolean) parameter #0:
+    Missing nullability on parameter `menu` in method `setGroupDividerEnabled`
+MissingNullability: androidx.core.view.MenuCompat#setShowAsAction(android.view.MenuItem, int) parameter #0:
+    Missing nullability on parameter `item` in method `setShowAsAction`
+MissingNullability: androidx.core.view.MenuItemCompat#collapseActionView(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `collapseActionView`
+MissingNullability: androidx.core.view.MenuItemCompat#expandActionView(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `expandActionView`
+MissingNullability: androidx.core.view.MenuItemCompat#getActionProvider(android.view.MenuItem):
+    Missing nullability on method `getActionProvider` return
+MissingNullability: androidx.core.view.MenuItemCompat#getActionProvider(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `getActionProvider`
+MissingNullability: androidx.core.view.MenuItemCompat#getActionView(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `getActionView`
+MissingNullability: androidx.core.view.MenuItemCompat#getAlphabeticModifiers(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `getAlphabeticModifiers`
+MissingNullability: androidx.core.view.MenuItemCompat#getContentDescription(android.view.MenuItem):
+    Missing nullability on method `getContentDescription` return
+MissingNullability: androidx.core.view.MenuItemCompat#getContentDescription(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `getContentDescription`
+MissingNullability: androidx.core.view.MenuItemCompat#getIconTintList(android.view.MenuItem):
+    Missing nullability on method `getIconTintList` return
+MissingNullability: androidx.core.view.MenuItemCompat#getIconTintList(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `getIconTintList`
+MissingNullability: androidx.core.view.MenuItemCompat#getIconTintMode(android.view.MenuItem):
+    Missing nullability on method `getIconTintMode` return
+MissingNullability: androidx.core.view.MenuItemCompat#getIconTintMode(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `getIconTintMode`
+MissingNullability: androidx.core.view.MenuItemCompat#getNumericModifiers(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `getNumericModifiers`
+MissingNullability: androidx.core.view.MenuItemCompat#getTooltipText(android.view.MenuItem):
+    Missing nullability on method `getTooltipText` return
+MissingNullability: androidx.core.view.MenuItemCompat#getTooltipText(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `getTooltipText`
+MissingNullability: androidx.core.view.MenuItemCompat#isActionViewExpanded(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `isActionViewExpanded`
+MissingNullability: androidx.core.view.MenuItemCompat#setActionProvider(android.view.MenuItem, androidx.core.view.ActionProvider):
+    Missing nullability on method `setActionProvider` return
+MissingNullability: androidx.core.view.MenuItemCompat#setActionProvider(android.view.MenuItem, androidx.core.view.ActionProvider) parameter #0:
+    Missing nullability on parameter `item` in method `setActionProvider`
+MissingNullability: androidx.core.view.MenuItemCompat#setActionProvider(android.view.MenuItem, androidx.core.view.ActionProvider) parameter #1:
+    Missing nullability on parameter `provider` in method `setActionProvider`
+MissingNullability: androidx.core.view.MenuItemCompat#setActionView(android.view.MenuItem, android.view.View) parameter #0:
+    Missing nullability on parameter `item` in method `setActionView`
+MissingNullability: androidx.core.view.MenuItemCompat#setActionView(android.view.MenuItem, android.view.View) parameter #1:
+    Missing nullability on parameter `view` in method `setActionView`
+MissingNullability: androidx.core.view.MenuItemCompat#setActionView(android.view.MenuItem, int) parameter #0:
+    Missing nullability on parameter `item` in method `setActionView`
+MissingNullability: androidx.core.view.MenuItemCompat#setAlphabeticShortcut(android.view.MenuItem, char, int) parameter #0:
+    Missing nullability on parameter `item` in method `setAlphabeticShortcut`
+MissingNullability: androidx.core.view.MenuItemCompat#setContentDescription(android.view.MenuItem, CharSequence) parameter #0:
+    Missing nullability on parameter `item` in method `setContentDescription`
+MissingNullability: androidx.core.view.MenuItemCompat#setContentDescription(android.view.MenuItem, CharSequence) parameter #1:
+    Missing nullability on parameter `contentDescription` in method `setContentDescription`
+MissingNullability: androidx.core.view.MenuItemCompat#setIconTintList(android.view.MenuItem, android.content.res.ColorStateList) parameter #0:
+    Missing nullability on parameter `item` in method `setIconTintList`
+MissingNullability: androidx.core.view.MenuItemCompat#setIconTintList(android.view.MenuItem, android.content.res.ColorStateList) parameter #1:
+    Missing nullability on parameter `tint` in method `setIconTintList`
+MissingNullability: androidx.core.view.MenuItemCompat#setIconTintMode(android.view.MenuItem, android.graphics.PorterDuff.Mode) parameter #0:
+    Missing nullability on parameter `item` in method `setIconTintMode`
+MissingNullability: androidx.core.view.MenuItemCompat#setIconTintMode(android.view.MenuItem, android.graphics.PorterDuff.Mode) parameter #1:
+    Missing nullability on parameter `tintMode` in method `setIconTintMode`
+MissingNullability: androidx.core.view.MenuItemCompat#setNumericShortcut(android.view.MenuItem, char, int) parameter #0:
+    Missing nullability on parameter `item` in method `setNumericShortcut`
+MissingNullability: androidx.core.view.MenuItemCompat#setOnActionExpandListener(android.view.MenuItem, androidx.core.view.MenuItemCompat.OnActionExpandListener) parameter #0:
+    Missing nullability on parameter `item` in method `setOnActionExpandListener`
+MissingNullability: androidx.core.view.MenuItemCompat#setOnActionExpandListener(android.view.MenuItem, androidx.core.view.MenuItemCompat.OnActionExpandListener) parameter #1:
+    Missing nullability on parameter `listener` in method `setOnActionExpandListener`
+MissingNullability: androidx.core.view.MenuItemCompat#setShortcut(android.view.MenuItem, char, char, int, int) parameter #0:
+    Missing nullability on parameter `item` in method `setShortcut`
+MissingNullability: androidx.core.view.MenuItemCompat#setShowAsAction(android.view.MenuItem, int) parameter #0:
+    Missing nullability on parameter `item` in method `setShowAsAction`
+MissingNullability: androidx.core.view.MenuItemCompat#setTooltipText(android.view.MenuItem, CharSequence) parameter #0:
+    Missing nullability on parameter `item` in method `setTooltipText`
+MissingNullability: androidx.core.view.MenuItemCompat#setTooltipText(android.view.MenuItem, CharSequence) parameter #1:
+    Missing nullability on parameter `tooltipText` in method `setTooltipText`
+MissingNullability: androidx.core.view.MenuItemCompat.OnActionExpandListener#onMenuItemActionCollapse(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `onMenuItemActionCollapse`
+MissingNullability: androidx.core.view.MenuItemCompat.OnActionExpandListener#onMenuItemActionExpand(android.view.MenuItem) parameter #0:
+    Missing nullability on parameter `item` in method `onMenuItemActionExpand`
+MissingNullability: androidx.core.view.MotionEventCompat#findPointerIndex(android.view.MotionEvent, int) parameter #0:
+    Missing nullability on parameter `event` in method `findPointerIndex`
+MissingNullability: androidx.core.view.MotionEventCompat#getActionIndex(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `event` in method `getActionIndex`
+MissingNullability: androidx.core.view.MotionEventCompat#getActionMasked(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `event` in method `getActionMasked`
+MissingNullability: androidx.core.view.MotionEventCompat#getAxisValue(android.view.MotionEvent, int) parameter #0:
+    Missing nullability on parameter `event` in method `getAxisValue`
+MissingNullability: androidx.core.view.MotionEventCompat#getAxisValue(android.view.MotionEvent, int, int) parameter #0:
+    Missing nullability on parameter `event` in method `getAxisValue`
+MissingNullability: androidx.core.view.MotionEventCompat#getButtonState(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `event` in method `getButtonState`
+MissingNullability: androidx.core.view.MotionEventCompat#getPointerCount(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `event` in method `getPointerCount`
+MissingNullability: androidx.core.view.MotionEventCompat#getPointerId(android.view.MotionEvent, int) parameter #0:
+    Missing nullability on parameter `event` in method `getPointerId`
+MissingNullability: androidx.core.view.MotionEventCompat#getSource(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `event` in method `getSource`
+MissingNullability: androidx.core.view.MotionEventCompat#getX(android.view.MotionEvent, int) parameter #0:
+    Missing nullability on parameter `event` in method `getX`
+MissingNullability: androidx.core.view.MotionEventCompat#getY(android.view.MotionEvent, int) parameter #0:
+    Missing nullability on parameter `event` in method `getY`
+MissingNullability: androidx.core.view.MotionEventCompat#isFromSource(android.view.MotionEvent, int) parameter #0:
+    Missing nullability on parameter `event` in method `isFromSource`
+MissingNullability: androidx.core.view.OnApplyWindowInsetsListener#onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat):
+    Missing nullability on method `onApplyWindowInsets` return
+MissingNullability: androidx.core.view.OnApplyWindowInsetsListener#onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat) parameter #0:
+    Missing nullability on parameter `v` in method `onApplyWindowInsets`
+MissingNullability: androidx.core.view.OnApplyWindowInsetsListener#onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat) parameter #1:
+    Missing nullability on parameter `insets` in method `onApplyWindowInsets`
+MissingNullability: androidx.core.view.OneShotPreDrawListener#onViewAttachedToWindow(android.view.View) parameter #0:
+    Missing nullability on parameter `v` in method `onViewAttachedToWindow`
+MissingNullability: androidx.core.view.OneShotPreDrawListener#onViewDetachedFromWindow(android.view.View) parameter #0:
+    Missing nullability on parameter `v` in method `onViewDetachedFromWindow`
+MissingNullability: androidx.core.view.PointerIconCompat#create(android.graphics.Bitmap, float, float):
+    Missing nullability on method `create` return
+MissingNullability: androidx.core.view.PointerIconCompat#create(android.graphics.Bitmap, float, float) parameter #0:
+    Missing nullability on parameter `bitmap` in method `create`
+MissingNullability: androidx.core.view.PointerIconCompat#getSystemIcon(android.content.Context, int):
+    Missing nullability on method `getSystemIcon` return
+MissingNullability: androidx.core.view.PointerIconCompat#getSystemIcon(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `getSystemIcon`
+MissingNullability: androidx.core.view.PointerIconCompat#load(android.content.res.Resources, int):
+    Missing nullability on method `load` return
+MissingNullability: androidx.core.view.PointerIconCompat#load(android.content.res.Resources, int) parameter #0:
+    Missing nullability on parameter `resources` in method `load`
+MissingNullability: androidx.core.view.ScaleGestureDetectorCompat#isQuickScaleEnabled(Object) parameter #0:
+    Missing nullability on parameter `scaleGestureDetector` in method `isQuickScaleEnabled`
+MissingNullability: androidx.core.view.ScaleGestureDetectorCompat#isQuickScaleEnabled(android.view.ScaleGestureDetector) parameter #0:
+    Missing nullability on parameter `scaleGestureDetector` in method `isQuickScaleEnabled`
+MissingNullability: androidx.core.view.ScaleGestureDetectorCompat#setQuickScaleEnabled(Object, boolean) parameter #0:
+    Missing nullability on parameter `scaleGestureDetector` in method `setQuickScaleEnabled`
+MissingNullability: androidx.core.view.ScaleGestureDetectorCompat#setQuickScaleEnabled(android.view.ScaleGestureDetector, boolean) parameter #0:
+    Missing nullability on parameter `scaleGestureDetector` in method `setQuickScaleEnabled`
+MissingNullability: androidx.core.view.VelocityTrackerCompat#getXVelocity(android.view.VelocityTracker, int) parameter #0:
+    Missing nullability on parameter `tracker` in method `getXVelocity`
+MissingNullability: androidx.core.view.VelocityTrackerCompat#getYVelocity(android.view.VelocityTracker, int) parameter #0:
+    Missing nullability on parameter `tracker` in method `getYVelocity`
+MissingNullability: androidx.core.view.ViewCompat#canScrollHorizontally(android.view.View, int) parameter #0:
+    Missing nullability on parameter `view` in method `canScrollHorizontally`
+MissingNullability: androidx.core.view.ViewCompat#canScrollVertically(android.view.View, int) parameter #0:
+    Missing nullability on parameter `view` in method `canScrollVertically`
+MissingNullability: androidx.core.view.ViewCompat#dispatchApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat):
+    Missing nullability on method `dispatchApplyWindowInsets` return
+MissingNullability: androidx.core.view.ViewCompat#dispatchApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat) parameter #1:
+    Missing nullability on parameter `insets` in method `dispatchApplyWindowInsets`
+MissingNullability: androidx.core.view.ViewCompat#enableAccessibleClickableSpanSupport(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `enableAccessibleClickableSpanSupport`
+MissingNullability: androidx.core.view.ViewCompat#getAccessibilityNodeProvider(android.view.View):
+    Missing nullability on method `getAccessibilityNodeProvider` return
+MissingNullability: androidx.core.view.ViewCompat#getAccessibilityPaneTitle(android.view.View):
+    Missing nullability on method `getAccessibilityPaneTitle` return
+MissingNullability: androidx.core.view.ViewCompat#getAccessibilityPaneTitle(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getAccessibilityPaneTitle`
+MissingNullability: androidx.core.view.ViewCompat#getAlpha(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getAlpha`
+MissingNullability: androidx.core.view.ViewCompat#getBackgroundTintList(android.view.View):
+    Missing nullability on method `getBackgroundTintList` return
+MissingNullability: androidx.core.view.ViewCompat#getBackgroundTintMode(android.view.View):
+    Missing nullability on method `getBackgroundTintMode` return
+MissingNullability: androidx.core.view.ViewCompat#getLayerType(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getLayerType`
+MissingNullability: androidx.core.view.ViewCompat#getMatrix(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getMatrix`
+MissingNullability: androidx.core.view.ViewCompat#getMeasuredHeightAndState(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getMeasuredHeightAndState`
+MissingNullability: androidx.core.view.ViewCompat#getMeasuredState(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getMeasuredState`
+MissingNullability: androidx.core.view.ViewCompat#getMeasuredWidthAndState(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getMeasuredWidthAndState`
+MissingNullability: androidx.core.view.ViewCompat#getOverScrollMode(android.view.View) parameter #0:
+    Missing nullability on parameter `v` in method `getOverScrollMode`
+MissingNullability: androidx.core.view.ViewCompat#getParentForAccessibility(android.view.View):
+    Missing nullability on method `getParentForAccessibility` return
+MissingNullability: androidx.core.view.ViewCompat#getPivotX(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getPivotX`
+MissingNullability: androidx.core.view.ViewCompat#getPivotY(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getPivotY`
+MissingNullability: androidx.core.view.ViewCompat#getRotation(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getRotation`
+MissingNullability: androidx.core.view.ViewCompat#getRotationX(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getRotationX`
+MissingNullability: androidx.core.view.ViewCompat#getRotationY(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getRotationY`
+MissingNullability: androidx.core.view.ViewCompat#getScaleX(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getScaleX`
+MissingNullability: androidx.core.view.ViewCompat#getScaleY(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getScaleY`
+MissingNullability: androidx.core.view.ViewCompat#getTranslationX(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getTranslationX`
+MissingNullability: androidx.core.view.ViewCompat#getTranslationY(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getTranslationY`
+MissingNullability: androidx.core.view.ViewCompat#getX(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getX`
+MissingNullability: androidx.core.view.ViewCompat#getY(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getY`
+MissingNullability: androidx.core.view.ViewCompat#isAccessibilityHeading(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `isAccessibilityHeading`
+MissingNullability: androidx.core.view.ViewCompat#isOpaque(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `isOpaque`
+MissingNullability: androidx.core.view.ViewCompat#isScreenReaderFocusable(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `isScreenReaderFocusable`
+MissingNullability: androidx.core.view.ViewCompat#jumpDrawablesToCurrentState(android.view.View) parameter #0:
+    Missing nullability on parameter `v` in method `jumpDrawablesToCurrentState`
+MissingNullability: androidx.core.view.ViewCompat#keyboardNavigationClusterSearch(android.view.View, android.view.View, int):
+    Missing nullability on method `keyboardNavigationClusterSearch` return
+MissingNullability: androidx.core.view.ViewCompat#keyboardNavigationClusterSearch(android.view.View, android.view.View, int) parameter #1:
+    Missing nullability on parameter `currentCluster` in method `keyboardNavigationClusterSearch`
+MissingNullability: androidx.core.view.ViewCompat#onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat):
+    Missing nullability on method `onApplyWindowInsets` return
+MissingNullability: androidx.core.view.ViewCompat#onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat) parameter #1:
+    Missing nullability on parameter `insets` in method `onApplyWindowInsets`
+MissingNullability: androidx.core.view.ViewCompat#onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `v` in method `onInitializeAccessibilityEvent`
+MissingNullability: androidx.core.view.ViewCompat#onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onInitializeAccessibilityEvent`
+MissingNullability: androidx.core.view.ViewCompat#onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #1:
+    Missing nullability on parameter `info` in method `onInitializeAccessibilityNodeInfo`
+MissingNullability: androidx.core.view.ViewCompat#onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `v` in method `onPopulateAccessibilityEvent`
+MissingNullability: androidx.core.view.ViewCompat#onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onPopulateAccessibilityEvent`
+MissingNullability: androidx.core.view.ViewCompat#performAccessibilityAction(android.view.View, int, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `arguments` in method `performAccessibilityAction`
+MissingNullability: androidx.core.view.ViewCompat#postOnAnimation(android.view.View, Runnable) parameter #1:
+    Missing nullability on parameter `action` in method `postOnAnimation`
+MissingNullability: androidx.core.view.ViewCompat#postOnAnimationDelayed(android.view.View, Runnable, long) parameter #1:
+    Missing nullability on parameter `action` in method `postOnAnimationDelayed`
+MissingNullability: androidx.core.view.ViewCompat#setAccessibilityDelegate(android.view.View, androidx.core.view.AccessibilityDelegateCompat) parameter #1:
+    Missing nullability on parameter `delegate` in method `setAccessibilityDelegate`
+MissingNullability: androidx.core.view.ViewCompat#setAccessibilityHeading(android.view.View, boolean) parameter #0:
+    Missing nullability on parameter `view` in method `setAccessibilityHeading`
+MissingNullability: androidx.core.view.ViewCompat#setAccessibilityPaneTitle(android.view.View, CharSequence) parameter #0:
+    Missing nullability on parameter `view` in method `setAccessibilityPaneTitle`
+MissingNullability: androidx.core.view.ViewCompat#setAccessibilityPaneTitle(android.view.View, CharSequence) parameter #1:
+    Missing nullability on parameter `accessibilityPaneTitle` in method `setAccessibilityPaneTitle`
+MissingNullability: androidx.core.view.ViewCompat#setActivated(android.view.View, boolean) parameter #0:
+    Missing nullability on parameter `view` in method `setActivated`
+MissingNullability: androidx.core.view.ViewCompat#setAlpha(android.view.View, float) parameter #0:
+    Missing nullability on parameter `view` in method `setAlpha`
+MissingNullability: androidx.core.view.ViewCompat#setBackgroundTintList(android.view.View, android.content.res.ColorStateList) parameter #1:
+    Missing nullability on parameter `tintList` in method `setBackgroundTintList`
+MissingNullability: androidx.core.view.ViewCompat#setBackgroundTintMode(android.view.View, android.graphics.PorterDuff.Mode) parameter #1:
+    Missing nullability on parameter `mode` in method `setBackgroundTintMode`
+MissingNullability: androidx.core.view.ViewCompat#setChildrenDrawingOrderEnabled(android.view.ViewGroup, boolean) parameter #0:
+    Missing nullability on parameter `viewGroup` in method `setChildrenDrawingOrderEnabled`
+MissingNullability: androidx.core.view.ViewCompat#setClipBounds(android.view.View, android.graphics.Rect) parameter #1:
+    Missing nullability on parameter `clipBounds` in method `setClipBounds`
+MissingNullability: androidx.core.view.ViewCompat#setFitsSystemWindows(android.view.View, boolean) parameter #0:
+    Missing nullability on parameter `view` in method `setFitsSystemWindows`
+MissingNullability: androidx.core.view.ViewCompat#setLayerPaint(android.view.View, android.graphics.Paint) parameter #1:
+    Missing nullability on parameter `paint` in method `setLayerPaint`
+MissingNullability: androidx.core.view.ViewCompat#setLayerType(android.view.View, int, android.graphics.Paint) parameter #0:
+    Missing nullability on parameter `view` in method `setLayerType`
+MissingNullability: androidx.core.view.ViewCompat#setLayerType(android.view.View, int, android.graphics.Paint) parameter #2:
+    Missing nullability on parameter `paint` in method `setLayerType`
+MissingNullability: androidx.core.view.ViewCompat#setOnApplyWindowInsetsListener(android.view.View, androidx.core.view.OnApplyWindowInsetsListener) parameter #1:
+    Missing nullability on parameter `listener` in method `setOnApplyWindowInsetsListener`
+MissingNullability: androidx.core.view.ViewCompat#setOverScrollMode(android.view.View, int) parameter #0:
+    Missing nullability on parameter `v` in method `setOverScrollMode`
+MissingNullability: androidx.core.view.ViewCompat#setPivotX(android.view.View, float) parameter #0:
+    Missing nullability on parameter `view` in method `setPivotX`
+MissingNullability: androidx.core.view.ViewCompat#setPivotY(android.view.View, float) parameter #0:
+    Missing nullability on parameter `view` in method `setPivotY`
+MissingNullability: androidx.core.view.ViewCompat#setPointerIcon(android.view.View, androidx.core.view.PointerIconCompat) parameter #1:
+    Missing nullability on parameter `pointerIcon` in method `setPointerIcon`
+MissingNullability: androidx.core.view.ViewCompat#setRotation(android.view.View, float) parameter #0:
+    Missing nullability on parameter `view` in method `setRotation`
+MissingNullability: androidx.core.view.ViewCompat#setRotationX(android.view.View, float) parameter #0:
+    Missing nullability on parameter `view` in method `setRotationX`
+MissingNullability: androidx.core.view.ViewCompat#setRotationY(android.view.View, float) parameter #0:
+    Missing nullability on parameter `view` in method `setRotationY`
+MissingNullability: androidx.core.view.ViewCompat#setSaveFromParentEnabled(android.view.View, boolean) parameter #0:
+    Missing nullability on parameter `v` in method `setSaveFromParentEnabled`
+MissingNullability: androidx.core.view.ViewCompat#setScaleX(android.view.View, float) parameter #0:
+    Missing nullability on parameter `view` in method `setScaleX`
+MissingNullability: androidx.core.view.ViewCompat#setScaleY(android.view.View, float) parameter #0:
+    Missing nullability on parameter `view` in method `setScaleY`
+MissingNullability: androidx.core.view.ViewCompat#setScreenReaderFocusable(android.view.View, boolean) parameter #0:
+    Missing nullability on parameter `view` in method `setScreenReaderFocusable`
+MissingNullability: androidx.core.view.ViewCompat#setTransitionName(android.view.View, String) parameter #1:
+    Missing nullability on parameter `transitionName` in method `setTransitionName`
+MissingNullability: androidx.core.view.ViewCompat#setTranslationX(android.view.View, float) parameter #0:
+    Missing nullability on parameter `view` in method `setTranslationX`
+MissingNullability: androidx.core.view.ViewCompat#setTranslationY(android.view.View, float) parameter #0:
+    Missing nullability on parameter `view` in method `setTranslationY`
+MissingNullability: androidx.core.view.ViewCompat#setX(android.view.View, float) parameter #0:
+    Missing nullability on parameter `view` in method `setX`
+MissingNullability: androidx.core.view.ViewCompat#setY(android.view.View, float) parameter #0:
+    Missing nullability on parameter `view` in method `setY`
+MissingNullability: androidx.core.view.ViewCompat#startDragAndDrop(android.view.View, android.content.ClipData, android.view.View.DragShadowBuilder, Object, int) parameter #1:
+    Missing nullability on parameter `data` in method `startDragAndDrop`
+MissingNullability: androidx.core.view.ViewCompat#startDragAndDrop(android.view.View, android.content.ClipData, android.view.View.DragShadowBuilder, Object, int) parameter #2:
+    Missing nullability on parameter `shadowBuilder` in method `startDragAndDrop`
+MissingNullability: androidx.core.view.ViewCompat#startDragAndDrop(android.view.View, android.content.ClipData, android.view.View.DragShadowBuilder, Object, int) parameter #3:
+    Missing nullability on parameter `localState` in method `startDragAndDrop`
+MissingNullability: androidx.core.view.ViewCompat#updateDragShadow(android.view.View, android.view.View.DragShadowBuilder) parameter #1:
+    Missing nullability on parameter `shadowBuilder` in method `updateDragShadow`
+MissingNullability: androidx.core.view.ViewCompat.OnUnhandledKeyEventListenerCompat#onUnhandledKeyEvent(android.view.View, android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `v` in method `onUnhandledKeyEvent`
+MissingNullability: androidx.core.view.ViewCompat.OnUnhandledKeyEventListenerCompat#onUnhandledKeyEvent(android.view.View, android.view.KeyEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onUnhandledKeyEvent`
+MissingNullability: androidx.core.view.ViewConfigurationCompat#getScaledHoverSlop(android.view.ViewConfiguration) parameter #0:
+    Missing nullability on parameter `config` in method `getScaledHoverSlop`
+MissingNullability: androidx.core.view.ViewConfigurationCompat#getScaledPagingTouchSlop(android.view.ViewConfiguration) parameter #0:
+    Missing nullability on parameter `config` in method `getScaledPagingTouchSlop`
+MissingNullability: androidx.core.view.ViewConfigurationCompat#hasPermanentMenuKey(android.view.ViewConfiguration) parameter #0:
+    Missing nullability on parameter `config` in method `hasPermanentMenuKey`
+MissingNullability: androidx.core.view.ViewConfigurationCompat#shouldShowMenuShortcutsWhenKeyboardPresent(android.view.ViewConfiguration, android.content.Context) parameter #0:
+    Missing nullability on parameter `config` in method `shouldShowMenuShortcutsWhenKeyboardPresent`
+MissingNullability: androidx.core.view.ViewGroupCompat#onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `group` in method `onRequestSendAccessibilityEvent`
+MissingNullability: androidx.core.view.ViewGroupCompat#onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent) parameter #1:
+    Missing nullability on parameter `child` in method `onRequestSendAccessibilityEvent`
+MissingNullability: androidx.core.view.ViewGroupCompat#onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent) parameter #2:
+    Missing nullability on parameter `event` in method `onRequestSendAccessibilityEvent`
+MissingNullability: androidx.core.view.ViewGroupCompat#setMotionEventSplittingEnabled(android.view.ViewGroup, boolean) parameter #0:
+    Missing nullability on parameter `group` in method `setMotionEventSplittingEnabled`
+MissingNullability: androidx.core.view.ViewParentCompat#notifySubtreeAccessibilityStateChanged(android.view.ViewParent, android.view.View, android.view.View, int) parameter #0:
+    Missing nullability on parameter `parent` in method `notifySubtreeAccessibilityStateChanged`
+MissingNullability: androidx.core.view.ViewParentCompat#notifySubtreeAccessibilityStateChanged(android.view.ViewParent, android.view.View, android.view.View, int) parameter #1:
+    Missing nullability on parameter `child` in method `notifySubtreeAccessibilityStateChanged`
+MissingNullability: androidx.core.view.ViewParentCompat#notifySubtreeAccessibilityStateChanged(android.view.ViewParent, android.view.View, android.view.View, int) parameter #2:
+    Missing nullability on parameter `source` in method `notifySubtreeAccessibilityStateChanged`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedFling(android.view.ViewParent, android.view.View, float, float, boolean) parameter #0:
+    Missing nullability on parameter `parent` in method `onNestedFling`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedFling(android.view.ViewParent, android.view.View, float, float, boolean) parameter #1:
+    Missing nullability on parameter `target` in method `onNestedFling`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedPreFling(android.view.ViewParent, android.view.View, float, float) parameter #0:
+    Missing nullability on parameter `parent` in method `onNestedPreFling`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedPreFling(android.view.ViewParent, android.view.View, float, float) parameter #1:
+    Missing nullability on parameter `target` in method `onNestedPreFling`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[]) parameter #0:
+    Missing nullability on parameter `parent` in method `onNestedPreScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[]) parameter #1:
+    Missing nullability on parameter `target` in method `onNestedPreScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[]) parameter #4:
+    Missing nullability on parameter `consumed` in method `onNestedPreScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[], int) parameter #0:
+    Missing nullability on parameter `parent` in method `onNestedPreScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[], int) parameter #1:
+    Missing nullability on parameter `target` in method `onNestedPreScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[], int) parameter #4:
+    Missing nullability on parameter `consumed` in method `onNestedPreScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int) parameter #0:
+    Missing nullability on parameter `parent` in method `onNestedScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int) parameter #1:
+    Missing nullability on parameter `target` in method `onNestedScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int, int) parameter #0:
+    Missing nullability on parameter `parent` in method `onNestedScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int, int) parameter #1:
+    Missing nullability on parameter `target` in method `onNestedScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int, int, int[]) parameter #0:
+    Missing nullability on parameter `parent` in method `onNestedScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int, int, int[]) parameter #1:
+    Missing nullability on parameter `target` in method `onNestedScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int) parameter #0:
+    Missing nullability on parameter `parent` in method `onNestedScrollAccepted`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int) parameter #1:
+    Missing nullability on parameter `child` in method `onNestedScrollAccepted`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int) parameter #2:
+    Missing nullability on parameter `target` in method `onNestedScrollAccepted`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int, int) parameter #0:
+    Missing nullability on parameter `parent` in method `onNestedScrollAccepted`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int, int) parameter #1:
+    Missing nullability on parameter `child` in method `onNestedScrollAccepted`
+MissingNullability: androidx.core.view.ViewParentCompat#onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int, int) parameter #2:
+    Missing nullability on parameter `target` in method `onNestedScrollAccepted`
+MissingNullability: androidx.core.view.ViewParentCompat#onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int) parameter #0:
+    Missing nullability on parameter `parent` in method `onStartNestedScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int) parameter #1:
+    Missing nullability on parameter `child` in method `onStartNestedScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int) parameter #2:
+    Missing nullability on parameter `target` in method `onStartNestedScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int, int) parameter #0:
+    Missing nullability on parameter `parent` in method `onStartNestedScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int, int) parameter #1:
+    Missing nullability on parameter `child` in method `onStartNestedScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int, int) parameter #2:
+    Missing nullability on parameter `target` in method `onStartNestedScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onStopNestedScroll(android.view.ViewParent, android.view.View) parameter #0:
+    Missing nullability on parameter `parent` in method `onStopNestedScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onStopNestedScroll(android.view.ViewParent, android.view.View) parameter #1:
+    Missing nullability on parameter `target` in method `onStopNestedScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onStopNestedScroll(android.view.ViewParent, android.view.View, int) parameter #0:
+    Missing nullability on parameter `parent` in method `onStopNestedScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#onStopNestedScroll(android.view.ViewParent, android.view.View, int) parameter #1:
+    Missing nullability on parameter `target` in method `onStopNestedScroll`
+MissingNullability: androidx.core.view.ViewParentCompat#requestSendAccessibilityEvent(android.view.ViewParent, android.view.View, android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `parent` in method `requestSendAccessibilityEvent`
+MissingNullability: androidx.core.view.ViewParentCompat#requestSendAccessibilityEvent(android.view.ViewParent, android.view.View, android.view.accessibility.AccessibilityEvent) parameter #1:
+    Missing nullability on parameter `child` in method `requestSendAccessibilityEvent`
+MissingNullability: androidx.core.view.ViewParentCompat#requestSendAccessibilityEvent(android.view.ViewParent, android.view.View, android.view.accessibility.AccessibilityEvent) parameter #2:
+    Missing nullability on parameter `event` in method `requestSendAccessibilityEvent`
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#alpha(float):
+    Missing nullability on method `alpha` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#alphaBy(float):
+    Missing nullability on method `alphaBy` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#getInterpolator():
+    Missing nullability on method `getInterpolator` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#rotation(float):
+    Missing nullability on method `rotation` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#rotationBy(float):
+    Missing nullability on method `rotationBy` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#rotationX(float):
+    Missing nullability on method `rotationX` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#rotationXBy(float):
+    Missing nullability on method `rotationXBy` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#rotationY(float):
+    Missing nullability on method `rotationY` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#rotationYBy(float):
+    Missing nullability on method `rotationYBy` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#scaleX(float):
+    Missing nullability on method `scaleX` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#scaleXBy(float):
+    Missing nullability on method `scaleXBy` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#scaleY(float):
+    Missing nullability on method `scaleY` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#scaleYBy(float):
+    Missing nullability on method `scaleYBy` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#setDuration(long):
+    Missing nullability on method `setDuration` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#setInterpolator(android.view.animation.Interpolator):
+    Missing nullability on method `setInterpolator` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#setInterpolator(android.view.animation.Interpolator) parameter #0:
+    Missing nullability on parameter `value` in method `setInterpolator`
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#setListener(androidx.core.view.ViewPropertyAnimatorListener):
+    Missing nullability on method `setListener` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#setListener(androidx.core.view.ViewPropertyAnimatorListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setListener`
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#setStartDelay(long):
+    Missing nullability on method `setStartDelay` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#setUpdateListener(androidx.core.view.ViewPropertyAnimatorUpdateListener):
+    Missing nullability on method `setUpdateListener` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#setUpdateListener(androidx.core.view.ViewPropertyAnimatorUpdateListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setUpdateListener`
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#translationX(float):
+    Missing nullability on method `translationX` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#translationXBy(float):
+    Missing nullability on method `translationXBy` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#translationY(float):
+    Missing nullability on method `translationY` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#translationYBy(float):
+    Missing nullability on method `translationYBy` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#translationZ(float):
+    Missing nullability on method `translationZ` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#translationZBy(float):
+    Missing nullability on method `translationZBy` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#withEndAction(Runnable):
+    Missing nullability on method `withEndAction` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#withEndAction(Runnable) parameter #0:
+    Missing nullability on parameter `runnable` in method `withEndAction`
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#withLayer():
+    Missing nullability on method `withLayer` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#withStartAction(Runnable):
+    Missing nullability on method `withStartAction` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#withStartAction(Runnable) parameter #0:
+    Missing nullability on parameter `runnable` in method `withStartAction`
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#x(float):
+    Missing nullability on method `x` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#xBy(float):
+    Missing nullability on method `xBy` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#y(float):
+    Missing nullability on method `y` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#yBy(float):
+    Missing nullability on method `yBy` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#z(float):
+    Missing nullability on method `z` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorCompat#zBy(float):
+    Missing nullability on method `zBy` return
+MissingNullability: androidx.core.view.ViewPropertyAnimatorListener#onAnimationCancel(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onAnimationCancel`
+MissingNullability: androidx.core.view.ViewPropertyAnimatorListener#onAnimationEnd(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onAnimationEnd`
+MissingNullability: androidx.core.view.ViewPropertyAnimatorListener#onAnimationStart(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onAnimationStart`
+MissingNullability: androidx.core.view.ViewPropertyAnimatorListenerAdapter#onAnimationCancel(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onAnimationCancel`
+MissingNullability: androidx.core.view.ViewPropertyAnimatorListenerAdapter#onAnimationEnd(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onAnimationEnd`
+MissingNullability: androidx.core.view.ViewPropertyAnimatorListenerAdapter#onAnimationStart(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onAnimationStart`
+MissingNullability: androidx.core.view.ViewPropertyAnimatorUpdateListener#onAnimationUpdate(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onAnimationUpdate`
+MissingNullability: androidx.core.view.WindowInsetsCompat#WindowInsetsCompat(androidx.core.view.WindowInsetsCompat) parameter #0:
+    Missing nullability on parameter `src` in method `WindowInsetsCompat`
+MissingNullability: androidx.core.view.WindowInsetsCompat#consumeDisplayCutout():
+    Missing nullability on method `consumeDisplayCutout` return
+MissingNullability: androidx.core.view.WindowInsetsCompat#consumeStableInsets():
+    Missing nullability on method `consumeStableInsets` return
+MissingNullability: androidx.core.view.WindowInsetsCompat#consumeSystemWindowInsets():
+    Missing nullability on method `consumeSystemWindowInsets` return
+MissingNullability: androidx.core.view.WindowInsetsCompat#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.core.view.WindowInsetsCompat#replaceSystemWindowInsets(android.graphics.Rect):
+    Missing nullability on method `replaceSystemWindowInsets` return
+MissingNullability: androidx.core.view.WindowInsetsCompat#replaceSystemWindowInsets(android.graphics.Rect) parameter #0:
+    Missing nullability on parameter `systemWindowInsets` in method `replaceSystemWindowInsets`
+MissingNullability: androidx.core.view.WindowInsetsCompat#replaceSystemWindowInsets(int, int, int, int):
+    Missing nullability on method `replaceSystemWindowInsets` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityEventCompat#appendRecord(android.view.accessibility.AccessibilityEvent, androidx.core.view.accessibility.AccessibilityRecordCompat) parameter #0:
+    Missing nullability on parameter `event` in method `appendRecord`
+MissingNullability: androidx.core.view.accessibility.AccessibilityEventCompat#appendRecord(android.view.accessibility.AccessibilityEvent, androidx.core.view.accessibility.AccessibilityRecordCompat) parameter #1:
+    Missing nullability on parameter `record` in method `appendRecord`
+MissingNullability: androidx.core.view.accessibility.AccessibilityEventCompat#asRecord(android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `event` in method `asRecord`
+MissingNullability: androidx.core.view.accessibility.AccessibilityEventCompat#getAction(android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `event` in method `getAction`
+MissingNullability: androidx.core.view.accessibility.AccessibilityEventCompat#getContentChangeTypes(android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `event` in method `getContentChangeTypes`
+MissingNullability: androidx.core.view.accessibility.AccessibilityEventCompat#getMovementGranularity(android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `event` in method `getMovementGranularity`
+MissingNullability: androidx.core.view.accessibility.AccessibilityEventCompat#getRecord(android.view.accessibility.AccessibilityEvent, int) parameter #0:
+    Missing nullability on parameter `event` in method `getRecord`
+MissingNullability: androidx.core.view.accessibility.AccessibilityEventCompat#getRecordCount(android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `event` in method `getRecordCount`
+MissingNullability: androidx.core.view.accessibility.AccessibilityEventCompat#setAction(android.view.accessibility.AccessibilityEvent, int) parameter #0:
+    Missing nullability on parameter `event` in method `setAction`
+MissingNullability: androidx.core.view.accessibility.AccessibilityEventCompat#setContentChangeTypes(android.view.accessibility.AccessibilityEvent, int) parameter #0:
+    Missing nullability on parameter `event` in method `setContentChangeTypes`
+MissingNullability: androidx.core.view.accessibility.AccessibilityEventCompat#setMovementGranularity(android.view.accessibility.AccessibilityEvent, int) parameter #0:
+    Missing nullability on parameter `event` in method `setMovementGranularity`
+MissingNullability: androidx.core.view.accessibility.AccessibilityManagerCompat#addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener) parameter #0:
+    Missing nullability on parameter `manager` in method `addAccessibilityStateChangeListener`
+MissingNullability: androidx.core.view.accessibility.AccessibilityManagerCompat#addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener) parameter #1:
+    Missing nullability on parameter `listener` in method `addAccessibilityStateChangeListener`
+MissingNullability: androidx.core.view.accessibility.AccessibilityManagerCompat#addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener) parameter #0:
+    Missing nullability on parameter `manager` in method `addTouchExplorationStateChangeListener`
+MissingNullability: androidx.core.view.accessibility.AccessibilityManagerCompat#addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener) parameter #1:
+    Missing nullability on parameter `listener` in method `addTouchExplorationStateChangeListener`
+MissingNullability: androidx.core.view.accessibility.AccessibilityManagerCompat#getEnabledAccessibilityServiceList(android.view.accessibility.AccessibilityManager, int) parameter #0:
+    Missing nullability on parameter `manager` in method `getEnabledAccessibilityServiceList`
+MissingNullability: androidx.core.view.accessibility.AccessibilityManagerCompat#getInstalledAccessibilityServiceList(android.view.accessibility.AccessibilityManager) parameter #0:
+    Missing nullability on parameter `manager` in method `getInstalledAccessibilityServiceList`
+MissingNullability: androidx.core.view.accessibility.AccessibilityManagerCompat#isTouchExplorationEnabled(android.view.accessibility.AccessibilityManager) parameter #0:
+    Missing nullability on parameter `manager` in method `isTouchExplorationEnabled`
+MissingNullability: androidx.core.view.accessibility.AccessibilityManagerCompat#removeAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener) parameter #0:
+    Missing nullability on parameter `manager` in method `removeAccessibilityStateChangeListener`
+MissingNullability: androidx.core.view.accessibility.AccessibilityManagerCompat#removeAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener) parameter #1:
+    Missing nullability on parameter `listener` in method `removeAccessibilityStateChangeListener`
+MissingNullability: androidx.core.view.accessibility.AccessibilityManagerCompat#removeTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener) parameter #0:
+    Missing nullability on parameter `manager` in method `removeTouchExplorationStateChangeListener`
+MissingNullability: androidx.core.view.accessibility.AccessibilityManagerCompat#removeTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener) parameter #1:
+    Missing nullability on parameter `listener` in method `removeTouchExplorationStateChangeListener`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#AccessibilityNodeInfoCompat(Object) parameter #0:
+    Missing nullability on parameter `info` in method `AccessibilityNodeInfoCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#addAction(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat) parameter #0:
+    Missing nullability on parameter `action` in method `addAction`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#addChild(android.view.View) parameter #0:
+    Missing nullability on parameter `child` in method `addChild`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#addChild(android.view.View, int) parameter #0:
+    Missing nullability on parameter `root` in method `addChild`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#findAccessibilityNodeInfosByText(String):
+    Missing nullability on method `findAccessibilityNodeInfosByText` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#findAccessibilityNodeInfosByText(String) parameter #0:
+    Missing nullability on parameter `text` in method `findAccessibilityNodeInfosByText`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#findAccessibilityNodeInfosByViewId(String):
+    Missing nullability on method `findAccessibilityNodeInfosByViewId` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#findAccessibilityNodeInfosByViewId(String) parameter #0:
+    Missing nullability on parameter `viewId` in method `findAccessibilityNodeInfosByViewId`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#findFocus(int):
+    Missing nullability on method `findFocus` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#focusSearch(int):
+    Missing nullability on method `focusSearch` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getActionList():
+    Missing nullability on method `getActionList` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getBoundsInParent(android.graphics.Rect) parameter #0:
+    Missing nullability on parameter `outBounds` in method `getBoundsInParent`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getBoundsInScreen(android.graphics.Rect) parameter #0:
+    Missing nullability on parameter `outBounds` in method `getBoundsInScreen`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getChild(int):
+    Missing nullability on method `getChild` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getClassName():
+    Missing nullability on method `getClassName` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getCollectionInfo():
+    Missing nullability on method `getCollectionInfo` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getCollectionItemInfo():
+    Missing nullability on method `getCollectionItemInfo` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getContentDescription():
+    Missing nullability on method `getContentDescription` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getError():
+    Missing nullability on method `getError` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getExtras():
+    Missing nullability on method `getExtras` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getLabelFor():
+    Missing nullability on method `getLabelFor` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getLabeledBy():
+    Missing nullability on method `getLabeledBy` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getPackageName():
+    Missing nullability on method `getPackageName` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getParent():
+    Missing nullability on method `getParent` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getRangeInfo():
+    Missing nullability on method `getRangeInfo` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getText():
+    Missing nullability on method `getText` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getTraversalAfter():
+    Missing nullability on method `getTraversalAfter` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getTraversalBefore():
+    Missing nullability on method `getTraversalBefore` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getViewIdResourceName():
+    Missing nullability on method `getViewIdResourceName` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getWindow():
+    Missing nullability on method `getWindow` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#obtain():
+    Missing nullability on method `obtain` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#obtain(android.view.View):
+    Missing nullability on method `obtain` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#obtain(android.view.View) parameter #0:
+    Missing nullability on parameter `source` in method `obtain`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#obtain(android.view.View, int):
+    Missing nullability on method `obtain` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#obtain(android.view.View, int) parameter #0:
+    Missing nullability on parameter `root` in method `obtain`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#obtain(androidx.core.view.accessibility.AccessibilityNodeInfoCompat):
+    Missing nullability on method `obtain` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#obtain(androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #0:
+    Missing nullability on parameter `info` in method `obtain`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#performAction(int, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `arguments` in method `performAction`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#removeAction(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat) parameter #0:
+    Missing nullability on parameter `action` in method `removeAction`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#removeChild(android.view.View) parameter #0:
+    Missing nullability on parameter `child` in method `removeChild`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#removeChild(android.view.View, int) parameter #0:
+    Missing nullability on parameter `root` in method `removeChild`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setBoundsInParent(android.graphics.Rect) parameter #0:
+    Missing nullability on parameter `bounds` in method `setBoundsInParent`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setBoundsInScreen(android.graphics.Rect) parameter #0:
+    Missing nullability on parameter `bounds` in method `setBoundsInScreen`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setClassName(CharSequence) parameter #0:
+    Missing nullability on parameter `className` in method `setClassName`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setCollectionInfo(Object) parameter #0:
+    Missing nullability on parameter `collectionInfo` in method `setCollectionInfo`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setCollectionItemInfo(Object) parameter #0:
+    Missing nullability on parameter `collectionItemInfo` in method `setCollectionItemInfo`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setContentDescription(CharSequence) parameter #0:
+    Missing nullability on parameter `contentDescription` in method `setContentDescription`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setError(CharSequence) parameter #0:
+    Missing nullability on parameter `error` in method `setError`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setLabelFor(android.view.View) parameter #0:
+    Missing nullability on parameter `labeled` in method `setLabelFor`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setLabelFor(android.view.View, int) parameter #0:
+    Missing nullability on parameter `root` in method `setLabelFor`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setLabeledBy(android.view.View) parameter #0:
+    Missing nullability on parameter `label` in method `setLabeledBy`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setLabeledBy(android.view.View, int) parameter #0:
+    Missing nullability on parameter `root` in method `setLabeledBy`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setPackageName(CharSequence) parameter #0:
+    Missing nullability on parameter `packageName` in method `setPackageName`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setParent(android.view.View) parameter #0:
+    Missing nullability on parameter `parent` in method `setParent`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setParent(android.view.View, int) parameter #0:
+    Missing nullability on parameter `root` in method `setParent`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setRangeInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat) parameter #0:
+    Missing nullability on parameter `rangeInfo` in method `setRangeInfo`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setSource(android.view.View) parameter #0:
+    Missing nullability on parameter `source` in method `setSource`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setSource(android.view.View, int) parameter #0:
+    Missing nullability on parameter `root` in method `setSource`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setText(CharSequence) parameter #0:
+    Missing nullability on parameter `text` in method `setText`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setTraversalAfter(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `setTraversalAfter`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setTraversalAfter(android.view.View, int) parameter #0:
+    Missing nullability on parameter `root` in method `setTraversalAfter`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setTraversalBefore(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `setTraversalBefore`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setTraversalBefore(android.view.View, int) parameter #0:
+    Missing nullability on parameter `root` in method `setTraversalBefore`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setViewIdResourceName(String) parameter #0:
+    Missing nullability on parameter `viewId` in method `setViewIdResourceName`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#unwrap():
+    Missing nullability on method `unwrap` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#wrap(android.view.accessibility.AccessibilityNodeInfo):
+    Missing nullability on method `wrap` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_ACCESSIBILITY_FOCUS:
+    Missing nullability on field `ACTION_ACCESSIBILITY_FOCUS` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_CLEAR_ACCESSIBILITY_FOCUS:
+    Missing nullability on field `ACTION_CLEAR_ACCESSIBILITY_FOCUS` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_CLEAR_FOCUS:
+    Missing nullability on field `ACTION_CLEAR_FOCUS` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_CLEAR_SELECTION:
+    Missing nullability on field `ACTION_CLEAR_SELECTION` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_CLICK:
+    Missing nullability on field `ACTION_CLICK` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_COLLAPSE:
+    Missing nullability on field `ACTION_COLLAPSE` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_CONTEXT_CLICK:
+    Missing nullability on field `ACTION_CONTEXT_CLICK` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_COPY:
+    Missing nullability on field `ACTION_COPY` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_CUT:
+    Missing nullability on field `ACTION_CUT` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_DISMISS:
+    Missing nullability on field `ACTION_DISMISS` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_EXPAND:
+    Missing nullability on field `ACTION_EXPAND` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_FOCUS:
+    Missing nullability on field `ACTION_FOCUS` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_HIDE_TOOLTIP:
+    Missing nullability on field `ACTION_HIDE_TOOLTIP` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_LONG_CLICK:
+    Missing nullability on field `ACTION_LONG_CLICK` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_MOVE_WINDOW:
+    Missing nullability on field `ACTION_MOVE_WINDOW` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_NEXT_AT_MOVEMENT_GRANULARITY:
+    Missing nullability on field `ACTION_NEXT_AT_MOVEMENT_GRANULARITY` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_NEXT_HTML_ELEMENT:
+    Missing nullability on field `ACTION_NEXT_HTML_ELEMENT` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_PASTE:
+    Missing nullability on field `ACTION_PASTE` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY:
+    Missing nullability on field `ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_PREVIOUS_HTML_ELEMENT:
+    Missing nullability on field `ACTION_PREVIOUS_HTML_ELEMENT` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_SCROLL_BACKWARD:
+    Missing nullability on field `ACTION_SCROLL_BACKWARD` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_SCROLL_DOWN:
+    Missing nullability on field `ACTION_SCROLL_DOWN` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_SCROLL_FORWARD:
+    Missing nullability on field `ACTION_SCROLL_FORWARD` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_SCROLL_LEFT:
+    Missing nullability on field `ACTION_SCROLL_LEFT` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_SCROLL_RIGHT:
+    Missing nullability on field `ACTION_SCROLL_RIGHT` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_SCROLL_TO_POSITION:
+    Missing nullability on field `ACTION_SCROLL_TO_POSITION` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_SCROLL_UP:
+    Missing nullability on field `ACTION_SCROLL_UP` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_SELECT:
+    Missing nullability on field `ACTION_SELECT` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_SET_PROGRESS:
+    Missing nullability on field `ACTION_SET_PROGRESS` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_SET_SELECTION:
+    Missing nullability on field `ACTION_SET_SELECTION` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_SET_TEXT:
+    Missing nullability on field `ACTION_SET_TEXT` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_SHOW_ON_SCREEN:
+    Missing nullability on field `ACTION_SHOW_ON_SCREEN` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_SHOW_TOOLTIP:
+    Missing nullability on field `ACTION_SHOW_TOOLTIP` in class `class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#AccessibilityActionCompat(int, CharSequence) parameter #1:
+    Missing nullability on parameter `label` in method `AccessibilityActionCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat#getLabel():
+    Missing nullability on method `getLabel` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat#obtain(int, int, boolean):
+    Missing nullability on method `obtain` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat#obtain(int, int, boolean, int):
+    Missing nullability on method `obtain` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat#obtain(int, int, int, int, boolean):
+    Missing nullability on method `obtain` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat#obtain(int, int, int, int, boolean, boolean):
+    Missing nullability on method `obtain` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat#obtain(int, float, float, float):
+    Missing nullability on method `obtain` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeProviderCompat#AccessibilityNodeProviderCompat(Object) parameter #0:
+    Missing nullability on parameter `provider` in method `AccessibilityNodeProviderCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeProviderCompat#findAccessibilityNodeInfosByText(String, int) parameter #0:
+    Missing nullability on parameter `text` in method `findAccessibilityNodeInfosByText`
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeProviderCompat#getProvider():
+    Missing nullability on method `getProvider` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityNodeProviderCompat#performAction(int, int, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `arguments` in method `performAction`
+MissingNullability: androidx.core.view.accessibility.AccessibilityRecordCompat#AccessibilityRecordCompat(Object) parameter #0:
+    Missing nullability on parameter `record` in method `AccessibilityRecordCompat`
+MissingNullability: androidx.core.view.accessibility.AccessibilityRecordCompat#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.core.view.accessibility.AccessibilityRecordCompat#getMaxScrollX(android.view.accessibility.AccessibilityRecord) parameter #0:
+    Missing nullability on parameter `record` in method `getMaxScrollX`
+MissingNullability: androidx.core.view.accessibility.AccessibilityRecordCompat#getMaxScrollY(android.view.accessibility.AccessibilityRecord) parameter #0:
+    Missing nullability on parameter `record` in method `getMaxScrollY`
+MissingNullability: androidx.core.view.accessibility.AccessibilityRecordCompat#obtain(androidx.core.view.accessibility.AccessibilityRecordCompat) parameter #0:
+    Missing nullability on parameter `record` in method `obtain`
+MissingNullability: androidx.core.view.accessibility.AccessibilityRecordCompat#setBeforeText(CharSequence) parameter #0:
+    Missing nullability on parameter `beforeText` in method `setBeforeText`
+MissingNullability: androidx.core.view.accessibility.AccessibilityRecordCompat#setClassName(CharSequence) parameter #0:
+    Missing nullability on parameter `className` in method `setClassName`
+MissingNullability: androidx.core.view.accessibility.AccessibilityRecordCompat#setContentDescription(CharSequence) parameter #0:
+    Missing nullability on parameter `contentDescription` in method `setContentDescription`
+MissingNullability: androidx.core.view.accessibility.AccessibilityRecordCompat#setMaxScrollX(android.view.accessibility.AccessibilityRecord, int) parameter #0:
+    Missing nullability on parameter `record` in method `setMaxScrollX`
+MissingNullability: androidx.core.view.accessibility.AccessibilityRecordCompat#setMaxScrollY(android.view.accessibility.AccessibilityRecord, int) parameter #0:
+    Missing nullability on parameter `record` in method `setMaxScrollY`
+MissingNullability: androidx.core.view.accessibility.AccessibilityRecordCompat#setParcelableData(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `parcelableData` in method `setParcelableData`
+MissingNullability: androidx.core.view.accessibility.AccessibilityRecordCompat#setSource(android.view.View) parameter #0:
+    Missing nullability on parameter `source` in method `setSource`
+MissingNullability: androidx.core.view.accessibility.AccessibilityRecordCompat#setSource(android.view.View, int) parameter #0:
+    Missing nullability on parameter `root` in method `setSource`
+MissingNullability: androidx.core.view.accessibility.AccessibilityRecordCompat#setSource(android.view.accessibility.AccessibilityRecord, android.view.View, int) parameter #1:
+    Missing nullability on parameter `root` in method `setSource`
+MissingNullability: androidx.core.view.accessibility.AccessibilityViewCommand.MoveHtmlArguments#getHTMLElement():
+    Missing nullability on method `getHTMLElement` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityViewCommand.SetTextArguments#getText():
+    Missing nullability on method `getText` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityWindowInfoCompat#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.core.view.accessibility.AccessibilityWindowInfoCompat#getAnchor():
+    Missing nullability on method `getAnchor` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityWindowInfoCompat#getBoundsInScreen(android.graphics.Rect) parameter #0:
+    Missing nullability on parameter `outBounds` in method `getBoundsInScreen`
+MissingNullability: androidx.core.view.accessibility.AccessibilityWindowInfoCompat#getChild(int):
+    Missing nullability on method `getChild` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityWindowInfoCompat#getParent():
+    Missing nullability on method `getParent` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityWindowInfoCompat#getRoot():
+    Missing nullability on method `getRoot` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityWindowInfoCompat#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityWindowInfoCompat#obtain():
+    Missing nullability on method `obtain` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityWindowInfoCompat#obtain(androidx.core.view.accessibility.AccessibilityWindowInfoCompat):
+    Missing nullability on method `obtain` return
+MissingNullability: androidx.core.view.accessibility.AccessibilityWindowInfoCompat#obtain(androidx.core.view.accessibility.AccessibilityWindowInfoCompat) parameter #0:
+    Missing nullability on parameter `info` in method `obtain`
+MissingNullability: androidx.core.view.animation.PathInterpolatorCompat#create(android.graphics.Path):
+    Missing nullability on method `create` return
+MissingNullability: androidx.core.view.animation.PathInterpolatorCompat#create(android.graphics.Path) parameter #0:
+    Missing nullability on parameter `path` in method `create`
+MissingNullability: androidx.core.view.animation.PathInterpolatorCompat#create(float, float):
+    Missing nullability on method `create` return
+MissingNullability: androidx.core.view.animation.PathInterpolatorCompat#create(float, float, float, float):
+    Missing nullability on method `create` return
+MissingNullability: androidx.core.view.inputmethod.EditorInfoCompat#getContentMimeTypes(android.view.inputmethod.EditorInfo) parameter #0:
+    Missing nullability on parameter `editorInfo` in method `getContentMimeTypes`
+MissingNullability: androidx.core.view.inputmethod.InputConnectionCompat.OnCommitContentListener#onCommitContent(androidx.core.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inputContentInfo` in method `onCommitContent`
+MissingNullability: androidx.core.view.inputmethod.InputConnectionCompat.OnCommitContentListener#onCommitContent(androidx.core.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `opts` in method `onCommitContent`
+MissingNullability: androidx.core.widget.AutoScrollHelper#onTouch(android.view.View, android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `v` in method `onTouch`
+MissingNullability: androidx.core.widget.AutoScrollHelper#onTouch(android.view.View, android.view.MotionEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onTouch`
+MissingNullability: androidx.core.widget.AutoScrollHelper#setEnabled(boolean):
+    Missing nullability on method `setEnabled` return
+MissingNullability: androidx.core.widget.AutoScrollHelper#setExclusive(boolean):
+    Missing nullability on method `setExclusive` return
+MissingNullability: androidx.core.widget.EdgeEffectCompat#EdgeEffectCompat(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `EdgeEffectCompat`
+MissingNullability: androidx.core.widget.EdgeEffectCompat#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
+MissingNullability: androidx.core.widget.ListPopupWindowCompat#createDragToOpenListener(Object, android.view.View) parameter #0:
+    Missing nullability on parameter `listPopupWindow` in method `createDragToOpenListener`
+MissingNullability: androidx.core.widget.ListPopupWindowCompat#createDragToOpenListener(Object, android.view.View) parameter #1:
+    Missing nullability on parameter `src` in method `createDragToOpenListener`
+MissingNullability: androidx.core.widget.NestedScrollView#addView(android.view.View) parameter #0:
+    Missing nullability on parameter `child` in method `addView`
+MissingNullability: androidx.core.widget.NestedScrollView#addView(android.view.View, android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `child` in method `addView`
+MissingNullability: androidx.core.widget.NestedScrollView#addView(android.view.View, android.view.ViewGroup.LayoutParams) parameter #1:
+    Missing nullability on parameter `params` in method `addView`
+MissingNullability: androidx.core.widget.NestedScrollView#addView(android.view.View, int) parameter #0:
+    Missing nullability on parameter `child` in method `addView`
+MissingNullability: androidx.core.widget.NestedScrollView#addView(android.view.View, int, android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `child` in method `addView`
+MissingNullability: androidx.core.widget.NestedScrollView#addView(android.view.View, int, android.view.ViewGroup.LayoutParams) parameter #2:
+    Missing nullability on parameter `params` in method `addView`
+MissingNullability: androidx.core.widget.NestedScrollView#computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect) parameter #0:
+    Missing nullability on parameter `rect` in method `computeScrollDeltaToGetChildRectOnScreen`
+MissingNullability: androidx.core.widget.NestedScrollView#dispatchKeyEvent(android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `event` in method `dispatchKeyEvent`
+MissingNullability: androidx.core.widget.NestedScrollView#dispatchNestedPreScroll(int, int, int[], int[]) parameter #2:
+    Missing nullability on parameter `consumed` in method `dispatchNestedPreScroll`
+MissingNullability: androidx.core.widget.NestedScrollView#dispatchNestedPreScroll(int, int, int[], int[]) parameter #3:
+    Missing nullability on parameter `offsetInWindow` in method `dispatchNestedPreScroll`
+MissingNullability: androidx.core.widget.NestedScrollView#dispatchNestedPreScroll(int, int, int[], int[], int) parameter #2:
+    Missing nullability on parameter `consumed` in method `dispatchNestedPreScroll`
+MissingNullability: androidx.core.widget.NestedScrollView#dispatchNestedPreScroll(int, int, int[], int[], int) parameter #3:
+    Missing nullability on parameter `offsetInWindow` in method `dispatchNestedPreScroll`
+MissingNullability: androidx.core.widget.NestedScrollView#dispatchNestedScroll(int, int, int, int, int[]) parameter #4:
+    Missing nullability on parameter `offsetInWindow` in method `dispatchNestedScroll`
+MissingNullability: androidx.core.widget.NestedScrollView#dispatchNestedScroll(int, int, int, int, int[], int) parameter #4:
+    Missing nullability on parameter `offsetInWindow` in method `dispatchNestedScroll`
+MissingNullability: androidx.core.widget.NestedScrollView#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
+MissingNullability: androidx.core.widget.NestedScrollView#measureChild(android.view.View, int, int) parameter #0:
+    Missing nullability on parameter `child` in method `measureChild`
+MissingNullability: androidx.core.widget.NestedScrollView#measureChildWithMargins(android.view.View, int, int, int, int) parameter #0:
+    Missing nullability on parameter `child` in method `measureChildWithMargins`
+MissingNullability: androidx.core.widget.NestedScrollView#onGenericMotionEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `event` in method `onGenericMotionEvent`
+MissingNullability: androidx.core.widget.NestedScrollView#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onInterceptTouchEvent`
+MissingNullability: androidx.core.widget.NestedScrollView#onRequestFocusInDescendants(int, android.graphics.Rect) parameter #1:
+    Missing nullability on parameter `previouslyFocusedRect` in method `onRequestFocusInDescendants`
+MissingNullability: androidx.core.widget.NestedScrollView#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.core.widget.NestedScrollView#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.core.widget.NestedScrollView#onTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onTouchEvent`
+MissingNullability: androidx.core.widget.NestedScrollView#requestChildFocus(android.view.View, android.view.View) parameter #0:
+    Missing nullability on parameter `child` in method `requestChildFocus`
+MissingNullability: androidx.core.widget.NestedScrollView#requestChildFocus(android.view.View, android.view.View) parameter #1:
+    Missing nullability on parameter `focused` in method `requestChildFocus`
+MissingNullability: androidx.core.widget.NestedScrollView#requestChildRectangleOnScreen(android.view.View, android.graphics.Rect, boolean) parameter #0:
+    Missing nullability on parameter `child` in method `requestChildRectangleOnScreen`
+MissingNullability: androidx.core.widget.NestedScrollView#requestChildRectangleOnScreen(android.view.View, android.graphics.Rect, boolean) parameter #1:
+    Missing nullability on parameter `rectangle` in method `requestChildRectangleOnScreen`
+MissingNullability: androidx.core.widget.NestedScrollView.OnScrollChangeListener#onScrollChange(androidx.core.widget.NestedScrollView, int, int, int, int) parameter #0:
+    Missing nullability on parameter `v` in method `onScrollChange`
+MissingNullability: androidx.core.widget.ScrollerCompat#create(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `create`
+MissingNullability: androidx.core.widget.ScrollerCompat#create(android.content.Context, android.view.animation.Interpolator) parameter #0:
+    Missing nullability on parameter `context` in method `create`
+MissingNullability: androidx.core.widget.ScrollerCompat#create(android.content.Context, android.view.animation.Interpolator) parameter #1:
+    Missing nullability on parameter `interpolator` in method `create`
+
+
 NoClone: androidx.core.app.NotificationCompat.Action.WearableExtender#clone():
     Provide an explicit copy constructor instead of implementing `clone()`
 NoClone: androidx.core.app.NotificationCompat.WearableExtender#clone():
diff --git a/core/core/api/current.txt b/core/core/api/current.txt
index fe4b834..d39053e 100644
--- a/core/core/api/current.txt
+++ b/core/core/api/current.txt
@@ -1610,7 +1610,7 @@
   }
 
   public interface Predicate<T> {
-    method public boolean test(T?);
+    method public boolean test(T!);
   }
 
   public interface Supplier<T> {
diff --git a/core/core/api/res-1.2.0-alpha04.txt b/core/core/api/res-1.2.0-alpha04.txt
new file mode 100644
index 0000000..a609e0a
--- /dev/null
+++ b/core/core/api/res-1.2.0-alpha04.txt
@@ -0,0 +1,17 @@
+attr alpha
+attr font
+attr fontProviderAuthority
+attr fontProviderCerts
+attr fontProviderFetchStrategy
+attr fontProviderFetchTimeout
+attr fontProviderPackage
+attr fontProviderQuery
+attr fontStyle
+attr fontVariationSettings
+attr fontWeight
+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.2.0-alpha03.txt b/core/core/api/restricted_1.2.0-alpha03.txt
index fe706a7..7991be2 100644
--- a/core/core/api/restricted_1.2.0-alpha03.txt
+++ b/core/core/api/restricted_1.2.0-alpha03.txt
@@ -1969,7 +1969,7 @@
   }
 
   public interface Predicate<T> {
-    method public boolean test(T?);
+    method public boolean test(T!);
   }
 
   public interface Supplier<T> {
diff --git a/core/core/api/restricted_1.2.0-alpha04.ignore b/core/core/api/restricted_1.2.0-alpha04.ignore
new file mode 100644
index 0000000..e0f9ee3
--- /dev/null
+++ b/core/core/api/restricted_1.2.0-alpha04.ignore
@@ -0,0 +1,13 @@
+// Baseline format: 1.0
+ChangedStatic: androidx.core.content.pm.ShortcutManagerCompat#removeDynamicShortcuts(android.content.Context, java.util.List<java.lang.String>):
+    Method androidx.core.content.pm.ShortcutManagerCompat.removeDynamicShortcuts has changed 'static' qualifier
+
+
+ChangedType: androidx.core.graphics.TypefaceCompatApi26Impl#mFontFamily:
+    Field androidx.core.graphics.TypefaceCompatApi26Impl.mFontFamily has changed type from java.lang.Class to java.lang.Class<?>
+ChangedType: androidx.core.graphics.TypefaceCompatApi26Impl#mFontFamilyCtor:
+    Field androidx.core.graphics.TypefaceCompatApi26Impl.mFontFamilyCtor has changed type from java.lang.reflect.Constructor to java.lang.reflect.Constructor<?>
+ChangedType: androidx.core.graphics.TypefaceCompatApi26Impl#obtainFontFamily():
+    Method androidx.core.graphics.TypefaceCompatApi26Impl.obtainFontFamily has changed return type from Class to Class<?>
+ChangedType: androidx.core.graphics.TypefaceCompatApi26Impl#obtainFontFamilyCtor(Class<?>):
+    Method androidx.core.graphics.TypefaceCompatApi26Impl.obtainFontFamilyCtor has changed return type from java.lang.reflect.Constructor to java.lang.reflect.Constructor<?>
diff --git a/core/core/api/restricted_1.2.0-alpha04.txt b/core/core/api/restricted_1.2.0-alpha04.txt
new file mode 100644
index 0000000..7991be2
--- /dev/null
+++ b/core/core/api/restricted_1.2.0-alpha04.txt
@@ -0,0 +1,3499 @@
+// Signature format: 3.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 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 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 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 @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 {
+  }
+
+  public abstract class JobIntentService extends android.app.Service {
+    ctor public JobIntentService();
+    method public static void enqueueWork(android.content.Context, Class<?>, int, android.content.Intent);
+    method public static void enqueueWork(android.content.Context, android.content.ComponentName, int, android.content.Intent);
+    method public boolean isStopped();
+    method public android.os.IBinder! onBind(android.content.Intent);
+    method protected abstract void onHandleWork(android.content.Intent);
+    method public boolean onStopCurrentWork();
+    method public void setInterruptIfStopped(boolean);
+  }
+
+  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 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 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 @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 String! getShortcutId(android.app.Notification!);
+    method public static String! getSortKey(android.app.Notification!);
+    method public static long getTimeoutAfter(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_MESSAGE = "msg";
+    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_SYSTEM = "sys";
+    field public static final String CATEGORY_TRANSPORT = "transport";
+    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_COMPACT_ACTIONS = "android.compactActions";
+    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_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_PEOPLE = "android.people";
+    field public static final String EXTRA_PICTURE = "android.picture";
+    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_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 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 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!);
+    method public android.app.PendingIntent! getActionIntent();
+    method public boolean getAllowGeneratedReplies();
+    method public androidx.core.app.RemoteInput![]! getDataOnlyRemoteInputs();
+    method public android.os.Bundle! getExtras();
+    method public int getIcon();
+    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 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 public int icon;
+    field public CharSequence! title;
+  }
+
+  public static final class NotificationCompat.Action.Builder {
+    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 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 public androidx.core.app.NotificationCompat.BigPictureStyle! setSummaryText(CharSequence!);
+  }
+
+  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 @RequiresApi(29) 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 boolean isNotificationSuppressed();
+    method @RequiresApi(29) public static android.app.Notification.BubbleMetadata? toPlatform(androidx.core.app.NotificationCompat.BubbleMetadata?);
+  }
+
+  public static final class NotificationCompat.BubbleMetadata.Builder {
+    ctor public NotificationCompat.BubbleMetadata.Builder();
+    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 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 public androidx.core.app.NotificationCompat.Builder! addPerson(String!);
+    method public android.app.Notification! build();
+    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 @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 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 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! 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! 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! setShortcutId(String!);
+    method public androidx.core.app.NotificationCompat.Builder! setShowWhen(boolean);
+    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 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;
+  }
+
+  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 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 public androidx.core.app.NotificationCompat.CarExtender! setUnreadConversation(androidx.core.app.NotificationCompat.CarExtender.UnreadConversation!);
+  }
+
+  public static class NotificationCompat.CarExtender.UnreadConversation {
+    method public long getLatestTimestamp();
+    method public String![]! getMessages();
+    method public String! getParticipant();
+    method public String![]! getParticipants();
+    method public android.app.PendingIntent! getReadPendingIntent();
+    method public androidx.core.app.RemoteInput! getRemoteInput();
+    method public android.app.PendingIntent! getReplyPendingIntent();
+  }
+
+  public static class NotificationCompat.CarExtender.UnreadConversation.Builder {
+    ctor public NotificationCompat.CarExtender.UnreadConversation.Builder(String!);
+    method public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder! addMessage(String!);
+    method public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation! build();
+    method public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder! setLatestTimestamp(long);
+    method public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder! setReadPendingIntent(android.app.PendingIntent!);
+    method 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 @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!>! 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({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) public android.graphics.Bitmap! createColoredBitmap(int, int);
+    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 createNotificationChannelGroup(android.app.NotificationChannelGroup);
+    method public void createNotificationChannelGroups(java.util.List<android.app.NotificationChannelGroup!>);
+    method public void createNotificationChannels(java.util.List<android.app.NotificationChannel!>);
+    method public void deleteNotificationChannel(String);
+    method public void deleteNotificationChannelGroup(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.NotificationChannelGroup? getNotificationChannelGroup(String);
+    method public java.util.List<android.app.NotificationChannelGroup!> getNotificationChannelGroups();
+    method public java.util.List<android.app.NotificationChannel!> getNotificationChannels();
+    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 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 @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 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) public android.app.PendingIntent! mActionIntent;
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public CharSequence! mContentDescription;
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public boolean mEnabled;
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public androidx.core.graphics.drawable.IconCompat! mIcon;
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public boolean mShouldShowIcon;
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) 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 public static void configureMenuItem(android.view.MenuItem, androidx.core.app.ShareCompat.IntentBuilder);
+    method 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 {
+    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 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 {
+    method 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 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 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();
+    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 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 makeMainSelectorActivity(String, String);
+    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";
+  }
+
+  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 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();
+  }
+
+}
+
+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);
+  }
+
+  public final class PermissionInfoCompat {
+    method @androidx.core.content.pm.PermissionInfoCompat.Protection public static int getProtection(android.content.pm.PermissionInfo);
+    method @androidx.core.content.pm.PermissionInfoCompat.ProtectionFlags 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 @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 CharSequence? getLongLabel();
+    method public CharSequence getShortLabel();
+    method @RequiresApi(25) public android.content.pm.ShortcutInfo! toShortcutInfo();
+  }
+
+  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 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 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 setLongLabel(CharSequence);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLived();
+    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 setShortLabel(CharSequence);
+  }
+
+  @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 java.util.List<androidx.core.content.pm.ShortcutInfoCompat!> getDynamicShortcuts(android.content.Context);
+    method public static int getMaxShortcutCountPerActivity(android.content.Context);
+    method public static boolean isRequestPinShortcutSupported(android.content.Context);
+    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 boolean requestPinShortcut(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat, android.content.IntentSender?);
+    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";
+  }
+
+}
+
+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 @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;
+  }
+
+  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);
+  }
+
+  @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 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=androidx.core.graphics.ColorUtils.XYZ_WHITE_REFERENCE_X) double, @FloatRange(from=0.0f, to=androidx.core.graphics.ColorUtils.XYZ_WHITE_REFERENCE_Y) double, @FloatRange(from=0.0f, to=androidx.core.graphics.ColorUtils.XYZ_WHITE_REFERENCE_Z) double);
+    method public static void XYZToLAB(@FloatRange(from=0.0f, to=androidx.core.graphics.ColorUtils.XYZ_WHITE_REFERENCE_X) double, @FloatRange(from=0.0f, to=androidx.core.graphics.ColorUtils.XYZ_WHITE_REFERENCE_Y) double, @FloatRange(from=0.0f, to=androidx.core.graphics.ColorUtils.XYZ_WHITE_REFERENCE_Z) 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 of(int, int, int, int);
+    method public static androidx.core.graphics.Insets of(android.graphics.Rect);
+    method @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 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 @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 @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 @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface? findFromCache(android.content.res.Resources, int, int);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @RequiresApi(26) 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;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @RequiresApi(28) public class TypefaceCompatApi28Impl extends androidx.core.graphics.TypefaceCompatApi26Impl {
+    ctor public TypefaceCompatApi28Impl();
+    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);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @RequiresApi(29) 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);
+  }
+
+  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 public static androidx.core.graphics.drawable.IconCompat! createWithAdaptiveBitmap(android.graphics.Bitmap!);
+    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 @IdRes public int getResId();
+    method public String getResPackage();
+    method @androidx.core.graphics.drawable.IconCompat.IconType public int getType();
+    method public android.net.Uri getUri();
+    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 @RequiresApi(23) public android.graphics.drawable.Icon! toIcon();
+    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) 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 final 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 final class LocationManagerCompat {
+    method public static boolean isLocationEnabled(android.location.LocationManager);
+  }
+
+}
+
+package androidx.core.math {
+
+  public class MathUtils {
+    method public static float clamp(float, float, float);
+    method public static double clamp(double, double, double);
+    method public static int clamp(int, int, int);
+  }
+
+}
+
+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 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 public static boolean isAtLeastN();
+    method @Deprecated public static boolean isAtLeastNMR1();
+    method @Deprecated public static boolean isAtLeastO();
+    method @Deprecated public static boolean isAtLeastOMR1();
+    method @Deprecated public static boolean isAtLeastP();
+    method @Deprecated public static boolean isAtLeastQ();
+  }
+
+  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 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 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 TraceCompat {
+    method public static void beginAsyncSection(String, int);
+    method public static void beginSection(String);
+    method public static void endAsyncSection(String, int);
+    method public static void endSection();
+    method public static boolean isEnabled();
+    method public static void setCounter(String, int);
+  }
+
+  public class UserManagerCompat {
+    method public static boolean isUserUnlocked(android.content.Context);
+  }
+
+}
+
+package androidx.core.provider {
+
+  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 @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 @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 @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 @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @RequiresApi(19) 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 @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void resetCache();
+    field @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 @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 @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 @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 {
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class SelfDestructiveThread {
+    ctor public SelfDestructiveThread(String!, int, int);
+    method @VisibleForTesting public int getGeneration();
+    method @VisibleForTesting public boolean isRunning();
+    method public <T> void postAndReply(java.util.concurrent.Callable<T!>!, androidx.core.provider.SelfDestructiveThread.ReplyCallback<T!>!);
+    method public <T> T! postAndWait(java.util.concurrent.Callable<T!>!, int) throws java.lang.InterruptedException;
+  }
+
+  public static interface SelfDestructiveThread.ReplyCallback<T> {
+    method public void onReply(T!);
+  }
+
+}
+
+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!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class LogWriter extends java.io.Writer {
+    ctor public LogWriter(String!);
+    method public void close();
+    method public void flush();
+    method 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?);
+  }
+
+  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 int checkArgumentInRange(int, int, int, String);
+    method @IntRange(from=0) public static int checkArgumentNonnegative(int, String?);
+    method @IntRange(from=0) public static int checkArgumentNonnegative(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);
+  }
+
+  public interface Predicate<T> {
+    method public boolean test(T!);
+  }
+
+  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 DisplayCutoutCompat {
+    ctor public DisplayCutoutCompat(android.graphics.Rect!, java.util.List<android.graphics.Rect!>!);
+    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();
+  }
+
+  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 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 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 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 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! 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 @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 @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 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 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 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 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 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 @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 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 @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 <T extends android.view.View> T requireViewById(android.view.Window, @IdRes int);
+    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 class WindowInsetsCompat {
+    ctor public WindowInsetsCompat(androidx.core.view.WindowInsetsCompat!);
+    method public androidx.core.view.WindowInsetsCompat! consumeDisplayCutout();
+    method public androidx.core.view.WindowInsetsCompat! consumeStableInsets();
+    method public androidx.core.view.WindowInsetsCompat! consumeSystemWindowInsets();
+    method public androidx.core.view.DisplayCutoutCompat? getDisplayCutout();
+    method public androidx.core.graphics.Insets getMandatorySystemGestureInsets();
+    method public int getStableInsetBottom();
+    method public int getStableInsetLeft();
+    method public int getStableInsetRight();
+    method public int getStableInsetTop();
+    method public androidx.core.graphics.Insets getStableInsets();
+    method public androidx.core.graphics.Insets getSystemGestureInsets();
+    method public int getSystemWindowInsetBottom();
+    method public int getSystemWindowInsetLeft();
+    method public int getSystemWindowInsetRight();
+    method public int getSystemWindowInsetTop();
+    method public androidx.core.graphics.Insets getSystemWindowInsets();
+    method public androidx.core.graphics.Insets getTappableElementInsets();
+    method public boolean hasInsets();
+    method public boolean hasStableInsets();
+    method public boolean hasSystemWindowInsets();
+    method public boolean isConsumed();
+    method public boolean isRound();
+    method public androidx.core.view.WindowInsetsCompat! replaceSystemWindowInsets(int, int, int, int);
+    method 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);
+  }
+
+}
+
+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 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_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 @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 @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! 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 @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 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_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_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_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 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 void setContentMimeTypes(android.view.inputmethod.EditorInfo, String![]?);
+    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 public static android.view.inputmethod.InputConnection createWrapper(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, androidx.core.view.inputmethod.InputConnectionCompat.OnCommitContentListener);
+    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 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 @Deprecated public boolean draw(android.graphics.Canvas!);
+    method @Deprecated public void finish();
+    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 @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 smoothScrollTo(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, @Px @IntRange(from=0) int);
+    method public static void setLastBaselineToBottomHeight(android.widget.TextView, @Px @IntRange(from=0) int);
+    method public static void setLineHeight(android.widget.TextView, @Px @IntRange(from=0) 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 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 {
+  }
+
+  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 fe706a7..7991be2 100644
--- a/core/core/api/restricted_current.txt
+++ b/core/core/api/restricted_current.txt
@@ -1969,7 +1969,7 @@
   }
 
   public interface Predicate<T> {
-    method public boolean test(T?);
+    method public boolean test(T!);
   }
 
   public interface Supplier<T> {
diff --git a/core/core/src/androidTest/java/androidx/core/view/AccessibilityDelegateCompatTest.java b/core/core/src/androidTest/java/androidx/core/view/AccessibilityDelegateCompatTest.java
index ddd7ea8..76a8a84 100644
--- a/core/core/src/androidTest/java/androidx/core/view/AccessibilityDelegateCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/view/AccessibilityDelegateCompatTest.java
@@ -305,6 +305,20 @@
 
     @Test
     @SdkSuppress(minSdkVersion = 21)
+    public void testActionRemovedAfterAfterNullReplacement() {
+        final AccessibilityViewCommand action = mock(AccessibilityViewCommand.class);
+
+        ViewCompat.replaceAccessibilityAction(mView, AccessibilityActionCompat.ACTION_FOCUS,
+                "Focus title", action);
+
+        ViewCompat.replaceAccessibilityAction(mView, AccessibilityActionCompat.ACTION_FOCUS,
+                null, null);
+
+        assertFalse(nodeHasActionWithId(AccessibilityNodeInfoCompat.ACTION_FOCUS, null));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 21)
     public void testReplaceActionPerformIsCalledWithArguments() {
         final AccessibilityViewCommand action =
                 (AccessibilityViewCommand) mock(
diff --git a/core/core/src/main/java/androidx/core/util/Predicate.java b/core/core/src/main/java/androidx/core/util/Predicate.java
index 41e8582..ceb9e6f 100644
--- a/core/core/src/main/java/androidx/core/util/Predicate.java
+++ b/core/core/src/main/java/androidx/core/util/Predicate.java
@@ -16,7 +16,7 @@
 
 package androidx.core.util;
 
-import androidx.annotation.Nullable;
+import android.annotation.SuppressLint;
 
 /**
  * Compat version of {@link java.util.function.Predicate}
@@ -32,5 +32,6 @@
      * @return {@code true} if the input argument matches the predicate,
      * otherwise {@code false}
      */
-    boolean test(@Nullable T t);
+    @SuppressLint("UnknownNullness")
+    boolean test(T t);
 }
diff --git a/core/core/src/main/java/androidx/core/view/ViewCompat.java b/core/core/src/main/java/androidx/core/view/ViewCompat.java
index f8d62370..6dc7a96 100644
--- a/core/core/src/main/java/androidx/core/view/ViewCompat.java
+++ b/core/core/src/main/java/androidx/core/view/ViewCompat.java
@@ -1249,7 +1249,7 @@
 
     /**
      * Replaces an action. This can be used to change the default behavior or label of the action
-     * specified.
+     * specified. If label and command are both {@code null}, the action will be removed.
      *
      * @param view The view.
      * @param replacedAction The action to be replaced.
@@ -1265,7 +1265,11 @@
     public static void replaceAccessibilityAction(@NonNull View view, @NonNull
             AccessibilityActionCompat replacedAction,  @Nullable CharSequence label,
             @Nullable AccessibilityViewCommand command) {
-        addAccessibilityAction(view, replacedAction.createReplacementAction(label, command));
+        if (command == null && label == null) {
+            ViewCompat.removeAccessibilityAction(view, replacedAction.getId());
+        } else {
+            addAccessibilityAction(view, replacedAction.createReplacementAction(label, command));
+        }
     }
 
     private static void addAccessibilityAction(@NonNull View view,
diff --git a/core/core/src/main/java/androidx/core/widget/NestedScrollView.java b/core/core/src/main/java/androidx/core/widget/NestedScrollView.java
index fff1cd1..803873c 100644
--- a/core/core/src/main/java/androidx/core/widget/NestedScrollView.java
+++ b/core/core/src/main/java/androidx/core/widget/NestedScrollView.java
@@ -2107,7 +2107,8 @@
                 return false;
             }
             switch (action) {
-                case AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD: {
+                case AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD:
+                case android.R.id.accessibilityActionScrollDown: {
                     final int viewportHeight = nsvHost.getHeight() - nsvHost.getPaddingBottom()
                             - nsvHost.getPaddingTop();
                     final int targetScrollY = Math.min(nsvHost.getScrollY() + viewportHeight,
@@ -2118,7 +2119,8 @@
                     }
                 }
                 return false;
-                case AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD: {
+                case AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD:
+                case android.R.id.accessibilityActionScrollUp: {
                     final int viewportHeight = nsvHost.getHeight() - nsvHost.getPaddingBottom()
                             - nsvHost.getPaddingTop();
                     final int targetScrollY = Math.max(nsvHost.getScrollY() - viewportHeight, 0);
@@ -2142,10 +2144,16 @@
                 if (scrollRange > 0) {
                     info.setScrollable(true);
                     if (nsvHost.getScrollY() > 0) {
-                        info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD);
+                        info.addAction(AccessibilityNodeInfoCompat.AccessibilityActionCompat
+                                .ACTION_SCROLL_BACKWARD);
+                        info.addAction(AccessibilityNodeInfoCompat.AccessibilityActionCompat
+                                .ACTION_SCROLL_UP);
                     }
                     if (nsvHost.getScrollY() < scrollRange) {
-                        info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD);
+                        info.addAction(AccessibilityNodeInfoCompat.AccessibilityActionCompat
+                                .ACTION_SCROLL_FORWARD);
+                        info.addAction(AccessibilityNodeInfoCompat.AccessibilityActionCompat
+                                .ACTION_SCROLL_DOWN);
                     }
                 }
             }
diff --git a/cursoradapter/api/api_lint.ignore b/cursoradapter/api/api_lint.ignore
index 7b5962b..b0ea08d 100644
--- a/cursoradapter/api/api_lint.ignore
+++ b/cursoradapter/api/api_lint.ignore
@@ -3,3 +3,167 @@
     Context is distinct, so it must be the first argument (method `bindView`)
 ContextFirst: androidx.cursoradapter.widget.SimpleCursorAdapter#bindView(android.view.View, android.content.Context, android.database.Cursor) parameter #1:
     Context is distinct, so it must be the first argument (method `bindView`)
+
+
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#CursorAdapter(android.content.Context, android.database.Cursor) parameter #0:
+    Missing nullability on parameter `context` in method `CursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#CursorAdapter(android.content.Context, android.database.Cursor) parameter #1:
+    Missing nullability on parameter `c` in method `CursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#CursorAdapter(android.content.Context, android.database.Cursor, boolean) parameter #0:
+    Missing nullability on parameter `context` in method `CursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#CursorAdapter(android.content.Context, android.database.Cursor, boolean) parameter #1:
+    Missing nullability on parameter `c` in method `CursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#CursorAdapter(android.content.Context, android.database.Cursor, int) parameter #0:
+    Missing nullability on parameter `context` in method `CursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#CursorAdapter(android.content.Context, android.database.Cursor, int) parameter #1:
+    Missing nullability on parameter `c` in method `CursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#bindView(android.view.View, android.content.Context, android.database.Cursor) parameter #0:
+    Missing nullability on parameter `view` in method `bindView`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#bindView(android.view.View, android.content.Context, android.database.Cursor) parameter #1:
+    Missing nullability on parameter `context` in method `bindView`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#bindView(android.view.View, android.content.Context, android.database.Cursor) parameter #2:
+    Missing nullability on parameter `cursor` in method `bindView`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#changeCursor(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `cursor` in method `changeCursor`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#convertToString(android.database.Cursor):
+    Missing nullability on method `convertToString` return
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#convertToString(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `cursor` in method `convertToString`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#getCursor():
+    Missing nullability on method `getCursor` return
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#getDropDownView(int, android.view.View, android.view.ViewGroup):
+    Missing nullability on method `getDropDownView` return
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#getDropDownView(int, android.view.View, android.view.ViewGroup) parameter #1:
+    Missing nullability on parameter `convertView` in method `getDropDownView`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#getDropDownView(int, android.view.View, android.view.ViewGroup) parameter #2:
+    Missing nullability on parameter `parent` in method `getDropDownView`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#getFilter():
+    Missing nullability on method `getFilter` return
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#getFilterQueryProvider():
+    Missing nullability on method `getFilterQueryProvider` return
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#getItem(int):
+    Missing nullability on method `getItem` return
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#getView(int, android.view.View, android.view.ViewGroup):
+    Missing nullability on method `getView` return
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#getView(int, android.view.View, android.view.ViewGroup) parameter #1:
+    Missing nullability on parameter `convertView` in method `getView`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#getView(int, android.view.View, android.view.ViewGroup) parameter #2:
+    Missing nullability on parameter `parent` in method `getView`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#init(android.content.Context, android.database.Cursor, boolean) parameter #0:
+    Missing nullability on parameter `context` in method `init`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#init(android.content.Context, android.database.Cursor, boolean) parameter #1:
+    Missing nullability on parameter `c` in method `init`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#newDropDownView(android.content.Context, android.database.Cursor, android.view.ViewGroup):
+    Missing nullability on method `newDropDownView` return
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#newDropDownView(android.content.Context, android.database.Cursor, android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `context` in method `newDropDownView`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#newDropDownView(android.content.Context, android.database.Cursor, android.view.ViewGroup) parameter #1:
+    Missing nullability on parameter `cursor` in method `newDropDownView`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#newDropDownView(android.content.Context, android.database.Cursor, android.view.ViewGroup) parameter #2:
+    Missing nullability on parameter `parent` in method `newDropDownView`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#newView(android.content.Context, android.database.Cursor, android.view.ViewGroup):
+    Missing nullability on method `newView` return
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#newView(android.content.Context, android.database.Cursor, android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `context` in method `newView`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#newView(android.content.Context, android.database.Cursor, android.view.ViewGroup) parameter #1:
+    Missing nullability on parameter `cursor` in method `newView`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#newView(android.content.Context, android.database.Cursor, android.view.ViewGroup) parameter #2:
+    Missing nullability on parameter `parent` in method `newView`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#runQueryOnBackgroundThread(CharSequence):
+    Missing nullability on method `runQueryOnBackgroundThread` return
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#runQueryOnBackgroundThread(CharSequence) parameter #0:
+    Missing nullability on parameter `constraint` in method `runQueryOnBackgroundThread`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#setFilterQueryProvider(android.widget.FilterQueryProvider) parameter #0:
+    Missing nullability on parameter `filterQueryProvider` in method `setFilterQueryProvider`
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#swapCursor(android.database.Cursor):
+    Missing nullability on method `swapCursor` return
+MissingNullability: androidx.cursoradapter.widget.CursorAdapter#swapCursor(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `newCursor` in method `swapCursor`
+MissingNullability: androidx.cursoradapter.widget.ResourceCursorAdapter#ResourceCursorAdapter(android.content.Context, int, android.database.Cursor) parameter #0:
+    Missing nullability on parameter `context` in method `ResourceCursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.ResourceCursorAdapter#ResourceCursorAdapter(android.content.Context, int, android.database.Cursor) parameter #2:
+    Missing nullability on parameter `c` in method `ResourceCursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.ResourceCursorAdapter#ResourceCursorAdapter(android.content.Context, int, android.database.Cursor, boolean) parameter #0:
+    Missing nullability on parameter `context` in method `ResourceCursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.ResourceCursorAdapter#ResourceCursorAdapter(android.content.Context, int, android.database.Cursor, boolean) parameter #2:
+    Missing nullability on parameter `c` in method `ResourceCursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.ResourceCursorAdapter#ResourceCursorAdapter(android.content.Context, int, android.database.Cursor, int) parameter #0:
+    Missing nullability on parameter `context` in method `ResourceCursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.ResourceCursorAdapter#ResourceCursorAdapter(android.content.Context, int, android.database.Cursor, int) parameter #2:
+    Missing nullability on parameter `c` in method `ResourceCursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.ResourceCursorAdapter#newDropDownView(android.content.Context, android.database.Cursor, android.view.ViewGroup):
+    Missing nullability on method `newDropDownView` return
+MissingNullability: androidx.cursoradapter.widget.ResourceCursorAdapter#newDropDownView(android.content.Context, android.database.Cursor, android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `context` in method `newDropDownView`
+MissingNullability: androidx.cursoradapter.widget.ResourceCursorAdapter#newDropDownView(android.content.Context, android.database.Cursor, android.view.ViewGroup) parameter #1:
+    Missing nullability on parameter `cursor` in method `newDropDownView`
+MissingNullability: androidx.cursoradapter.widget.ResourceCursorAdapter#newDropDownView(android.content.Context, android.database.Cursor, android.view.ViewGroup) parameter #2:
+    Missing nullability on parameter `parent` in method `newDropDownView`
+MissingNullability: androidx.cursoradapter.widget.ResourceCursorAdapter#newView(android.content.Context, android.database.Cursor, android.view.ViewGroup):
+    Missing nullability on method `newView` return
+MissingNullability: androidx.cursoradapter.widget.ResourceCursorAdapter#newView(android.content.Context, android.database.Cursor, android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `context` in method `newView`
+MissingNullability: androidx.cursoradapter.widget.ResourceCursorAdapter#newView(android.content.Context, android.database.Cursor, android.view.ViewGroup) parameter #1:
+    Missing nullability on parameter `cursor` in method `newView`
+MissingNullability: androidx.cursoradapter.widget.ResourceCursorAdapter#newView(android.content.Context, android.database.Cursor, android.view.ViewGroup) parameter #2:
+    Missing nullability on parameter `parent` in method `newView`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#SimpleCursorAdapter(android.content.Context, int, android.database.Cursor, String[], int[]) parameter #0:
+    Missing nullability on parameter `context` in method `SimpleCursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#SimpleCursorAdapter(android.content.Context, int, android.database.Cursor, String[], int[]) parameter #2:
+    Missing nullability on parameter `c` in method `SimpleCursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#SimpleCursorAdapter(android.content.Context, int, android.database.Cursor, String[], int[]) parameter #3:
+    Missing nullability on parameter `from` in method `SimpleCursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#SimpleCursorAdapter(android.content.Context, int, android.database.Cursor, String[], int[]) parameter #4:
+    Missing nullability on parameter `to` in method `SimpleCursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#SimpleCursorAdapter(android.content.Context, int, android.database.Cursor, String[], int[], int) parameter #0:
+    Missing nullability on parameter `context` in method `SimpleCursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#SimpleCursorAdapter(android.content.Context, int, android.database.Cursor, String[], int[], int) parameter #2:
+    Missing nullability on parameter `c` in method `SimpleCursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#SimpleCursorAdapter(android.content.Context, int, android.database.Cursor, String[], int[], int) parameter #3:
+    Missing nullability on parameter `from` in method `SimpleCursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#SimpleCursorAdapter(android.content.Context, int, android.database.Cursor, String[], int[], int) parameter #4:
+    Missing nullability on parameter `to` in method `SimpleCursorAdapter`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#bindView(android.view.View, android.content.Context, android.database.Cursor) parameter #0:
+    Missing nullability on parameter `view` in method `bindView`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#bindView(android.view.View, android.content.Context, android.database.Cursor) parameter #1:
+    Missing nullability on parameter `context` in method `bindView`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#bindView(android.view.View, android.content.Context, android.database.Cursor) parameter #2:
+    Missing nullability on parameter `cursor` in method `bindView`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#changeCursorAndColumns(android.database.Cursor, String[], int[]) parameter #0:
+    Missing nullability on parameter `c` in method `changeCursorAndColumns`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#changeCursorAndColumns(android.database.Cursor, String[], int[]) parameter #1:
+    Missing nullability on parameter `from` in method `changeCursorAndColumns`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#changeCursorAndColumns(android.database.Cursor, String[], int[]) parameter #2:
+    Missing nullability on parameter `to` in method `changeCursorAndColumns`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#convertToString(android.database.Cursor):
+    Missing nullability on method `convertToString` return
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#convertToString(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `cursor` in method `convertToString`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#getCursorToStringConverter():
+    Missing nullability on method `getCursorToStringConverter` return
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#getViewBinder():
+    Missing nullability on method `getViewBinder` return
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#setCursorToStringConverter(androidx.cursoradapter.widget.SimpleCursorAdapter.CursorToStringConverter) parameter #0:
+    Missing nullability on parameter `cursorToStringConverter` in method `setCursorToStringConverter`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#setViewBinder(androidx.cursoradapter.widget.SimpleCursorAdapter.ViewBinder) parameter #0:
+    Missing nullability on parameter `viewBinder` in method `setViewBinder`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#setViewImage(android.widget.ImageView, String) parameter #0:
+    Missing nullability on parameter `v` in method `setViewImage`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#setViewImage(android.widget.ImageView, String) parameter #1:
+    Missing nullability on parameter `value` in method `setViewImage`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#setViewText(android.widget.TextView, String) parameter #0:
+    Missing nullability on parameter `v` in method `setViewText`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#setViewText(android.widget.TextView, String) parameter #1:
+    Missing nullability on parameter `text` in method `setViewText`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#swapCursor(android.database.Cursor):
+    Missing nullability on method `swapCursor` return
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter#swapCursor(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `c` in method `swapCursor`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter.CursorToStringConverter#convertToString(android.database.Cursor):
+    Missing nullability on method `convertToString` return
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter.CursorToStringConverter#convertToString(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `cursor` in method `convertToString`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter.ViewBinder#setViewValue(android.view.View, android.database.Cursor, int) parameter #0:
+    Missing nullability on parameter `view` in method `setViewValue`
+MissingNullability: androidx.cursoradapter.widget.SimpleCursorAdapter.ViewBinder#setViewValue(android.view.View, android.database.Cursor, int) parameter #1:
+    Missing nullability on parameter `cursor` in method `setViewValue`
diff --git a/customview/api/api_lint.ignore b/customview/api/api_lint.ignore
index b809558..e3d334f 100644
--- a/customview/api/api_lint.ignore
+++ b/customview/api/api_lint.ignore
@@ -3,6 +3,32 @@
     Callback method names must follow the on<Something> style: getOrderedChildIndex
 
 
+MissingNullability: androidx.customview.view.AbsSavedState#CREATOR:
+    Missing nullability on field `CREATOR` in class `class androidx.customview.view.AbsSavedState`
+MissingNullability: androidx.customview.view.AbsSavedState#EMPTY_STATE:
+    Missing nullability on field `EMPTY_STATE` in class `class androidx.customview.view.AbsSavedState`
+MissingNullability: androidx.customview.view.AbsSavedState#writeToParcel(android.os.Parcel, int) parameter #0:
+    Missing nullability on parameter `dest` in method `writeToParcel`
+MissingNullability: androidx.customview.widget.ExploreByTouchHelper#getAccessibilityNodeProvider(android.view.View):
+    Missing nullability on method `getAccessibilityNodeProvider` return
+MissingNullability: androidx.customview.widget.ExploreByTouchHelper#getAccessibilityNodeProvider(android.view.View) parameter #0:
+    Missing nullability on parameter `host` in method `getAccessibilityNodeProvider`
+MissingNullability: androidx.customview.widget.ExploreByTouchHelper#getVisibleVirtualViews(java.util.List<java.lang.Integer>) parameter #0:
+    Missing nullability on parameter `virtualViewIds` in method `getVisibleVirtualViews`
+MissingNullability: androidx.customview.widget.ExploreByTouchHelper#onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `host` in method `onInitializeAccessibilityEvent`
+MissingNullability: androidx.customview.widget.ExploreByTouchHelper#onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onInitializeAccessibilityEvent`
+MissingNullability: androidx.customview.widget.ExploreByTouchHelper#onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #0:
+    Missing nullability on parameter `host` in method `onInitializeAccessibilityNodeInfo`
+MissingNullability: androidx.customview.widget.ExploreByTouchHelper#onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #1:
+    Missing nullability on parameter `info` in method `onInitializeAccessibilityNodeInfo`
+MissingNullability: androidx.customview.widget.ViewDragHelper#create(android.view.ViewGroup, androidx.customview.widget.ViewDragHelper.Callback):
+    Missing nullability on method `create` return
+MissingNullability: androidx.customview.widget.ViewDragHelper#create(android.view.ViewGroup, float, androidx.customview.widget.ViewDragHelper.Callback):
+    Missing nullability on method `create` return
+
+
 ParcelConstructor: androidx.customview.view.AbsSavedState#AbsSavedState(android.os.Parcel):
     Parcelable inflation is exposed through CREATOR, not raw constructors, in androidx.customview.view.AbsSavedState
 
diff --git a/customview/src/main/java/androidx/customview/widget/ExploreByTouchHelper.java b/customview/src/main/java/androidx/customview/widget/ExploreByTouchHelper.java
index 43a1a24..03ffb2c 100644
--- a/customview/src/main/java/androidx/customview/widget/ExploreByTouchHelper.java
+++ b/customview/src/main/java/androidx/customview/widget/ExploreByTouchHelper.java
@@ -76,7 +76,7 @@
  *     }
  *
  *     &#64;Override
- *     public boolean onFocusChanged(boolean gainFocus, int direction,
+ *     public void onFocusChanged(boolean gainFocus, int direction,
  *         Rect previouslyFocusedRect) {
  *       super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
  *       mHelper.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
diff --git a/docs-runner/guava-package.list b/docs-runner/guava-package.list
new file mode 100644
index 0000000..8644ca9
--- /dev/null
+++ b/docs-runner/guava-package.list
@@ -0,0 +1 @@
+com.google.common.util.concurrent
\ No newline at end of file
diff --git a/drawerlayout/api/api_lint.ignore b/drawerlayout/api/api_lint.ignore
index e4e6148..002b6b2 100644
--- a/drawerlayout/api/api_lint.ignore
+++ b/drawerlayout/api/api_lint.ignore
@@ -7,6 +7,60 @@
     Listeners should be an interface, or otherwise renamed Callback: SimpleDrawerListener
 
 
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#addFocusables(java.util.ArrayList<android.view.View>, int, int) parameter #0:
+    Missing nullability on parameter `views` in method `addFocusables`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#addView(android.view.View, int, android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `child` in method `addView`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#addView(android.view.View, int, android.view.ViewGroup.LayoutParams) parameter #2:
+    Missing nullability on parameter `params` in method `addView`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#checkLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `checkLayoutParams`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#dispatchGenericMotionEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `event` in method `dispatchGenericMotionEvent`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#drawChild(android.graphics.Canvas, android.view.View, long) parameter #0:
+    Missing nullability on parameter `canvas` in method `drawChild`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#drawChild(android.graphics.Canvas, android.view.View, long) parameter #1:
+    Missing nullability on parameter `child` in method `drawChild`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#generateLayoutParams(android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#generateLayoutParams(android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#generateLayoutParams(android.view.ViewGroup.LayoutParams):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `generateLayoutParams`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `c` in method `onDraw`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onInterceptTouchEvent`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#onKeyDown(int, android.view.KeyEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onKeyDown`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#onKeyUp(int, android.view.KeyEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onKeyUp`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#onTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onTouchEvent`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#setDrawerListener(androidx.drawerlayout.widget.DrawerLayout.DrawerListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setDrawerListener`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#setDrawerShadow(android.graphics.drawable.Drawable, int) parameter #0:
+    Missing nullability on parameter `shadowDrawable` in method `setDrawerShadow`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout.SavedState#CREATOR:
+    Missing nullability on field `CREATOR` in class `class androidx.drawerlayout.widget.DrawerLayout.SavedState`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout.SavedState#writeToParcel(android.os.Parcel, int) parameter #0:
+    Missing nullability on parameter `dest` in method `writeToParcel`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout.SimpleDrawerListener#onDrawerClosed(android.view.View) parameter #0:
+    Missing nullability on parameter `drawerView` in method `onDrawerClosed`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout.SimpleDrawerListener#onDrawerOpened(android.view.View) parameter #0:
+    Missing nullability on parameter `drawerView` in method `onDrawerOpened`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout.SimpleDrawerListener#onDrawerSlide(android.view.View, float) parameter #0:
+    Missing nullability on parameter `drawerView` in method `onDrawerSlide`
+
+
 ParcelCreator: androidx.drawerlayout.widget.DrawerLayout.SavedState:
     Parcelable requires `public int describeContents()`; missing in androidx.drawerlayout.widget.DrawerLayout.SavedState
 
diff --git a/drawerlayout/build.gradle b/drawerlayout/build.gradle
index 7caf70d..49e01cc 100644
--- a/drawerlayout/build.gradle
+++ b/drawerlayout/build.gradle
@@ -11,8 +11,8 @@
 
 dependencies {
     api("androidx.annotation:annotation:1.1.0")
-    api(project(":core:core"))
-    api(project(":customview"))
+    api("androidx.core:core:1.2.0-alpha03")
+    api("androidx.customview:customview:1.1.0-alpha01")
 
     androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
     androidTestImplementation(ANDROIDX_TEST_CORE)
diff --git a/dynamic-animation/api/api_lint.ignore b/dynamic-animation/api/api_lint.ignore
new file mode 100644
index 0000000..9ac0566
--- /dev/null
+++ b/dynamic-animation/api/api_lint.ignore
@@ -0,0 +1,79 @@
+// Baseline format: 1.0
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#ALPHA:
+    Missing nullability on field `ALPHA` in class `class androidx.dynamicanimation.animation.DynamicAnimation`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#ROTATION:
+    Missing nullability on field `ROTATION` in class `class androidx.dynamicanimation.animation.DynamicAnimation`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#ROTATION_X:
+    Missing nullability on field `ROTATION_X` in class `class androidx.dynamicanimation.animation.DynamicAnimation`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#ROTATION_Y:
+    Missing nullability on field `ROTATION_Y` in class `class androidx.dynamicanimation.animation.DynamicAnimation`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#SCALE_X:
+    Missing nullability on field `SCALE_X` in class `class androidx.dynamicanimation.animation.DynamicAnimation`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#SCALE_Y:
+    Missing nullability on field `SCALE_Y` in class `class androidx.dynamicanimation.animation.DynamicAnimation`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#SCROLL_X:
+    Missing nullability on field `SCROLL_X` in class `class androidx.dynamicanimation.animation.DynamicAnimation`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#SCROLL_Y:
+    Missing nullability on field `SCROLL_Y` in class `class androidx.dynamicanimation.animation.DynamicAnimation`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#TRANSLATION_X:
+    Missing nullability on field `TRANSLATION_X` in class `class androidx.dynamicanimation.animation.DynamicAnimation`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#TRANSLATION_Y:
+    Missing nullability on field `TRANSLATION_Y` in class `class androidx.dynamicanimation.animation.DynamicAnimation`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#TRANSLATION_Z:
+    Missing nullability on field `TRANSLATION_Z` in class `class androidx.dynamicanimation.animation.DynamicAnimation`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#X:
+    Missing nullability on field `X` in class `class androidx.dynamicanimation.animation.DynamicAnimation`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#Y:
+    Missing nullability on field `Y` in class `class androidx.dynamicanimation.animation.DynamicAnimation`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#Z:
+    Missing nullability on field `Z` in class `class androidx.dynamicanimation.animation.DynamicAnimation`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#addEndListener(androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationEndListener) parameter #0:
+    Missing nullability on parameter `listener` in method `addEndListener`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#addUpdateListener(androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationUpdateListener) parameter #0:
+    Missing nullability on parameter `listener` in method `addUpdateListener`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#removeEndListener(androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationEndListener) parameter #0:
+    Missing nullability on parameter `listener` in method `removeEndListener`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation#removeUpdateListener(androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationUpdateListener) parameter #0:
+    Missing nullability on parameter `listener` in method `removeUpdateListener`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationEndListener#onAnimationEnd(androidx.dynamicanimation.animation.DynamicAnimation, boolean, float, float) parameter #0:
+    Missing nullability on parameter `animation` in method `onAnimationEnd`
+MissingNullability: androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationUpdateListener#onAnimationUpdate(androidx.dynamicanimation.animation.DynamicAnimation, float, float) parameter #0:
+    Missing nullability on parameter `animation` in method `onAnimationUpdate`
+MissingNullability: androidx.dynamicanimation.animation.FlingAnimation#FlingAnimation(K, androidx.dynamicanimation.animation.FloatPropertyCompat<K>) parameter #1:
+    Missing nullability on parameter `property` in method `FlingAnimation`
+MissingNullability: androidx.dynamicanimation.animation.FlingAnimation#FlingAnimation(androidx.dynamicanimation.animation.FloatValueHolder) parameter #0:
+    Missing nullability on parameter `floatValueHolder` in method `FlingAnimation`
+MissingNullability: androidx.dynamicanimation.animation.FlingAnimation#setFriction(float):
+    Missing nullability on method `setFriction` return
+MissingNullability: androidx.dynamicanimation.animation.FlingAnimation#setMaxValue(float):
+    Missing nullability on method `setMaxValue` return
+MissingNullability: androidx.dynamicanimation.animation.FlingAnimation#setMinValue(float):
+    Missing nullability on method `setMinValue` return
+MissingNullability: androidx.dynamicanimation.animation.FlingAnimation#setStartVelocity(float):
+    Missing nullability on method `setStartVelocity` return
+MissingNullability: androidx.dynamicanimation.animation.FloatPropertyCompat#FloatPropertyCompat(String) parameter #0:
+    Missing nullability on parameter `name` in method `FloatPropertyCompat`
+MissingNullability: androidx.dynamicanimation.animation.FloatPropertyCompat#createFloatPropertyCompat(android.util.FloatProperty<T>):
+    Missing nullability on method `createFloatPropertyCompat` return
+MissingNullability: androidx.dynamicanimation.animation.FloatPropertyCompat#createFloatPropertyCompat(android.util.FloatProperty<T>) parameter #0:
+    Missing nullability on parameter `property` in method `createFloatPropertyCompat`
+MissingNullability: androidx.dynamicanimation.animation.SpringAnimation#SpringAnimation(K, androidx.dynamicanimation.animation.FloatPropertyCompat<K>) parameter #1:
+    Missing nullability on parameter `property` in method `SpringAnimation`
+MissingNullability: androidx.dynamicanimation.animation.SpringAnimation#SpringAnimation(K, androidx.dynamicanimation.animation.FloatPropertyCompat<K>, float) parameter #1:
+    Missing nullability on parameter `property` in method `SpringAnimation`
+MissingNullability: androidx.dynamicanimation.animation.SpringAnimation#SpringAnimation(androidx.dynamicanimation.animation.FloatValueHolder) parameter #0:
+    Missing nullability on parameter `floatValueHolder` in method `SpringAnimation`
+MissingNullability: androidx.dynamicanimation.animation.SpringAnimation#SpringAnimation(androidx.dynamicanimation.animation.FloatValueHolder, float) parameter #0:
+    Missing nullability on parameter `floatValueHolder` in method `SpringAnimation`
+MissingNullability: androidx.dynamicanimation.animation.SpringAnimation#getSpring():
+    Missing nullability on method `getSpring` return
+MissingNullability: androidx.dynamicanimation.animation.SpringAnimation#setSpring(androidx.dynamicanimation.animation.SpringForce):
+    Missing nullability on method `setSpring` return
+MissingNullability: androidx.dynamicanimation.animation.SpringAnimation#setSpring(androidx.dynamicanimation.animation.SpringForce) parameter #0:
+    Missing nullability on parameter `force` in method `setSpring`
+MissingNullability: androidx.dynamicanimation.animation.SpringForce#setDampingRatio(float):
+    Missing nullability on method `setDampingRatio` return
+MissingNullability: androidx.dynamicanimation.animation.SpringForce#setFinalPosition(float):
+    Missing nullability on method `setFinalPosition` return
+MissingNullability: androidx.dynamicanimation.animation.SpringForce#setStiffness(float):
+    Missing nullability on method `setStiffness` return
diff --git a/emoji/appcompat/api/api_lint.ignore b/emoji/appcompat/api/api_lint.ignore
new file mode 100644
index 0000000..607bcb5
--- /dev/null
+++ b/emoji/appcompat/api/api_lint.ignore
@@ -0,0 +1,39 @@
+// Baseline format: 1.0
+MissingNullability: androidx.emoji.widget.EmojiAppCompatButton#EmojiAppCompatButton(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiAppCompatButton`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatButton#EmojiAppCompatButton(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiAppCompatButton`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatButton#EmojiAppCompatButton(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `EmojiAppCompatButton`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatButton#EmojiAppCompatButton(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiAppCompatButton`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatButton#EmojiAppCompatButton(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `EmojiAppCompatButton`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatButton#setFilters(android.text.InputFilter[]) parameter #0:
+    Missing nullability on parameter `filters` in method `setFilters`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatEditText#EmojiAppCompatEditText(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiAppCompatEditText`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatEditText#EmojiAppCompatEditText(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiAppCompatEditText`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatEditText#EmojiAppCompatEditText(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `EmojiAppCompatEditText`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatEditText#EmojiAppCompatEditText(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiAppCompatEditText`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatEditText#EmojiAppCompatEditText(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `EmojiAppCompatEditText`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatEditText#onCreateInputConnection(android.view.inputmethod.EditorInfo):
+    Missing nullability on method `onCreateInputConnection` return
+MissingNullability: androidx.emoji.widget.EmojiAppCompatEditText#onCreateInputConnection(android.view.inputmethod.EditorInfo) parameter #0:
+    Missing nullability on parameter `outAttrs` in method `onCreateInputConnection`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatTextView#EmojiAppCompatTextView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiAppCompatTextView`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatTextView#EmojiAppCompatTextView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiAppCompatTextView`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatTextView#EmojiAppCompatTextView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `EmojiAppCompatTextView`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatTextView#EmojiAppCompatTextView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiAppCompatTextView`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatTextView#EmojiAppCompatTextView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `EmojiAppCompatTextView`
+MissingNullability: androidx.emoji.widget.EmojiAppCompatTextView#setFilters(android.text.InputFilter[]) parameter #0:
+    Missing nullability on parameter `filters` in method `setFilters`
diff --git a/emoji/core/api/api_lint.ignore b/emoji/core/api/api_lint.ignore
new file mode 100644
index 0000000..8cac4ec
--- /dev/null
+++ b/emoji/core/api/api_lint.ignore
@@ -0,0 +1,123 @@
+// Baseline format: 1.0
+MissingNullability: androidx.emoji.text.EmojiCompat#get():
+    Missing nullability on method `get` return
+MissingNullability: androidx.emoji.text.EmojiCompat#handleOnKeyDown(android.text.Editable, int, android.view.KeyEvent) parameter #2:
+    Missing nullability on parameter `event` in method `handleOnKeyDown`
+MissingNullability: androidx.emoji.text.EmojiCompat#init(androidx.emoji.text.EmojiCompat.Config):
+    Missing nullability on method `init` return
+MissingNullability: androidx.emoji.text.EmojiCompat#process(CharSequence):
+    Missing nullability on method `process` return
+MissingNullability: androidx.emoji.text.EmojiCompat#process(CharSequence, int, int):
+    Missing nullability on method `process` return
+MissingNullability: androidx.emoji.text.EmojiCompat#process(CharSequence, int, int, int):
+    Missing nullability on method `process` return
+MissingNullability: androidx.emoji.text.EmojiCompat#process(CharSequence, int, int, int, int):
+    Missing nullability on method `process` return
+MissingNullability: androidx.emoji.text.EmojiCompat.Config#getMetadataRepoLoader():
+    Missing nullability on method `getMetadataRepoLoader` return
+MissingNullability: androidx.emoji.text.EmojiCompat.Config#registerInitCallback(androidx.emoji.text.EmojiCompat.InitCallback):
+    Missing nullability on method `registerInitCallback` return
+MissingNullability: androidx.emoji.text.EmojiCompat.Config#setEmojiSpanIndicatorColor(int):
+    Missing nullability on method `setEmojiSpanIndicatorColor` return
+MissingNullability: androidx.emoji.text.EmojiCompat.Config#setEmojiSpanIndicatorEnabled(boolean):
+    Missing nullability on method `setEmojiSpanIndicatorEnabled` return
+MissingNullability: androidx.emoji.text.EmojiCompat.Config#setMetadataLoadStrategy(int):
+    Missing nullability on method `setMetadataLoadStrategy` return
+MissingNullability: androidx.emoji.text.EmojiCompat.Config#setReplaceAll(boolean):
+    Missing nullability on method `setReplaceAll` return
+MissingNullability: androidx.emoji.text.EmojiCompat.Config#setUseEmojiAsDefaultStyle(boolean):
+    Missing nullability on method `setUseEmojiAsDefaultStyle` return
+MissingNullability: androidx.emoji.text.EmojiCompat.Config#setUseEmojiAsDefaultStyle(boolean, java.util.List<java.lang.Integer>):
+    Missing nullability on method `setUseEmojiAsDefaultStyle` return
+MissingNullability: androidx.emoji.text.EmojiCompat.Config#unregisterInitCallback(androidx.emoji.text.EmojiCompat.InitCallback):
+    Missing nullability on method `unregisterInitCallback` return
+MissingNullability: androidx.emoji.text.EmojiSpan#getSize(android.graphics.Paint, CharSequence, int, int, android.graphics.Paint.FontMetricsInt) parameter #1:
+    Missing nullability on parameter `text` in method `getSize`
+MissingNullability: androidx.emoji.text.EmojiSpan#getSize(android.graphics.Paint, CharSequence, int, int, android.graphics.Paint.FontMetricsInt) parameter #4:
+    Missing nullability on parameter `fm` in method `getSize`
+MissingNullability: androidx.emoji.text.FontRequestEmojiCompatConfig#setHandler(android.os.Handler):
+    Missing nullability on method `setHandler` return
+MissingNullability: androidx.emoji.text.FontRequestEmojiCompatConfig#setHandler(android.os.Handler) parameter #0:
+    Missing nullability on parameter `handler` in method `setHandler`
+MissingNullability: androidx.emoji.text.FontRequestEmojiCompatConfig#setRetryPolicy(androidx.emoji.text.FontRequestEmojiCompatConfig.RetryPolicy):
+    Missing nullability on method `setRetryPolicy` return
+MissingNullability: androidx.emoji.text.FontRequestEmojiCompatConfig#setRetryPolicy(androidx.emoji.text.FontRequestEmojiCompatConfig.RetryPolicy) parameter #0:
+    Missing nullability on parameter `policy` in method `setRetryPolicy`
+MissingNullability: androidx.emoji.text.MetadataRepo#create(android.content.res.AssetManager, String):
+    Missing nullability on method `create` return
+MissingNullability: androidx.emoji.text.MetadataRepo#create(android.content.res.AssetManager, String) parameter #1:
+    Missing nullability on parameter `assetPath` in method `create`
+MissingNullability: androidx.emoji.text.MetadataRepo#create(android.graphics.Typeface, java.io.InputStream):
+    Missing nullability on method `create` return
+MissingNullability: androidx.emoji.text.MetadataRepo#create(android.graphics.Typeface, java.nio.ByteBuffer):
+    Missing nullability on method `create` return
+MissingNullability: androidx.emoji.widget.EmojiButton#EmojiButton(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiButton`
+MissingNullability: androidx.emoji.widget.EmojiButton#EmojiButton(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiButton`
+MissingNullability: androidx.emoji.widget.EmojiButton#EmojiButton(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `EmojiButton`
+MissingNullability: androidx.emoji.widget.EmojiButton#EmojiButton(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiButton`
+MissingNullability: androidx.emoji.widget.EmojiButton#EmojiButton(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `EmojiButton`
+MissingNullability: androidx.emoji.widget.EmojiButton#EmojiButton(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiButton`
+MissingNullability: androidx.emoji.widget.EmojiButton#EmojiButton(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `EmojiButton`
+MissingNullability: androidx.emoji.widget.EmojiButton#setCustomSelectionActionModeCallback(android.view.ActionMode.Callback) parameter #0:
+    Missing nullability on parameter `actionModeCallback` in method `setCustomSelectionActionModeCallback`
+MissingNullability: androidx.emoji.widget.EmojiButton#setFilters(android.text.InputFilter[]) parameter #0:
+    Missing nullability on parameter `filters` in method `setFilters`
+MissingNullability: androidx.emoji.widget.EmojiEditText#EmojiEditText(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiEditText`
+MissingNullability: androidx.emoji.widget.EmojiEditText#EmojiEditText(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiEditText`
+MissingNullability: androidx.emoji.widget.EmojiEditText#EmojiEditText(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `EmojiEditText`
+MissingNullability: androidx.emoji.widget.EmojiEditText#EmojiEditText(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiEditText`
+MissingNullability: androidx.emoji.widget.EmojiEditText#EmojiEditText(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `EmojiEditText`
+MissingNullability: androidx.emoji.widget.EmojiEditText#EmojiEditText(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiEditText`
+MissingNullability: androidx.emoji.widget.EmojiEditText#EmojiEditText(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `EmojiEditText`
+MissingNullability: androidx.emoji.widget.EmojiEditText#onCreateInputConnection(android.view.inputmethod.EditorInfo):
+    Missing nullability on method `onCreateInputConnection` return
+MissingNullability: androidx.emoji.widget.EmojiEditText#onCreateInputConnection(android.view.inputmethod.EditorInfo) parameter #0:
+    Missing nullability on parameter `outAttrs` in method `onCreateInputConnection`
+MissingNullability: androidx.emoji.widget.EmojiEditText#setCustomSelectionActionModeCallback(android.view.ActionMode.Callback) parameter #0:
+    Missing nullability on parameter `actionModeCallback` in method `setCustomSelectionActionModeCallback`
+MissingNullability: androidx.emoji.widget.EmojiExtractTextLayout#EmojiExtractTextLayout(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiExtractTextLayout`
+MissingNullability: androidx.emoji.widget.EmojiExtractTextLayout#EmojiExtractTextLayout(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiExtractTextLayout`
+MissingNullability: androidx.emoji.widget.EmojiExtractTextLayout#EmojiExtractTextLayout(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiExtractTextLayout`
+MissingNullability: androidx.emoji.widget.EmojiExtractTextLayout#EmojiExtractTextLayout(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiExtractTextLayout`
+MissingNullability: androidx.emoji.widget.EmojiExtractTextLayout#EmojiExtractTextLayout(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `EmojiExtractTextLayout`
+MissingNullability: androidx.emoji.widget.EmojiExtractTextLayout#onUpdateExtractingViews(android.inputmethodservice.InputMethodService, android.view.inputmethod.EditorInfo) parameter #0:
+    Missing nullability on parameter `inputMethodService` in method `onUpdateExtractingViews`
+MissingNullability: androidx.emoji.widget.EmojiExtractTextLayout#onUpdateExtractingViews(android.inputmethodservice.InputMethodService, android.view.inputmethod.EditorInfo) parameter #1:
+    Missing nullability on parameter `ei` in method `onUpdateExtractingViews`
+MissingNullability: androidx.emoji.widget.EmojiTextView#EmojiTextView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiTextView`
+MissingNullability: androidx.emoji.widget.EmojiTextView#EmojiTextView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiTextView`
+MissingNullability: androidx.emoji.widget.EmojiTextView#EmojiTextView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `EmojiTextView`
+MissingNullability: androidx.emoji.widget.EmojiTextView#EmojiTextView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiTextView`
+MissingNullability: androidx.emoji.widget.EmojiTextView#EmojiTextView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `EmojiTextView`
+MissingNullability: androidx.emoji.widget.EmojiTextView#EmojiTextView(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `EmojiTextView`
+MissingNullability: androidx.emoji.widget.EmojiTextView#EmojiTextView(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `EmojiTextView`
+MissingNullability: androidx.emoji.widget.EmojiTextView#setCustomSelectionActionModeCallback(android.view.ActionMode.Callback) parameter #0:
+    Missing nullability on parameter `actionModeCallback` in method `setCustomSelectionActionModeCallback`
+MissingNullability: androidx.emoji.widget.EmojiTextView#setFilters(android.text.InputFilter[]) parameter #0:
+    Missing nullability on parameter `filters` in method `setFilters`
diff --git a/enterprise/feedback/api/1.0.0-alpha04.txt b/enterprise/feedback/api/1.0.0-alpha04.txt
new file mode 100644
index 0000000..040814c
--- /dev/null
+++ b/enterprise/feedback/api/1.0.0-alpha04.txt
@@ -0,0 +1,59 @@
+// Signature format: 3.0
+package androidx.enterprise.feedback {
+
+  public abstract class KeyedAppState {
+    method public static androidx.enterprise.feedback.KeyedAppState.KeyedAppStateBuilder builder();
+    method public abstract String? getData();
+    method public abstract String getKey();
+    method public abstract String? getMessage();
+    method public abstract int getSeverity();
+    field public static final int MAX_DATA_LENGTH = 1000; // 0x3e8
+    field public static final int MAX_KEY_LENGTH = 100; // 0x64
+    field public static final int MAX_MESSAGE_LENGTH = 1000; // 0x3e8
+    field public static final int SEVERITY_ERROR = 2; // 0x2
+    field public static final int SEVERITY_INFO = 1; // 0x1
+  }
+
+  public abstract static class KeyedAppState.KeyedAppStateBuilder {
+    method public androidx.enterprise.feedback.KeyedAppState build();
+    method public abstract androidx.enterprise.feedback.KeyedAppState.KeyedAppStateBuilder setData(String?);
+    method public abstract androidx.enterprise.feedback.KeyedAppState.KeyedAppStateBuilder setKey(String);
+    method public abstract androidx.enterprise.feedback.KeyedAppState.KeyedAppStateBuilder setMessage(String?);
+    method public abstract androidx.enterprise.feedback.KeyedAppState.KeyedAppStateBuilder setSeverity(int);
+  }
+
+  public abstract class KeyedAppStatesReporter {
+    method public static androidx.enterprise.feedback.KeyedAppStatesReporter create(android.content.Context);
+    method public static androidx.enterprise.feedback.KeyedAppStatesReporter create(android.content.Context, java.util.concurrent.Executor);
+    method public abstract void setStates(java.util.Collection<androidx.enterprise.feedback.KeyedAppState!>);
+    method public abstract void setStatesImmediate(java.util.Collection<androidx.enterprise.feedback.KeyedAppState!>);
+  }
+
+  public abstract class KeyedAppStatesService extends android.app.Service {
+    ctor public KeyedAppStatesService();
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public abstract void onReceive(java.util.Collection<androidx.enterprise.feedback.ReceivedKeyedAppState!>, boolean);
+  }
+
+  public abstract class ReceivedKeyedAppState {
+    method public static androidx.enterprise.feedback.ReceivedKeyedAppState.ReceivedKeyedAppStateBuilder builder();
+    method public abstract String? getData();
+    method public abstract String getKey();
+    method public abstract String? getMessage();
+    method public abstract String getPackageName();
+    method public abstract int getSeverity();
+    method public abstract long getTimestamp();
+  }
+
+  public abstract static class ReceivedKeyedAppState.ReceivedKeyedAppStateBuilder {
+    method public abstract androidx.enterprise.feedback.ReceivedKeyedAppState build();
+    method public abstract androidx.enterprise.feedback.ReceivedKeyedAppState.ReceivedKeyedAppStateBuilder setData(String?);
+    method public abstract androidx.enterprise.feedback.ReceivedKeyedAppState.ReceivedKeyedAppStateBuilder setKey(String);
+    method public abstract androidx.enterprise.feedback.ReceivedKeyedAppState.ReceivedKeyedAppStateBuilder setMessage(String?);
+    method public abstract androidx.enterprise.feedback.ReceivedKeyedAppState.ReceivedKeyedAppStateBuilder setPackageName(String);
+    method public abstract androidx.enterprise.feedback.ReceivedKeyedAppState.ReceivedKeyedAppStateBuilder setSeverity(int);
+    method public abstract androidx.enterprise.feedback.ReceivedKeyedAppState.ReceivedKeyedAppStateBuilder setTimestamp(long);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/enterprise/feedback/api/res-1.0.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to enterprise/feedback/api/res-1.0.0-alpha04.txt
diff --git a/enterprise/feedback/api/restricted_1.0.0-alpha04.txt b/enterprise/feedback/api/restricted_1.0.0-alpha04.txt
new file mode 100644
index 0000000..040814c
--- /dev/null
+++ b/enterprise/feedback/api/restricted_1.0.0-alpha04.txt
@@ -0,0 +1,59 @@
+// Signature format: 3.0
+package androidx.enterprise.feedback {
+
+  public abstract class KeyedAppState {
+    method public static androidx.enterprise.feedback.KeyedAppState.KeyedAppStateBuilder builder();
+    method public abstract String? getData();
+    method public abstract String getKey();
+    method public abstract String? getMessage();
+    method public abstract int getSeverity();
+    field public static final int MAX_DATA_LENGTH = 1000; // 0x3e8
+    field public static final int MAX_KEY_LENGTH = 100; // 0x64
+    field public static final int MAX_MESSAGE_LENGTH = 1000; // 0x3e8
+    field public static final int SEVERITY_ERROR = 2; // 0x2
+    field public static final int SEVERITY_INFO = 1; // 0x1
+  }
+
+  public abstract static class KeyedAppState.KeyedAppStateBuilder {
+    method public androidx.enterprise.feedback.KeyedAppState build();
+    method public abstract androidx.enterprise.feedback.KeyedAppState.KeyedAppStateBuilder setData(String?);
+    method public abstract androidx.enterprise.feedback.KeyedAppState.KeyedAppStateBuilder setKey(String);
+    method public abstract androidx.enterprise.feedback.KeyedAppState.KeyedAppStateBuilder setMessage(String?);
+    method public abstract androidx.enterprise.feedback.KeyedAppState.KeyedAppStateBuilder setSeverity(int);
+  }
+
+  public abstract class KeyedAppStatesReporter {
+    method public static androidx.enterprise.feedback.KeyedAppStatesReporter create(android.content.Context);
+    method public static androidx.enterprise.feedback.KeyedAppStatesReporter create(android.content.Context, java.util.concurrent.Executor);
+    method public abstract void setStates(java.util.Collection<androidx.enterprise.feedback.KeyedAppState!>);
+    method public abstract void setStatesImmediate(java.util.Collection<androidx.enterprise.feedback.KeyedAppState!>);
+  }
+
+  public abstract class KeyedAppStatesService extends android.app.Service {
+    ctor public KeyedAppStatesService();
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public abstract void onReceive(java.util.Collection<androidx.enterprise.feedback.ReceivedKeyedAppState!>, boolean);
+  }
+
+  public abstract class ReceivedKeyedAppState {
+    method public static androidx.enterprise.feedback.ReceivedKeyedAppState.ReceivedKeyedAppStateBuilder builder();
+    method public abstract String? getData();
+    method public abstract String getKey();
+    method public abstract String? getMessage();
+    method public abstract String getPackageName();
+    method public abstract int getSeverity();
+    method public abstract long getTimestamp();
+  }
+
+  public abstract static class ReceivedKeyedAppState.ReceivedKeyedAppStateBuilder {
+    method public abstract androidx.enterprise.feedback.ReceivedKeyedAppState build();
+    method public abstract androidx.enterprise.feedback.ReceivedKeyedAppState.ReceivedKeyedAppStateBuilder setData(String?);
+    method public abstract androidx.enterprise.feedback.ReceivedKeyedAppState.ReceivedKeyedAppStateBuilder setKey(String);
+    method public abstract androidx.enterprise.feedback.ReceivedKeyedAppState.ReceivedKeyedAppStateBuilder setMessage(String?);
+    method public abstract androidx.enterprise.feedback.ReceivedKeyedAppState.ReceivedKeyedAppStateBuilder setPackageName(String);
+    method public abstract androidx.enterprise.feedback.ReceivedKeyedAppState.ReceivedKeyedAppStateBuilder setSeverity(int);
+    method public abstract androidx.enterprise.feedback.ReceivedKeyedAppState.ReceivedKeyedAppStateBuilder setTimestamp(long);
+  }
+
+}
+
diff --git a/enterprise/feedback/testing/api/1.0.0-alpha04.txt b/enterprise/feedback/testing/api/1.0.0-alpha04.txt
new file mode 100644
index 0000000..9c90bc0
--- /dev/null
+++ b/enterprise/feedback/testing/api/1.0.0-alpha04.txt
@@ -0,0 +1,17 @@
+// Signature format: 3.0
+package androidx.enterprise.feedback {
+
+  public class FakeKeyedAppStatesReporter extends androidx.enterprise.feedback.KeyedAppStatesReporter {
+    method public java.util.List<androidx.enterprise.feedback.KeyedAppState!> getKeyedAppStates();
+    method public java.util.Map<java.lang.String!,androidx.enterprise.feedback.KeyedAppState!> getKeyedAppStatesByKey();
+    method public int getNumberOfUploads();
+    method public java.util.List<androidx.enterprise.feedback.KeyedAppState!> getOnDeviceKeyedAppStates();
+    method public java.util.Map<java.lang.String!,androidx.enterprise.feedback.KeyedAppState!> getOnDeviceKeyedAppStatesByKey();
+    method public java.util.List<androidx.enterprise.feedback.KeyedAppState!> getUploadedKeyedAppStates();
+    method public java.util.Map<java.lang.String!,androidx.enterprise.feedback.KeyedAppState!> getUploadedKeyedAppStatesByKey();
+    method public void setStates(java.util.Collection<androidx.enterprise.feedback.KeyedAppState!>);
+    method public void setStatesImmediate(java.util.Collection<androidx.enterprise.feedback.KeyedAppState!>);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/enterprise/feedback/testing/api/res-1.0.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to enterprise/feedback/testing/api/res-1.0.0-alpha04.txt
diff --git a/enterprise/feedback/testing/api/restricted_1.0.0-alpha04.txt b/enterprise/feedback/testing/api/restricted_1.0.0-alpha04.txt
new file mode 100644
index 0000000..9c90bc0
--- /dev/null
+++ b/enterprise/feedback/testing/api/restricted_1.0.0-alpha04.txt
@@ -0,0 +1,17 @@
+// Signature format: 3.0
+package androidx.enterprise.feedback {
+
+  public class FakeKeyedAppStatesReporter extends androidx.enterprise.feedback.KeyedAppStatesReporter {
+    method public java.util.List<androidx.enterprise.feedback.KeyedAppState!> getKeyedAppStates();
+    method public java.util.Map<java.lang.String!,androidx.enterprise.feedback.KeyedAppState!> getKeyedAppStatesByKey();
+    method public int getNumberOfUploads();
+    method public java.util.List<androidx.enterprise.feedback.KeyedAppState!> getOnDeviceKeyedAppStates();
+    method public java.util.Map<java.lang.String!,androidx.enterprise.feedback.KeyedAppState!> getOnDeviceKeyedAppStatesByKey();
+    method public java.util.List<androidx.enterprise.feedback.KeyedAppState!> getUploadedKeyedAppStates();
+    method public java.util.Map<java.lang.String!,androidx.enterprise.feedback.KeyedAppState!> getUploadedKeyedAppStatesByKey();
+    method public void setStates(java.util.Collection<androidx.enterprise.feedback.KeyedAppState!>);
+    method public void setStatesImmediate(java.util.Collection<androidx.enterprise.feedback.KeyedAppState!>);
+  }
+
+}
+
diff --git a/exifinterface/api/api_lint.ignore b/exifinterface/api/api_lint.ignore
index e0f65e9..32b350e 100644
--- a/exifinterface/api/api_lint.ignore
+++ b/exifinterface/api/api_lint.ignore
@@ -1,3 +1,15 @@
 // Baseline format: 1.0
+MissingNullability: androidx.exifinterface.media.ExifInterface#BITS_PER_SAMPLE_GREYSCALE_1:
+    Missing nullability on field `BITS_PER_SAMPLE_GREYSCALE_1` in class `class androidx.exifinterface.media.ExifInterface`
+MissingNullability: androidx.exifinterface.media.ExifInterface#BITS_PER_SAMPLE_GREYSCALE_2:
+    Missing nullability on field `BITS_PER_SAMPLE_GREYSCALE_2` in class `class androidx.exifinterface.media.ExifInterface`
+MissingNullability: androidx.exifinterface.media.ExifInterface#BITS_PER_SAMPLE_RGB:
+    Missing nullability on field `BITS_PER_SAMPLE_RGB` in class `class androidx.exifinterface.media.ExifInterface`
+MissingNullability: androidx.exifinterface.media.ExifInterface#getLatLong(float[]) parameter #0:
+    Missing nullability on parameter `output` in method `getLatLong`
+MissingNullability: androidx.exifinterface.media.ExifInterface#setGpsInfo(android.location.Location) parameter #0:
+    Missing nullability on parameter `location` in method `setGpsInfo`
+
+
 NoClone: androidx.exifinterface.media.ExifInterface#ExifInterface(java.io.FileDescriptor) parameter #0:
     Must use ParcelFileDescriptor instead of FileDescriptor in parameter fileDescriptor in androidx.exifinterface.media.ExifInterface(java.io.FileDescriptor fileDescriptor)
diff --git a/fragment/fragment-ktx/api/1.2.0-alpha03.txt b/fragment/fragment-ktx/api/1.2.0-alpha03.txt
new file mode 100644
index 0000000..ab3b3b7
--- /dev/null
+++ b/fragment/fragment-ktx/api/1.2.0-alpha03.txt
@@ -0,0 +1,31 @@
+// Signature format: 3.0
+package androidx.fragment.app {
+
+  public final class FragmentManagerKt {
+    ctor public FragmentManagerKt();
+    method public static inline void commit(androidx.fragment.app.FragmentManager, boolean allowStateLoss = false, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
+    method public static inline void commitNow(androidx.fragment.app.FragmentManager, boolean allowStateLoss = false, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
+    method @Deprecated public static inline void transaction(androidx.fragment.app.FragmentManager, boolean now = false, boolean allowStateLoss = false, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
+  }
+
+  public final class FragmentTransactionKt {
+    ctor public FragmentTransactionKt();
+    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction add(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, String? tag = null, android.os.Bundle? args = null);
+    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction add(androidx.fragment.app.FragmentTransaction, String tag, android.os.Bundle? args = null);
+    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction replace(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, String? tag = null, android.os.Bundle? args = null);
+  }
+
+  public final class FragmentViewModelLazyKt {
+    ctor public FragmentViewModelLazyKt();
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> activityViewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+    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, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> viewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner> ownerProducer = { this }, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+  }
+
+  public final class ViewKt {
+    ctor public ViewKt();
+    method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha03.txt b/fragment/fragment-ktx/api/res-1.2.0-alpha03.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha03.txt
copy to fragment/fragment-ktx/api/res-1.2.0-alpha03.txt
diff --git a/fragment/fragment-ktx/api/restricted_1.2.0-alpha03.txt b/fragment/fragment-ktx/api/restricted_1.2.0-alpha03.txt
new file mode 100644
index 0000000..ab3b3b7
--- /dev/null
+++ b/fragment/fragment-ktx/api/restricted_1.2.0-alpha03.txt
@@ -0,0 +1,31 @@
+// Signature format: 3.0
+package androidx.fragment.app {
+
+  public final class FragmentManagerKt {
+    ctor public FragmentManagerKt();
+    method public static inline void commit(androidx.fragment.app.FragmentManager, boolean allowStateLoss = false, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
+    method public static inline void commitNow(androidx.fragment.app.FragmentManager, boolean allowStateLoss = false, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
+    method @Deprecated public static inline void transaction(androidx.fragment.app.FragmentManager, boolean now = false, boolean allowStateLoss = false, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
+  }
+
+  public final class FragmentTransactionKt {
+    ctor public FragmentTransactionKt();
+    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction add(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, String? tag = null, android.os.Bundle? args = null);
+    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction add(androidx.fragment.app.FragmentTransaction, String tag, android.os.Bundle? args = null);
+    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction replace(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, String? tag = null, android.os.Bundle? args = null);
+  }
+
+  public final class FragmentViewModelLazyKt {
+    ctor public FragmentViewModelLazyKt();
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> activityViewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+    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, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> viewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner> ownerProducer = { this }, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+  }
+
+  public final class ViewKt {
+    ctor public ViewKt();
+    method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
+  }
+
+}
+
diff --git a/fragment/fragment-testing/api/1.2.0-alpha03.txt b/fragment/fragment-testing/api/1.2.0-alpha03.txt
new file mode 100644
index 0000000..873d5c8
--- /dev/null
+++ b/fragment/fragment-testing/api/1.2.0-alpha03.txt
@@ -0,0 +1,31 @@
+// Signature format: 3.0
+package androidx.fragment.app.testing {
+
+  public final class FragmentScenario<F extends androidx.fragment.app.Fragment> {
+    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>);
+    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>, android.os.Bundle?);
+    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>, android.os.Bundle?, androidx.fragment.app.FragmentFactory?);
+    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>, android.os.Bundle?, @StyleRes int, androidx.fragment.app.FragmentFactory?);
+    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>);
+    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>, android.os.Bundle?);
+    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>, android.os.Bundle?, androidx.fragment.app.FragmentFactory?);
+    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>, android.os.Bundle?, @StyleRes int, androidx.fragment.app.FragmentFactory?);
+    method public androidx.fragment.app.testing.FragmentScenario<F!> moveToState(androidx.lifecycle.Lifecycle.State);
+    method public androidx.fragment.app.testing.FragmentScenario<F!> onFragment(androidx.fragment.app.testing.FragmentScenario.FragmentAction<F!>);
+    method public androidx.fragment.app.testing.FragmentScenario<F!> recreate();
+  }
+
+  public static interface FragmentScenario.FragmentAction<F extends androidx.fragment.app.Fragment> {
+    method public void perform(F);
+  }
+
+  public final class FragmentScenarioKt {
+    ctor public FragmentScenarioKt();
+    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragment(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, androidx.fragment.app.FragmentFactory? factory = null);
+    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragment(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, 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(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, androidx.fragment.app.FragmentFactory? factory = null);
+    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragmentInContainer(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, kotlin.jvm.functions.Function0<? extends F> instantiate);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha03.txt b/fragment/fragment-testing/api/res-1.2.0-alpha03.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha03.txt
copy to fragment/fragment-testing/api/res-1.2.0-alpha03.txt
diff --git a/fragment/fragment-testing/api/restricted_1.2.0-alpha03.txt b/fragment/fragment-testing/api/restricted_1.2.0-alpha03.txt
new file mode 100644
index 0000000..7042bb9
--- /dev/null
+++ b/fragment/fragment-testing/api/restricted_1.2.0-alpha03.txt
@@ -0,0 +1,33 @@
+// Signature format: 3.0
+package androidx.fragment.app.testing {
+
+  public final class FragmentScenario<F extends androidx.fragment.app.Fragment> {
+    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>);
+    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>, android.os.Bundle?);
+    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>, android.os.Bundle?, androidx.fragment.app.FragmentFactory?);
+    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>, android.os.Bundle?, @StyleRes int, androidx.fragment.app.FragmentFactory?);
+    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>);
+    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>, android.os.Bundle?);
+    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>, android.os.Bundle?, androidx.fragment.app.FragmentFactory?);
+    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>, android.os.Bundle?, @StyleRes int, androidx.fragment.app.FragmentFactory?);
+    method public androidx.fragment.app.testing.FragmentScenario<F!> moveToState(androidx.lifecycle.Lifecycle.State);
+    method public androidx.fragment.app.testing.FragmentScenario<F!> onFragment(androidx.fragment.app.testing.FragmentScenario.FragmentAction<F!>);
+    method public androidx.fragment.app.testing.FragmentScenario<F!> recreate();
+  }
+
+
+  public static interface FragmentScenario.FragmentAction<F extends androidx.fragment.app.Fragment> {
+    method public void perform(F);
+  }
+
+
+  public final class FragmentScenarioKt {
+    ctor public FragmentScenarioKt();
+    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragment(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, androidx.fragment.app.FragmentFactory? factory = null);
+    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragment(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, 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(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, androidx.fragment.app.FragmentFactory? factory = null);
+    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragmentInContainer(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, kotlin.jvm.functions.Function0<? extends F> instantiate);
+  }
+
+}
+
diff --git a/fragment/fragment/api/1.2.0-alpha03.txt b/fragment/fragment/api/1.2.0-alpha03.txt
new file mode 100644
index 0000000..672cb24
--- /dev/null
+++ b/fragment/fragment/api/1.2.0-alpha03.txt
@@ -0,0 +1,425 @@
+// Signature format: 3.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();
+    method public void dismiss();
+    method public void dismissAllowingStateLoss();
+    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 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 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 Object? getReenterTransition();
+    method public final android.content.res.Resources getResources();
+    method 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 public final androidx.fragment.app.Fragment? getTargetFragment();
+    method 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 @MainThread @CallSuper public void onActivityCreated(android.os.Bundle?);
+    method public void onActivityResult(int, int, android.content.Intent?);
+    method @MainThread @CallSuper public void onAttach(android.content.Context);
+    method @Deprecated @CallSuper @MainThread public void onAttach(android.app.Activity);
+    method @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 @MainThread @CallSuper 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 @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 @MainThread @CallSuper public void onDestroy();
+    method @MainThread public void onDestroyOptionsMenu();
+    method @MainThread @CallSuper public void onDestroyView();
+    method @MainThread @CallSuper public void onDetach();
+    method public android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle?);
+    method @MainThread public void onHiddenChanged(boolean);
+    method @UiThread @CallSuper 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 @MainThread public boolean onOptionsItemSelected(android.view.MenuItem);
+    method @MainThread public void onOptionsMenuClosed(android.view.Menu);
+    method @MainThread @CallSuper public void onPause();
+    method public void onPictureInPictureModeChanged(boolean);
+    method @MainThread public void onPrepareOptionsMenu(android.view.Menu);
+    method @MainThread public void onPrimaryNavigationFragmentChanged(boolean);
+    method public void onRequestPermissionsResult(int, String![], int[]);
+    method @MainThread @CallSuper public void onResume();
+    method @MainThread public void onSaveInstanceState(android.os.Bundle);
+    method @MainThread @CallSuper public void onStart();
+    method @MainThread @CallSuper public void onStop();
+    method @MainThread public void onViewCreated(android.view.View, android.os.Bundle?);
+    method @MainThread @CallSuper public void onViewStateRestored(android.os.Bundle?);
+    method public void postponeEnterTransition();
+    method public final void postponeEnterTransition(long, java.util.concurrent.TimeUnit);
+    method public void registerForContextMenu(android.view.View);
+    method 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 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 public void setHasOptionsMenu(boolean);
+    method public void setInitialSavedState(androidx.fragment.app.Fragment.SavedState?);
+    method public void setMenuVisibility(boolean);
+    method public void setReenterTransition(Object?);
+    method public void setRetainInstance(boolean);
+    method public void setReturnTransition(Object?);
+    method public void setSharedElementEnterTransition(Object?);
+    method public void setSharedElementReturnTransition(Object?);
+    method 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 public void startActivityForResult(android.content.Intent!, int);
+    method public void startActivityForResult(android.content.Intent!, int, android.os.Bundle?);
+    method 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 public void onAttachFragment(androidx.fragment.app.Fragment);
+    method @CallSuper public void onMultiWindowModeChanged(boolean);
+    method @CallSuper public void onPictureInPictureModeChanged(boolean);
+    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 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 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 class FragmentContainerView extends android.widget.FrameLayout {
+    ctor public FragmentContainerView(android.content.Context);
+    ctor public FragmentContainerView(android.content.Context, android.util.AttributeSet?);
+    ctor public FragmentContainerView(android.content.Context, android.util.AttributeSet?, int);
+  }
+
+  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 public void dispatchConfigurationChanged(android.content.res.Configuration);
+    method public boolean dispatchContextItemSelected(android.view.MenuItem);
+    method public void dispatchCreate();
+    method public boolean dispatchCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
+    method public void dispatchDestroy();
+    method public void dispatchDestroyView();
+    method public void dispatchLowMemory();
+    method public void dispatchMultiWindowModeChanged(boolean);
+    method public boolean dispatchOptionsItemSelected(android.view.MenuItem);
+    method public void dispatchOptionsMenuClosed(android.view.Menu);
+    method public void dispatchPause();
+    method public void dispatchPictureInPictureModeChanged(boolean);
+    method 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 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 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 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 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 {
+    ctor public FragmentManager();
+    method public void addOnBackStackChangedListener(androidx.fragment.app.FragmentManager.OnBackStackChangedListener);
+    method public androidx.fragment.app.FragmentTransaction beginTransaction();
+    method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
+    method 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 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 removeOnBackStackChangedListener(androidx.fragment.app.FragmentManager.OnBackStackChangedListener);
+    method public androidx.fragment.app.Fragment.SavedState? saveFragmentInstanceState(androidx.fragment.app.Fragment);
+    method public void setFragmentFactory(androidx.fragment.app.FragmentFactory);
+    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 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 abstract class FragmentPagerAdapter extends androidx.viewpager.widget.PagerAdapter {
+    ctor @Deprecated public FragmentPagerAdapter(androidx.fragment.app.FragmentManager);
+    ctor public FragmentPagerAdapter(androidx.fragment.app.FragmentManager, int);
+    method public abstract androidx.fragment.app.Fragment getItem(int);
+    method public long getItemId(int);
+    method public boolean isViewFromObject(android.view.View, Object);
+    field 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 abstract class FragmentStatePagerAdapter extends androidx.viewpager.widget.PagerAdapter {
+    ctor @Deprecated public FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager);
+    ctor public FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager, int);
+    method public abstract androidx.fragment.app.Fragment getItem(int);
+    method public boolean isViewFromObject(android.view.View, Object);
+    field 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(@AnimatorRes @AnimRes int, @AnimatorRes @AnimRes int);
+    method public androidx.fragment.app.FragmentTransaction setCustomAnimations(@AnimatorRes @AnimRes int, @AnimatorRes @AnimRes int, @AnimatorRes @AnimRes int, @AnimatorRes @AnimRes 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_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);
+  }
+
+}
+
diff --git a/fragment/fragment/api/api_lint.ignore b/fragment/fragment/api/api_lint.ignore
index ad3841c..90d42d8 100644
--- a/fragment/fragment/api/api_lint.ignore
+++ b/fragment/fragment/api/api_lint.ignore
@@ -15,6 +15,46 @@
     FragmentActivity should not extend `Activity`. Activity subclasses are impossible to compose. Expose a composable API instead.
 
 
+MissingNullability: androidx.fragment.app.Fragment#startActivity(android.content.Intent) parameter #0:
+    Missing nullability on parameter `intent` in method `startActivity`
+MissingNullability: androidx.fragment.app.Fragment#startActivity(android.content.Intent, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `intent` in method `startActivity`
+MissingNullability: androidx.fragment.app.Fragment#startActivityForResult(android.content.Intent, int) parameter #0:
+    Missing nullability on parameter `intent` in method `startActivityForResult`
+MissingNullability: androidx.fragment.app.Fragment#startActivityForResult(android.content.Intent, int, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `intent` in method `startActivityForResult`
+MissingNullability: androidx.fragment.app.Fragment#startIntentSenderForResult(android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `intent` in method `startIntentSenderForResult`
+MissingNullability: androidx.fragment.app.FragmentActivity#onNewIntent(android.content.Intent) parameter #0:
+    Missing nullability on parameter `intent` in method `onNewIntent`
+MissingNullability: androidx.fragment.app.FragmentActivity#startActivityForResult(android.content.Intent, int) parameter #0:
+    Missing nullability on parameter `intent` in method `startActivityForResult`
+MissingNullability: androidx.fragment.app.FragmentActivity#startActivityForResult(android.content.Intent, int, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `intent` in method `startActivityForResult`
+MissingNullability: androidx.fragment.app.FragmentActivity#startActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent, int) parameter #1:
+    Missing nullability on parameter `intent` in method `startActivityFromFragment`
+MissingNullability: androidx.fragment.app.FragmentActivity#startActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent, int, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `intent` in method `startActivityFromFragment`
+MissingNullability: androidx.fragment.app.FragmentActivity#startIntentSenderForResult(android.content.IntentSender, int, android.content.Intent, int, int, int) parameter #0:
+    Missing nullability on parameter `intent` in method `startIntentSenderForResult`
+MissingNullability: androidx.fragment.app.FragmentActivity#startIntentSenderForResult(android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `intent` in method `startIntentSenderForResult`
+MissingNullability: androidx.fragment.app.FragmentActivity#startIntentSenderFromFragment(androidx.fragment.app.Fragment, android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `intent` in method `startIntentSenderFromFragment`
+MissingNullability: androidx.fragment.app.FragmentController#getActiveFragments(java.util.List<androidx.fragment.app.Fragment>) parameter #0:
+    Missing nullability on parameter `actives` in method `getActiveFragments`
+MissingNullability: androidx.fragment.app.FragmentController#restoreLoaderNonConfig(androidx.collection.SimpleArrayMap<java.lang.String,androidx.loader.app.LoaderManager>) parameter #0:
+    Missing nullability on parameter `loaderManagers` in method `restoreLoaderNonConfig`
+MissingNullability: androidx.fragment.app.FragmentHostCallback#onStartActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent, int) parameter #1:
+    Missing nullability on parameter `intent` in method `onStartActivityFromFragment`
+MissingNullability: androidx.fragment.app.FragmentHostCallback#onStartActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent, int, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `intent` in method `onStartActivityFromFragment`
+MissingNullability: androidx.fragment.app.FragmentHostCallback#onStartIntentSenderFromFragment(androidx.fragment.app.Fragment, android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `intent` in method `onStartIntentSenderFromFragment`
+MissingNullability: androidx.fragment.app.FragmentTabHost#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+
+
 NoClone: androidx.fragment.app.Fragment#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
     Must use ParcelFileDescriptor instead of FileDescriptor in parameter fd in androidx.fragment.app.Fragment.dump(String prefix, java.io.FileDescriptor fd, java.io.PrintWriter writer, String[] args)
 NoClone: androidx.fragment.app.FragmentActivity#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
diff --git a/preference/ktx/api/res-1.1.0-alpha03.txt b/fragment/fragment/api/res-1.2.0-alpha03.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha03.txt
copy to fragment/fragment/api/res-1.2.0-alpha03.txt
diff --git a/fragment/fragment/api/restricted_1.2.0-alpha03.txt b/fragment/fragment/api/restricted_1.2.0-alpha03.txt
new file mode 100644
index 0000000..b1f0d5f
--- /dev/null
+++ b/fragment/fragment/api/restricted_1.2.0-alpha03.txt
@@ -0,0 +1,454 @@
+// Signature format: 3.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();
+    method public void dismiss();
+    method public void dismissAllowingStateLoss();
+    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 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 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 Object? getReenterTransition();
+    method public final android.content.res.Resources getResources();
+    method 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 public final androidx.fragment.app.Fragment? getTargetFragment();
+    method 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 @MainThread @CallSuper public void onActivityCreated(android.os.Bundle?);
+    method public void onActivityResult(int, int, android.content.Intent?);
+    method @MainThread @CallSuper public void onAttach(android.content.Context);
+    method @Deprecated @CallSuper @MainThread public void onAttach(android.app.Activity);
+    method @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 @MainThread @CallSuper 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 @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 @MainThread @CallSuper public void onDestroy();
+    method @MainThread public void onDestroyOptionsMenu();
+    method @MainThread @CallSuper public void onDestroyView();
+    method @MainThread @CallSuper public void onDetach();
+    method public android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle?);
+    method @MainThread public void onHiddenChanged(boolean);
+    method @UiThread @CallSuper 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 @MainThread public boolean onOptionsItemSelected(android.view.MenuItem);
+    method @MainThread public void onOptionsMenuClosed(android.view.Menu);
+    method @MainThread @CallSuper public void onPause();
+    method public void onPictureInPictureModeChanged(boolean);
+    method @MainThread public void onPrepareOptionsMenu(android.view.Menu);
+    method @MainThread public void onPrimaryNavigationFragmentChanged(boolean);
+    method public void onRequestPermissionsResult(int, String![], int[]);
+    method @MainThread @CallSuper public void onResume();
+    method @MainThread public void onSaveInstanceState(android.os.Bundle);
+    method @MainThread @CallSuper public void onStart();
+    method @MainThread @CallSuper public void onStop();
+    method @MainThread public void onViewCreated(android.view.View, android.os.Bundle?);
+    method @MainThread @CallSuper public void onViewStateRestored(android.os.Bundle?);
+    method public void postponeEnterTransition();
+    method public final void postponeEnterTransition(long, java.util.concurrent.TimeUnit);
+    method public void registerForContextMenu(android.view.View);
+    method 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 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 public void setHasOptionsMenu(boolean);
+    method public void setInitialSavedState(androidx.fragment.app.Fragment.SavedState?);
+    method public void setMenuVisibility(boolean);
+    method public void setReenterTransition(Object?);
+    method public void setRetainInstance(boolean);
+    method public void setReturnTransition(Object?);
+    method public void setSharedElementEnterTransition(Object?);
+    method public void setSharedElementReturnTransition(Object?);
+    method 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 public void startActivityForResult(android.content.Intent!, int);
+    method public void startActivityForResult(android.content.Intent!, int, android.os.Bundle?);
+    method 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 public void onAttachFragment(androidx.fragment.app.Fragment);
+    method @CallSuper public void onMultiWindowModeChanged(boolean);
+    method @CallSuper public void onPictureInPictureModeChanged(boolean);
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) protected boolean onPrepareOptionsPanel(android.view.View?, android.view.Menu);
+    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 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 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 class FragmentContainerView extends android.widget.FrameLayout {
+    ctor public FragmentContainerView(android.content.Context);
+    ctor public FragmentContainerView(android.content.Context, android.util.AttributeSet?);
+    ctor public FragmentContainerView(android.content.Context, android.util.AttributeSet?, int);
+  }
+
+  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 public void dispatchConfigurationChanged(android.content.res.Configuration);
+    method public boolean dispatchContextItemSelected(android.view.MenuItem);
+    method public void dispatchCreate();
+    method public boolean dispatchCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
+    method public void dispatchDestroy();
+    method public void dispatchDestroyView();
+    method public void dispatchLowMemory();
+    method public void dispatchMultiWindowModeChanged(boolean);
+    method public boolean dispatchOptionsItemSelected(android.view.MenuItem);
+    method public void dispatchOptionsMenuClosed(android.view.Menu);
+    method public void dispatchPause();
+    method public void dispatchPictureInPictureModeChanged(boolean);
+    method 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 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 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 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 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 {
+    ctor public FragmentManager();
+    method public void addOnBackStackChangedListener(androidx.fragment.app.FragmentManager.OnBackStackChangedListener);
+    method public androidx.fragment.app.FragmentTransaction beginTransaction();
+    method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
+    method 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 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 removeOnBackStackChangedListener(androidx.fragment.app.FragmentManager.OnBackStackChangedListener);
+    method public androidx.fragment.app.Fragment.SavedState? saveFragmentInstanceState(androidx.fragment.app.Fragment);
+    method public void setFragmentFactory(androidx.fragment.app.FragmentFactory);
+    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 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 abstract class FragmentPagerAdapter extends androidx.viewpager.widget.PagerAdapter {
+    ctor @Deprecated public FragmentPagerAdapter(androidx.fragment.app.FragmentManager);
+    ctor public FragmentPagerAdapter(androidx.fragment.app.FragmentManager, int);
+    method public abstract androidx.fragment.app.Fragment getItem(int);
+    method public long getItemId(int);
+    method public boolean isViewFromObject(android.view.View, Object);
+    field 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 abstract class FragmentStatePagerAdapter extends androidx.viewpager.widget.PagerAdapter {
+    ctor @Deprecated public FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager);
+    ctor public FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager, int);
+    method public abstract androidx.fragment.app.Fragment getItem(int);
+    method public boolean isViewFromObject(android.view.View, Object);
+    field 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(@AnimatorRes @AnimRes int, @AnimatorRes @AnimRes int);
+    method public androidx.fragment.app.FragmentTransaction setCustomAnimations(@AnimatorRes @AnimRes int, @AnimatorRes @AnimRes int, @AnimatorRes @AnimRes int, @AnimatorRes @AnimRes 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_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 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);
+  }
+
+}
+
diff --git a/fragment/fragment/lint-baseline.xml b/fragment/fragment/lint-baseline.xml
deleted file mode 100644
index 8a8c65d..0000000
--- a/fragment/fragment/lint-baseline.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  Copyright 2019 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.
-  -->
-
-<issues format="5" by="lint 3.5.0-beta04" client="gradle" variant="debug" version="3.5.0-beta04">
-
-    <issue
-        id="KotlinPropertyAccess"
-        message="This method should be called `getHasOptionsMenu` such that `hasOptionsMenu` can be accessed as a property from Kotlin; see https://android.github.io/kotlin-guides/interop.html#property-prefixes"
-        errorLine1="    final public boolean hasOptionsMenu() {"
-        errorLine2="                         ~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/fragment/app/Fragment.java"
-            line="1018"
-            column="26"/>
-    </issue>
-
-</issues>
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt
index 5d7c1ac..83fd843 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt
@@ -69,7 +69,7 @@
         waitForAnimationReady()
         val fm = activityRule.activity.supportFragmentManager
 
-        val fragment = AnimatorFragment()
+        val fragment = AnimationFragment()
         fm.beginTransaction()
             .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
             .add(R.id.fragmentContainer, fragment)
@@ -86,7 +86,7 @@
         waitForAnimationReady()
         val fm = activityRule.activity.supportFragmentManager
 
-        val fragment = AnimatorFragment()
+        val fragment = AnimationFragment()
         fm.beginTransaction().add(R.id.fragmentContainer, fragment, "1").commit()
         activityRule.waitForExecution()
 
@@ -106,7 +106,7 @@
         waitForAnimationReady()
         val fm = activityRule.activity.supportFragmentManager
 
-        val fragment = AnimatorFragment()
+        val fragment = AnimationFragment()
         fm.beginTransaction().add(R.id.fragmentContainer, fragment).hide(fragment).commit()
         activityRule.waitForExecution()
 
@@ -126,7 +126,7 @@
         waitForAnimationReady()
         val fm = activityRule.activity.supportFragmentManager
 
-        val fragment = AnimatorFragment()
+        val fragment = AnimationFragment()
         fm.beginTransaction().add(R.id.fragmentContainer, fragment, "1").commit()
         activityRule.waitForExecution()
 
@@ -146,7 +146,7 @@
         waitForAnimationReady()
         val fm = activityRule.activity.supportFragmentManager
 
-        val fragment = AnimatorFragment()
+        val fragment = AnimationFragment()
         fm.beginTransaction().add(R.id.fragmentContainer, fragment).detach(fragment).commit()
         activityRule.waitForExecution()
 
@@ -166,7 +166,7 @@
         waitForAnimationReady()
         val fm = activityRule.activity.supportFragmentManager
 
-        val fragment = AnimatorFragment()
+        val fragment = AnimationFragment()
         fm.beginTransaction().add(R.id.fragmentContainer, fragment, "1").commit()
         activityRule.waitForExecution()
 
@@ -187,15 +187,15 @@
         waitForAnimationReady()
         val fm = activityRule.activity.supportFragmentManager
 
-        val fragment1 = AnimatorFragment()
-        val fragment2 = AnimatorFragment()
+        val fragment1 = AnimationFragment()
+        val fragment2 = AnimationFragment()
         fm.beginTransaction()
             .add(R.id.fragmentContainer, fragment1, "1")
             .add(R.id.fragmentContainer, fragment2, "2")
             .commit()
         activityRule.waitForExecution()
 
-        val fragment3 = AnimatorFragment()
+        val fragment3 = AnimationFragment()
         fm.beginTransaction()
             .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
             .replace(R.id.fragmentContainer, fragment3)
@@ -211,8 +211,8 @@
         activityRule.waitForExecution()
 
         assertFragmentAnimation(fragment3, 2, false, POP_EXIT)
-        val replacement1 = fm.findFragmentByTag("1") as AnimatorFragment?
-        val replacement2 = fm.findFragmentByTag("1") as AnimatorFragment?
+        val replacement1 = fm.findFragmentByTag("1") as AnimationFragment?
+        val replacement2 = fm.findFragmentByTag("1") as AnimationFragment?
         val expectedAnimations = if (replacement1 === fragment1) 2 else 1
         assertFragmentAnimation(replacement1!!, expectedAnimations, true, POP_ENTER)
         assertFragmentAnimation(replacement2!!, expectedAnimations, true, POP_ENTER)
@@ -224,14 +224,14 @@
         waitForAnimationReady()
         val fm = activityRule.activity.supportFragmentManager
 
-        val parent = AnimatorFragment(R.layout.simple_container)
+        val parent = AnimationFragment(R.layout.simple_container)
         fm.beginTransaction()
             .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
             .add(R.id.fragmentContainer, parent, "parent")
             .commit()
         activityRule.executePendingTransactions()
 
-        val child = AnimatorFragment()
+        val child = AnimationFragment()
         parent.childFragmentManager.beginTransaction()
             .add(R.id.fragmentContainer, child, "child")
             .commit()
@@ -242,7 +242,7 @@
 
         fm.beginTransaction()
             .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
-            .replace(R.id.fragmentContainer, AnimatorFragment(), "other")
+            .replace(R.id.fragmentContainer, AnimationFragment(), "other")
             .commit()
         activityRule.executePendingTransactions()
 
@@ -256,20 +256,20 @@
         waitForAnimationReady()
         val fm = activityRule.activity.supportFragmentManager
 
-        val parent = AnimatorFragment(R.layout.simple_container)
+        val parent = AnimationFragment(R.layout.simple_container)
         fm.beginTransaction()
             .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
             .add(R.id.fragmentContainer, parent, "parent")
             .commit()
         activityRule.executePendingTransactions()
 
-        val child = AnimatorFragment(R.layout.simple_container)
+        val child = AnimationFragment(R.layout.simple_container)
         parent.childFragmentManager.beginTransaction()
             .add(R.id.fragmentContainer, child, "child")
             .commit()
         activityRule.executePendingTransactions(parent.childFragmentManager)
 
-        val grandChild = AnimatorFragment()
+        val grandChild = AnimationFragment()
         child.childFragmentManager.beginTransaction()
             .add(R.id.fragmentContainer, grandChild, "grandChild")
             .commit()
@@ -283,7 +283,7 @@
 
         fm.beginTransaction()
             .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
-            .replace(R.id.fragmentContainer, AnimatorFragment(), "other")
+            .replace(R.id.fragmentContainer, AnimationFragment(), "other")
             .commit()
         activityRule.executePendingTransactions()
 
@@ -299,7 +299,7 @@
         waitForAnimationReady()
         val fm = activityRule.activity.supportFragmentManager
 
-        val fragment = AnimatorFragment()
+        val fragment = AnimationFragment()
         fragment.postponeEnterTransition()
         fm.beginTransaction()
             .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
@@ -323,7 +323,7 @@
         waitForAnimationReady()
         val fm = activityRule.activity.supportFragmentManager
 
-        val fragment = AnimatorFragment()
+        val fragment = AnimationFragment()
         fm.beginTransaction().add(R.id.fragmentContainer, fragment, "1").commit()
         activityRule.waitForExecution()
 
@@ -345,7 +345,7 @@
         waitForAnimationReady()
         val fm = activityRule.activity.supportFragmentManager
 
-        val fragment1 = AnimatorFragment()
+        val fragment1 = AnimationFragment()
         fm.beginTransaction()
             .add(R.id.fragmentContainer, fragment1)
             .addToBackStack(null)
@@ -353,7 +353,7 @@
             .commit()
         activityRule.waitForExecution()
 
-        val fragment2 = AnimatorFragment()
+        val fragment2 = AnimationFragment()
         fragment2.postponeEnterTransition()
 
         fm.beginTransaction()
@@ -383,7 +383,7 @@
         waitForAnimationReady()
         val fm = activityRule.activity.supportFragmentManager
 
-        val fragment1 = AnimatorFragment()
+        val fragment1 = AnimationFragment()
         fm.beginTransaction()
             .add(R.id.fragmentContainer, fragment1)
             .setReorderingAllowed(true)
@@ -391,7 +391,7 @@
         activityRule.waitForExecution()
         assertThat(fragment1.numAnimators).isEqualTo(0)
 
-        val fragment2 = AnimatorFragment()
+        val fragment2 = AnimationFragment()
         fragment2.postponeEnterTransition()
 
         fm.beginTransaction()
@@ -433,26 +433,26 @@
 
         val fm1 = fc1.supportFragmentManager
 
-        val fragment1 = StrictViewFragment(R.layout.scene1)
+        val fragment1 = AnimationListenerFragment(R.layout.scene1)
         fm1.beginTransaction()
             .add(R.id.fragmentContainer, fragment1, "1")
             .commit()
         activityRule.waitForExecution()
 
-        val fragment2 = StrictViewFragment()
+        val fragment2 = AnimationListenerFragment()
 
         fm1.beginTransaction()
             .setCustomAnimations(0, 0, 0, R.anim.long_fade_out)
             .replace(R.id.fragmentContainer, fragment2, "2")
             .addToBackStack(null)
             .commit()
-        instrumentation.runOnMainSync { fm1.executePendingTransactions() }
-        activityRule.waitForExecution()
+        activityRule.executePendingTransactions(fm1)
 
         fm1.popBackStack()
-
-        instrumentation.runOnMainSync { fm1.executePendingTransactions() }
-        activityRule.waitForExecution()
+        activityRule.executePendingTransactions(fm1)
+        // ensure the animation was started
+        assertThat(fragment2.startAnimationLatch.await(1000, TimeUnit.MILLISECONDS))
+            .isTrue()
         // Now fragment2 should be animating away
         assertThat(fragment2.isAdded).isFalse()
         // still exists because it is animating
@@ -616,7 +616,7 @@
         }
     }
 
-    private fun assertEnterPopExit(fragment: AnimatorFragment) {
+    private fun assertEnterPopExit(fragment: AnimationFragment) {
         assertFragmentAnimation(fragment, 1, true, ENTER)
 
         val fm = activityRule.activity.supportFragmentManager
@@ -626,21 +626,21 @@
         assertFragmentAnimation(fragment, 2, false, POP_EXIT)
     }
 
-    private fun assertExitPopEnter(fragment: AnimatorFragment) {
+    private fun assertExitPopEnter(fragment: AnimationFragment) {
         assertFragmentAnimation(fragment, 1, false, EXIT)
 
         val fm = activityRule.activity.supportFragmentManager
         fm.popBackStack()
         activityRule.waitForExecution()
 
-        val replacement = fm.findFragmentByTag("1") as AnimatorFragment?
+        val replacement = fm.findFragmentByTag("1") as AnimationFragment?
 
         val isSameFragment = replacement === fragment
         val expectedAnimators = if (isSameFragment) 2 else 1
         assertFragmentAnimation(replacement!!, expectedAnimators, true, POP_ENTER)
     }
 
-    private fun assertExitPostponedPopEnter(fragment: AnimatorFragment) {
+    private fun assertExitPostponedPopEnter(fragment: AnimationFragment) {
         assertFragmentAnimation(fragment, 1, false, EXIT)
 
         fragment.postponeEnterTransition()
@@ -654,7 +654,7 @@
     }
 
     private fun assertFragmentAnimation(
-        fragment: AnimatorFragment,
+        fragment: AnimationFragment,
         numAnimators: Int,
         isEnter: Boolean,
         animatorResourceId: Int
@@ -668,7 +668,7 @@
         assertThat(fragment.nextAnim).isEqualTo(0)
     }
 
-    private fun assertPostponed(fragment: AnimatorFragment, expectedAnimators: Int) {
+    private fun assertPostponed(fragment: AnimationFragment, expectedAnimators: Int) {
         assertThat(fragment.onCreateViewCalled).isTrue()
         assertThat(fragment.requireView().visibility).isEqualTo(View.VISIBLE)
         assertThat(fragment.requireView().alpha).isWithin(0f).of(0f)
@@ -697,7 +697,7 @@
         }
     }
 
-    class AnimatorFragment(@LayoutRes contentLayoutId: Int = R.layout.strict_view_fragment) :
+    class AnimationFragment(@LayoutRes contentLayoutId: Int = R.layout.strict_view_fragment) :
         StrictViewFragment(contentLayoutId) {
         var numAnimators: Int = 0
         var animation: Animation? = null
@@ -718,7 +718,9 @@
         }
     }
 
-    class AnimationListenerFragment : StrictViewFragment() {
+    class AnimationListenerFragment(
+        @LayoutRes contentLayoutId: Int = R.layout.strict_view_fragment
+    ) : StrictViewFragment(contentLayoutId) {
         lateinit var createdView: View
         var forceRunOnHwLayer: Boolean = false
         var repeat: Boolean = false
@@ -728,6 +730,7 @@
         var exitStartCount = 0
         var exitRepeatCount = 0
         var exitEndCount = 0
+        val startAnimationLatch = CountDownLatch(1)
         val enterLatch = CountDownLatch(1)
         val exitLatch = CountDownLatch(1)
 
@@ -770,6 +773,7 @@
                         } else {
                             exitStartCount++
                         }
+                        startAnimationLatch.countDown()
                     }
 
                     override fun onAnimationEnd(animation: Animation) {
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimatorTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimatorTest.kt
index c74f1f3..1478ed2 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimatorTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimatorTest.kt
@@ -22,6 +22,7 @@
 import android.os.Build
 import android.view.View
 import androidx.annotation.AnimatorRes
+import androidx.annotation.LayoutRes
 import androidx.annotation.RequiresApi
 import androidx.core.view.ViewCompat
 import androidx.fragment.app.test.FragmentTestActivity
@@ -452,14 +453,14 @@
 
         val fm1 = fc1.supportFragmentManager
 
-        val fragment1 = StrictViewFragment(R.layout.scene1)
+        val fragment1 = AnimatorFragment(R.layout.scene1)
         fm1.beginTransaction()
             .add(R.id.fragmentContainer, fragment1, "1")
             .setReorderingAllowed(true)
             .commit()
         activityRule.waitForExecution()
 
-        val fragment2 = StrictViewFragment()
+        val fragment2 = AnimatorFragment()
 
         fm1.beginTransaction()
             .setCustomAnimations(0, 0, 0, R.animator.slow_fade_out)
@@ -468,12 +469,12 @@
             .setReorderingAllowed(true)
             .commit()
         activityRule.executePendingTransactions(fm1)
-        activityRule.waitForExecution()
 
         fm1.popBackStack()
 
         activityRule.executePendingTransactions(fm1)
-        activityRule.waitForExecution()
+        // ensure the animation was started
+        assertThat(fragment2.wasStarted).isTrue()
         // Now fragment2 should be animating away
         assertThat(fragment2.isAdded).isFalse()
         assertThat(fm1.findFragmentByTag("2"))
@@ -548,7 +549,8 @@
         assertThat(fragment.numAnimators).isEqualTo(expectedAnimators)
     }
 
-    class AnimatorFragment : StrictViewFragment() {
+    class AnimatorFragment(@LayoutRes contentLayoutId: Int = R.layout.strict_view_fragment) :
+        StrictViewFragment(contentLayoutId) {
         var numAnimators: Int = 0
         lateinit var baseAnimator: Animator
         var baseEnter: Boolean = false
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerViewTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerViewTest.kt
index 021ea3c..cad0cce 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerViewTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerViewTest.kt
@@ -26,6 +26,7 @@
 import android.view.View
 import android.view.ViewGroup
 import android.view.WindowInsets
+import android.view.animation.Animation
 import androidx.fragment.app.test.FragmentTestActivity
 import androidx.fragment.test.R
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -243,13 +244,18 @@
 
     @Test
     fun removeAllViewsInLayout() {
+        val removingView1 = ChildView(context)
+        val removingView2 = ChildView(context)
+
         val view = setupRemoveTestsView(
-            FragmentContainerView(context),
-            FragmentContainerView(context)
+            removingView1,
+            removingView2
         )
 
         view.removeAllViewsInLayout()
 
+        assertThat(removingView1.getAnimationCount).isEqualTo(2)
+        assertThat(removingView2.getAnimationCount).isEqualTo(2)
         assertThat(view.childCount).isEqualTo(0)
     }
 
@@ -268,8 +274,8 @@
     }
 
     private fun setupRemoveTestsView(
-        childView1: FragmentContainerView,
-        childView2: FragmentContainerView
+        childView1: View,
+        childView2: View
     ): FragmentContainerView {
         val view = FragmentContainerView(context)
         val fragment1 = Fragment()
@@ -330,10 +336,17 @@
     }
 
     class ChildView(context: Context?) : View(context) {
+        var getAnimationCount = 0
+
         override fun onDraw(canvas: Canvas?) {
             super.onDraw(canvas)
             setDrawnFirstView(this)
         }
+
+        override fun getAnimation(): Animation? {
+            getAnimationCount++
+            return super.getAnimation()
+        }
     }
 
     companion object {
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentLifecycleTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentLifecycleTest.kt
index 167ed52..c71f32c 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentLifecycleTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentLifecycleTest.kt
@@ -604,6 +604,190 @@
             .isNull()
     }
 
+    @Test
+    @UiThreadTest
+    fun popBackStackImmediateAfterSaveState() {
+        val viewModelStore = ViewModelStore()
+        val fc = activityRule.startupFragmentController(viewModelStore)
+        val fm = fc.supportFragmentManager
+
+        val fragment1 = StrictFragment()
+        fragment1.retainInstance = true
+        fm.beginTransaction()
+            .add(fragment1, "1")
+            .commitNow()
+
+        // Now save the state of the FragmentManager
+        fc.dispatchPause()
+        fc.saveAllState()
+
+        val fragment2 = StrictFragment()
+        fragment2.retainInstance = true
+        fm.beginTransaction()
+            .add(fragment2, "2")
+            .commitNowAllowingStateLoss()
+
+        try {
+            fm.popBackStackImmediate()
+            fail("PopBackStackImmediate after saveState should throw IllegalStateException")
+        } catch (e: IllegalStateException) {
+            assertWithMessage("popBackStackImmediate should throw an IllegalStateException")
+                .that(e)
+                .hasMessageThat()
+                .contains("Can not perform this action after onSaveInstanceState")
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun popBackStackAfterSaveState() {
+        val viewModelStore = ViewModelStore()
+        val fc = activityRule.startupFragmentController(viewModelStore)
+        val fm = fc.supportFragmentManager
+
+        val fragment1 = StrictFragment()
+        fragment1.retainInstance = true
+        fm.beginTransaction()
+            .add(fragment1, "1")
+            .commitNow()
+
+        // Now save the state of the FragmentManager
+        fc.dispatchPause()
+        fc.saveAllState()
+
+        val fragment2 = StrictFragment()
+        fragment2.retainInstance = true
+        fm.beginTransaction()
+            .add(fragment2, "2")
+            .commitNowAllowingStateLoss()
+
+        try {
+            fm.popBackStack()
+            fail("PopBackStack after saveState should throw IllegalStateException")
+        } catch (e: IllegalStateException) {
+            assertWithMessage("popBackStack should throw an IllegalStateException")
+                .that(e)
+                .hasMessageThat()
+                .contains("Can not perform this action after onSaveInstanceState")
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun popBackStackAfterManagerDestroyed() {
+        val viewModelStore = ViewModelStore()
+        val fc = activityRule.startupFragmentController(viewModelStore)
+        val fm = fc.supportFragmentManager
+
+        val fragment1 = StrictFragment()
+        fragment1.retainInstance = true
+        fm.beginTransaction()
+            .add(fragment1, "1")
+            .commitNow()
+
+        // Now destroy the Fragment Manager
+        fc.dispatchPause()
+        fc.dispatchStop()
+        fc.dispatchDestroy()
+
+        try {
+            fm.popBackStack()
+            fail("PopBackStack after FragmentManager destroyed should throw IllegalStateException")
+        } catch (e: IllegalStateException) {
+            assertWithMessage("popBackStack should throw an IllegalStateException")
+                .that(e)
+                .hasMessageThat()
+                .contains("FragmentManager has been destroyed")
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun commitWhenFragmentManagerNeverAttached() {
+        val viewModelStore = ViewModelStore()
+        val fc = FragmentController.createController(
+            ControllerHostCallbacks(activityRule.activity, viewModelStore)
+        )
+        val fm = fc.supportFragmentManager
+
+        val fragment1 = StrictFragment()
+        fragment1.retainInstance = true
+
+        try {
+            fm.beginTransaction()
+                .add(fragment1, "1")
+                .commit()
+            fail("Commit when FragmentManager never attached should throw " +
+                    "IllegalStateException")
+        } catch (e: IllegalStateException) {
+            assertWithMessage("Commit when FragmentManager never attached should throw an " +
+                    "IllegalStateException")
+                .that(e)
+                .hasMessageThat()
+                .contains("FragmentManager has not been attached to a host.")
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun popBackStackAndFragmentHostDestroyed() {
+        val viewModelStore = ViewModelStore()
+        val fc = activityRule.startupFragmentController(viewModelStore)
+        val fm = fc.supportFragmentManager
+
+        val fragment1 = StrictFragment()
+        fragment1.retainInstance = true
+        fm.beginTransaction()
+            .add(fragment1, "1")
+            .commitNow()
+
+        // Now save the state of the FragmentManager
+        fc.dispatchPause()
+
+        val fragment2 = StrictFragment()
+        fragment2.retainInstance = true
+        fm.beginTransaction()
+            .add(fragment2, "2")
+            .commitNowAllowingStateLoss()
+
+        fc.dispatchStop()
+        fc.dispatchDestroy()
+
+        try {
+            fm.popBackStack()
+            fail("PopBackStack after host destroyed should throw IllegalStateException")
+        } catch (e: IllegalStateException) {
+            assertWithMessage("popBackStack should throw an IllegalStateException")
+                .that(e)
+                .hasMessageThat()
+                .contains("FragmentManager has been destroyed")
+        }
+    }
+
+    @Test
+    @UiThreadTest
+    fun commitNowWhenFragmentHostNeverAttached() {
+        val viewModelStore = ViewModelStore()
+        val fc = FragmentController.createController(
+            ControllerHostCallbacks(activityRule.activity, viewModelStore)
+        )
+        val fm = fc.supportFragmentManager
+
+        val fragment1 = StrictFragment()
+        fragment1.retainInstance = true
+        try {
+            fm.beginTransaction()
+                .add(fragment1, "1")
+                .commitNow()
+            fail("CommitNow when host never attached should throw an IllegalStateException")
+        } catch (e: IllegalStateException) {
+            assertWithMessage("CommitNow should throw an IllegalStateException")
+                .that(e)
+                .hasMessageThat()
+                .contains("FragmentManager has not been attached to a host.")
+        }
+    }
+
     /**
      * When a fragment is saved in non-config, it should be restored to the same index.
      */
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentTransitTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentTransitTest.kt
new file mode 100644
index 0000000..641fc40
--- /dev/null
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentTransitTest.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2019 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.fragment.app
+
+import android.animation.Animator
+import android.view.animation.Animation
+import androidx.fragment.app.test.FragmentTestActivity
+import androidx.fragment.test.R
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.test.rule.ActivityTestRule
+import androidx.testutils.waitForExecution
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Tests for [FragmentTransaction.setTransition].
+ */
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+class FragmentTransitTest {
+
+    @get:Rule
+    var activityRule = ActivityTestRule(FragmentTestActivity::class.java)
+
+    @Before
+    fun setupContainer() {
+        activityRule.setContentView(R.layout.simple_container)
+    }
+
+    @Test
+    fun addWithTransit() {
+        val fm = activityRule.activity.supportFragmentManager
+
+        val fragment = TransitFragment()
+        fm.beginTransaction()
+            .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
+            .add(R.id.fragmentContainer, fragment)
+            .addToBackStack(null)
+            .setReorderingAllowed(true)
+            .commit()
+        activityRule.waitForExecution()
+
+        assertThat(fragment.transitValues)
+            .containsExactly(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
+    }
+
+    class TransitFragment : StrictViewFragment() {
+        val transitValues = mutableSetOf<Int>()
+
+        override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
+            transitValues += transit
+            return super.onCreateAnimation(transit, enter, nextAnim)
+        }
+
+        override fun onCreateAnimator(transit: Int, enter: Boolean, nextAnim: Int): Animator? {
+            transitValues += transit
+            return super.onCreateAnimator(transit, enter, nextAnim)
+        }
+    }
+}
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentViewTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentViewTest.kt
index e65aa30..86d419a 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentViewTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentViewTest.kt
@@ -1039,18 +1039,6 @@
         return activityRule.activity.findViewById(viewId)
     }
 
-    private fun assertChildren(container: ViewGroup, vararg fragments: Fragment) {
-        val numFragments = fragments.size
-        assertWithMessage("There aren't the correct number of fragment Views in its container")
-            .that(container.childCount)
-            .isEqualTo(numFragments)
-        for (i in 0 until numFragments) {
-            assertWithMessage("Wrong Fragment View order for [$i]")
-                .that(fragments[i].view)
-                .isEqualTo(container.getChildAt(i))
-        }
-    }
-
     class InvisibleFragment : StrictViewFragment() {
         var visibility = View.INVISIBLE
 
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/PrimaryNavFragmentTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/PrimaryNavFragmentTest.kt
index fc1f76d1..07f6c5a 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/PrimaryNavFragmentTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/PrimaryNavFragmentTest.kt
@@ -22,7 +22,7 @@
 import android.view.ViewGroup
 import androidx.fragment.app.test.EmptyFragmentTestActivity
 import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.MediumTest
+import androidx.test.filters.LargeTest
 import androidx.test.rule.ActivityTestRule
 import androidx.testutils.runOnUiThreadRethrow
 import androidx.testutils.waitForExecution
@@ -35,7 +35,7 @@
 import org.mockito.Mockito.verify
 
 @RunWith(AndroidJUnit4::class)
-@MediumTest
+@LargeTest
 class PrimaryNavFragmentTest {
     @get:Rule
     val activityRule = ActivityTestRule(EmptyFragmentTestActivity::class.java)
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/StrictViewFragment.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/StrictViewFragment.kt
index e58aea0..837a2caae 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/StrictViewFragment.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/StrictViewFragment.kt
@@ -39,6 +39,8 @@
     ): View? {
         checkGetActivity()
         checkState("onCreateView", State.CREATED)
+        assertWithMessage("Fragment should not have a view when calling onCreateView")
+            .that(mView).isNull()
         return super.onCreateView(inflater, container, savedInstanceState).also {
             onCreateViewCalled = true
         }
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/BackStackRecord.java b/fragment/fragment/src/main/java/androidx/fragment/app/BackStackRecord.java
index ccbc082..ff0ab99 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/BackStackRecord.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/BackStackRecord.java
@@ -400,7 +400,7 @@
             switch (op.mCmd) {
                 case OP_ADD:
                     f.setNextAnim(op.mEnterAnim);
-                    mManager.addFragment(f, false);
+                    mManager.addFragment(f);
                     break;
                 case OP_REMOVE:
                     f.setNextAnim(op.mExitAnim);
@@ -465,7 +465,7 @@
                     break;
                 case OP_REMOVE:
                     f.setNextAnim(op.mPopEnterAnim);
-                    mManager.addFragment(f, false);
+                    mManager.addFragment(f);
                     break;
                 case OP_HIDE:
                     f.setNextAnim(op.mPopEnterAnim);
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java b/fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
index 4dc499c..66bf8df 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
@@ -1063,6 +1063,7 @@
 
     /** @hide */
     @RestrictTo(LIBRARY_GROUP_PREFIX)
+    @SuppressLint("KotlinPropertyAccess")
     final public boolean hasOptionsMenu() {
         return mHasMenu;
     }
@@ -2695,7 +2696,7 @@
 
     void performStart() {
         mChildFragmentManager.noteStateNotSaved();
-        mChildFragmentManager.execPendingActions();
+        mChildFragmentManager.execPendingActions(true);
         mState = STARTED;
         mCalled = false;
         onStart();
@@ -2712,7 +2713,7 @@
 
     void performResume() {
         mChildFragmentManager.noteStateNotSaved();
-        mChildFragmentManager.execPendingActions();
+        mChildFragmentManager.execPendingActions(true);
         mState = RESUMED;
         mCalled = false;
         onResume();
@@ -2725,7 +2726,6 @@
             mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
         }
         mChildFragmentManager.dispatchResume();
-        mChildFragmentManager.execPendingActions();
     }
 
     void noteStateNotSaved() {
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentContainerView.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentContainerView.java
index 898a17c..4308a2e 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentContainerView.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentContainerView.java
@@ -240,7 +240,7 @@
 
     @Override
     public void removeAllViewsInLayout() {
-        for (int i = getChildCount() - 1; i > 0; i--) {
+        for (int i = getChildCount() - 1; i >= 0; i--) {
             final View view = getChildAt(i);
             addDisappearingFragmentView(view);
         }
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentController.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentController.java
index 476fc48..f5993f0 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentController.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentController.java
@@ -444,7 +444,7 @@
      * @return {@code true} if queued actions were performed
      */
     public boolean execPendingActions() {
-        return mHost.mFragmentManager.execPendingActions();
+        return mHost.mFragmentManager.execPendingActions(true);
     }
 
     /**
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentLayoutInflaterFactory.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentLayoutInflaterFactory.java
index 22efe88..faa0829 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentLayoutInflaterFactory.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentLayoutInflaterFactory.java
@@ -101,7 +101,8 @@
             fragment.mHost = mFragmentManager.mHost;
             fragment.onInflate(mFragmentManager.mHost.getContext(), attrs,
                     fragment.mSavedFragmentState);
-            mFragmentManager.addFragment(fragment, true);
+            mFragmentManager.addFragment(fragment);
+            mFragmentManager.moveToState(fragment);
 
         } else if (fragment.mInLayout) {
             // A fragment already exists and it is not one we restored from
@@ -125,7 +126,7 @@
         // at the right phase of the lifecycle so that we will have mView populated
         // for compliant fragments below.
         if (mFragmentManager.mCurState < Fragment.CREATED && fragment.mFromLayout) {
-            mFragmentManager.moveToState(fragment, Fragment.CREATED, 0, false);
+            mFragmentManager.moveToState(fragment, Fragment.CREATED);
         } else {
             mFragmentManager.moveToState(fragment);
         }
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
index d376369..c2ef3f3 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
@@ -137,7 +137,8 @@
         /**
          * Return the full bread crumb title resource identifier for the entry,
          * or 0 if it does not have one.
-         * @deprecated Store breadcrumb titles separately from back stack entries.
+         * @deprecated Store breadcrumb titles separately from back stack entries. For example,
+         * by using an <code>android:label</code> on a fragment in a navigation graph.
          */
         @Deprecated
         @StringRes
@@ -146,7 +147,8 @@
         /**
          * Return the short bread crumb title resource identifier for the entry,
          * or 0 if it does not have one.
-         * @deprecated Store breadcrumb short titles separately from back stack entries.
+         * @deprecated Store breadcrumb short titles separately from back stack entries. For
+         * example, by using an <code>android:label</code> on a fragment in a navigation graph.
          */
         @Deprecated
         @StringRes
@@ -155,7 +157,8 @@
         /**
          * Return the full bread crumb title for the entry, or null if it
          * does not have one.
-         * @deprecated Store breadcrumb titles separately from back stack entries.
+         * @deprecated Store breadcrumb titles separately from back stack entries. For example,
+         *          * by using an <code>android:label</code> on a fragment in a navigation graph.
          */
         @Deprecated
         @Nullable
@@ -164,7 +167,8 @@
         /**
          * Return the short bread crumb title for the entry, or null if it
          * does not have one.
-         * @deprecated Store breadcrumb short titles separately from back stack entries.
+         * @deprecated Store breadcrumb short titles separately from back stack entries. For
+         * example, by using an <code>android:label</code> on a fragment in a navigation graph.
          */
         @Deprecated
         @Nullable
@@ -414,7 +418,7 @@
     private Runnable mExecCommit = new Runnable() {
         @Override
         public void run() {
-            execPendingActions();
+            execPendingActions(true);
         }
     };
 
@@ -490,7 +494,7 @@
      * executed.
      */
     public boolean executePendingTransactions() {
-        boolean updates = execPendingActions();
+        boolean updates = execPendingActions(true);
         forcePostponedTransactions();
         return updates;
     }
@@ -539,7 +543,7 @@
         // up to date view of the world just in case anyone is queuing
         // up transactions that change the back stack then immediately
         // calling onBackPressed()
-        execPendingActions();
+        execPendingActions(true);
         if (mOnBackPressedCallback.isEnabled()) {
             // We still have a back stack, so we can pop
             popBackStackImmediate();
@@ -570,7 +574,6 @@
      * @return Returns true if there was something popped, else false.
      */
     public boolean popBackStackImmediate() {
-        checkStateLoss();
         return popBackStackImmediate(null, -1, 0);
     }
 
@@ -598,7 +601,6 @@
      * @return Returns true if there was something popped, else false.
      */
     public boolean popBackStackImmediate(@Nullable String name, int flags) {
-        checkStateLoss();
         return popBackStackImmediate(name, -1, flags);
     }
 
@@ -630,8 +632,6 @@
      * @return Returns true if there was something popped, else false.
      */
     public boolean popBackStackImmediate(int id, int flags) {
-        checkStateLoss();
-        execPendingActions();
         if (id < 0) {
             throw new IllegalArgumentException("Bad id: " + id);
         }
@@ -646,7 +646,7 @@
      * @return true if the pop operation did anything or false otherwise.
      */
     private boolean popBackStackImmediate(String name, int id, int flags) {
-        execPendingActions();
+        execPendingActions(false);
         ensureExecReady(true);
 
         if (mPrimaryNav != null // We have a primary nav fragment
@@ -1070,7 +1070,8 @@
         }
     }
 
-    private AnimationOrAnimator loadAnimation(Fragment fragment, int transit, boolean enter) {
+    private AnimationOrAnimator loadAnimation(Fragment fragment, boolean enter) {
+        int transit = fragment.getNextTransition();
         int nextAnim = fragment.getNextAnim();
         // Clear the Fragment animation
         fragment.setNextAnim(0);
@@ -1151,7 +1152,7 @@
                 return;
             }
             f.mDeferStart = false;
-            moveToState(f, mCurState, 0, false);
+            moveToState(f, mCurState);
         }
     }
 
@@ -1160,7 +1161,7 @@
     }
 
     @SuppressWarnings("ReferenceEquality")
-    void moveToState(Fragment f, int newState, int transit, boolean keepActive) {
+    void moveToState(Fragment f, int newState) {
         // Fragments that are not currently added will sit in the onCreate() state.
         if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {
             newState = Fragment.CREATED;
@@ -1196,11 +1197,9 @@
             if (f.mState < newState && (f.getAnimatingAway() != null || f.getAnimator() != null)) {
                 // The fragment is currently being animated...  but!  Now we
                 // want to move our state back up.  Give up on waiting for the
-                // animation, move to whatever the final state should be once
-                // the animation is done, and then we can proceed from there.
+                // animation and proceed from where we are.
                 f.setAnimatingAway(null);
                 f.setAnimator(null);
-                moveToState(f, f.getStateAfterAnimating(), 0, true);
             }
             switch (f.mState) {
                 case Fragment.INITIALIZING:
@@ -1247,7 +1246,7 @@
                                         + " that does not belong to this FragmentManager!");
                             }
                             if (f.mTarget.mState < Fragment.CREATED) {
-                                moveToState(f.mTarget, Fragment.CREATED, 0, true);
+                                moveToState(f.mTarget, Fragment.CREATED);
                             }
                             f.mTargetWho = f.mTarget.mWho;
                             f.mTarget = null;
@@ -1260,7 +1259,7 @@
                                         + " that does not belong to this FragmentManager!");
                             }
                             if (target.mState < Fragment.CREATED) {
-                                moveToState(target, Fragment.CREATED, 0, true);
+                                moveToState(target, Fragment.CREATED);
                             }
                         }
 
@@ -1403,7 +1402,7 @@
                                 if (mCurState > Fragment.INITIALIZING && !mDestroyed
                                         && f.mView.getVisibility() == View.VISIBLE
                                         && f.mPostponedAlpha >= 0) {
-                                    anim = loadAnimation(f, transit, false);
+                                    anim = loadAnimation(f, false);
                                 }
                                 f.mPostponedAlpha = 0;
                                 if (anim != null) {
@@ -1467,21 +1466,19 @@
 
                             f.performDetach();
                             dispatchOnFragmentDetached(f, false);
-                            if (!keepActive) {
-                                if (beingRemoved || mNonConfig.shouldDestroy(f)) {
-                                    makeInactive(f);
-                                } else {
-                                    f.mHost = null;
-                                    f.mParentFragment = null;
-                                    f.mFragmentManager = null;
-                                    if (f.mTargetWho != null) {
-                                        Fragment target = mActive.get(f.mTargetWho);
-                                        if (target != null && target.getRetainInstance()) {
-                                            // Only keep references to other retained Fragments
-                                            // to avoid developers accessing Fragments that
-                                            // are never coming back
-                                            f.mTarget = target;
-                                        }
+                            if (beingRemoved || mNonConfig.shouldDestroy(f)) {
+                                makeInactive(f);
+                            } else {
+                                f.mHost = null;
+                                f.mParentFragment = null;
+                                f.mFragmentManager = null;
+                                if (f.mTargetWho != null) {
+                                    Fragment target = mActive.get(f.mTargetWho);
+                                    if (target != null && target.getRetainInstance()) {
+                                        // Only keep references to other retained Fragments
+                                        // to avoid developers accessing Fragments that
+                                        // are never coming back
+                                        f.mTarget = target;
                                     }
                                 }
                             }
@@ -1531,7 +1528,7 @@
                             if (fragment.getAnimatingAway() != null) {
                                 fragment.setAnimatingAway(null);
                                 destroyFragmentView(fragment);
-                                moveToState(fragment, fragment.getStateAfterAnimating(), 0, false);
+                                moveToState(fragment, fragment.getStateAfterAnimating());
                             }
                         }
                     });
@@ -1555,7 +1552,7 @@
                     fragment.setAnimator(null);
                     if (animator != null && container.indexOfChild(viewToAnimate) < 0) {
                         destroyFragmentView(fragment);
-                        moveToState(fragment, fragment.getStateAfterAnimating(), 0, false);
+                        moveToState(fragment, fragment.getStateAfterAnimating());
                     }
                 }
             });
@@ -1578,7 +1575,7 @@
     }
 
     void moveToState(Fragment f) {
-        moveToState(f, mCurState, 0, false);
+        moveToState(f, mCurState);
     }
 
     private void ensureInflatedFragmentView(Fragment f) {
@@ -1609,8 +1606,7 @@
      */
     private void completeShowHideFragment(final Fragment fragment) {
         if (fragment.mView != null) {
-            AnimationOrAnimator anim = loadAnimation(fragment, fragment.getNextTransition(),
-                    !fragment.mHidden);
+            AnimationOrAnimator anim = loadAnimation(fragment, !fragment.mHidden);
             if (anim != null && anim.animator != null) {
                 anim.animator.setTarget(fragment.mView);
                 if (fragment.mHidden) {
@@ -1683,7 +1679,7 @@
                 nextState = Math.min(nextState, Fragment.INITIALIZING);
             }
         }
-        moveToState(f, nextState, f.getNextTransition(), false);
+        moveToState(f, nextState);
 
         if (f.mView != null) {
             // Move the view if it is out of order
@@ -1707,7 +1703,7 @@
                 f.mPostponedAlpha = 0f;
                 f.mIsNewlyAdded = false;
                 // run animations:
-                AnimationOrAnimator anim = loadAnimation(f, f.getNextTransition(), true);
+                AnimationOrAnimator anim = loadAnimation(f, true);
                 if (anim != null) {
                     if (anim.animation != null) {
                         f.mView.startAnimation(anim.animation);
@@ -1818,7 +1814,7 @@
         f.initState();
     }
 
-    void addFragment(Fragment fragment, boolean moveToStateNow) {
+    void addFragment(Fragment fragment) {
         if (DEBUG) Log.v(TAG, "add: " + fragment);
         makeActive(fragment);
         if (!fragment.mDetached) {
@@ -1836,9 +1832,6 @@
             if (isMenuAvailable(fragment)) {
                 mNeedMenuInvalidate = true;
             }
-            if (moveToStateNow) {
-                moveToState(fragment);
-            }
         }
     }
 
@@ -2026,10 +2019,18 @@
      */
     void enqueueAction(OpGenerator action, boolean allowStateLoss) {
         if (!allowStateLoss) {
+            if (mHost == null) {
+                if (mDestroyed) {
+                    throw new IllegalStateException("FragmentManager has been destroyed");
+                } else {
+                    throw new IllegalStateException("FragmentManager has not been attached to a "
+                            + "host.");
+                }
+            }
             checkStateLoss();
         }
         synchronized (mPendingActions) {
-            if (mDestroyed || mHost == null) {
+            if (mHost == null) {
                 if (allowStateLoss) {
                     // This FragmentManager isn't attached, so drop the entire transaction.
                     return;
@@ -2077,7 +2078,11 @@
         }
 
         if (mHost == null) {
-            throw new IllegalStateException("Fragment host has been destroyed");
+            if (mDestroyed) {
+                throw new IllegalStateException("FragmentManager has been destroyed");
+            } else {
+                throw new IllegalStateException("FragmentManager has not been attached to a host.");
+            }
         }
 
         if (Looper.myLooper() != mHost.getHandler().getLooper()) {
@@ -2133,8 +2138,8 @@
     /**
      * Only call from main thread!
      */
-    boolean execPendingActions() {
-        ensureExecReady(true);
+    boolean execPendingActions(boolean allowStateLoss) {
+        ensureExecReady(allowStateLoss);
 
         boolean didSomething = false;
         while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
@@ -2512,7 +2517,7 @@
         for (int i = 0; i < numAdded; i++) {
             Fragment fragment = mAdded.get(i);
             if (fragment.mState < state) {
-                moveToState(fragment, state, fragment.getNextAnim(), false);
+                moveToState(fragment, state);
                 if (fragment.mView != null && !fragment.mHidden && fragment.mIsNewlyAdded) {
                     added.add(fragment);
                 }
@@ -2551,7 +2556,7 @@
                     }
                     fragment.setAnimatingAway(null);
                     destroyFragmentView(fragment);
-                    moveToState(fragment, stateAfterAnimating, 0, false);
+                    moveToState(fragment, stateAfterAnimating);
                 } else if (fragment.getAnimator() != null) {
                     fragment.getAnimator().end();
                 }
@@ -2734,7 +2739,7 @@
         // our state update-to-date.
         forcePostponedTransactions();
         endAnimatingAwayFragments();
-        execPendingActions();
+        execPendingActions(true);
 
         mStateSaved = true;
 
@@ -2878,9 +2883,9 @@
                 // We need to ensure that onDestroy and any other clean up is done
                 // so move the Fragment up to CREATED, then mark it as being removed, then
                 // destroy it.
-                moveToState(f, Fragment.CREATED, 0, false);
+                moveToState(f, Fragment.CREATED);
                 f.mRemoving = true;
-                moveToState(f, Fragment.INITIALIZING, 0, false);
+                moveToState(f, Fragment.INITIALIZING);
                 continue;
             }
             fs.mInstance = f;
@@ -3055,7 +3060,7 @@
 
     void dispatchDestroy() {
         mDestroyed = true;
-        execPendingActions();
+        execPendingActions(true);
         dispatchStateChange(Fragment.INITIALIZING);
         mHost = null;
         mContainer = null;
@@ -3075,7 +3080,7 @@
         } finally {
             mExecutingActions = false;
         }
-        execPendingActions();
+        execPendingActions(true);
     }
 
     void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode) {
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransaction.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransaction.java
index f92b54d..a66adf2 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransaction.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransaction.java
@@ -655,7 +655,8 @@
      * is on the back stack.
      *
      * @param res A string resource containing the title.
-     * @deprecated Store breadcrumb titles separately from fragment transactions.
+     * @deprecated Store breadcrumb titles separately from fragment transactions. For
+     * example, by using an <code>android:label</code> on a fragment in a navigation graph.
      */
     @Deprecated
     @NonNull
@@ -669,7 +670,8 @@
      * Like {@link #setBreadCrumbTitle(int)} but taking a raw string; this
      * method is <em>not</em> recommended, as the string can not be changed
      * later if the locale changes.
-     * @deprecated Store breadcrumb titles separately from fragment transactions.
+     * @deprecated Store breadcrumb titles separately from fragment transactions. For
+     * example, by using an <code>android:label</code> on a fragment in a navigation graph.
      */
     @Deprecated
     @NonNull
@@ -684,7 +686,8 @@
      * is on the back stack.
      *
      * @param res A string resource containing the title.
-     * @deprecated Store breadcrumb short titles separately from fragment transactions.
+     * @deprecated Store breadcrumb short titles separately from fragment transactions. For
+     * example, by using an <code>android:label</code> on a fragment in a navigation graph.
      */
     @Deprecated
     @NonNull
@@ -698,7 +701,8 @@
      * Like {@link #setBreadCrumbShortTitle(int)} but taking a raw string; this
      * method is <em>not</em> recommended, as the string can not be changed
      * later if the locale changes.
-     * @deprecated Store breadcrumb short titles separately from fragment transactions.
+     * @deprecated Store breadcrumb short titles separately from fragment transactions. For
+     * example, by using an <code>android:label</code> on a fragment in a navigation graph.
      */
     @Deprecated
     @NonNull
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransition.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransition.java
index d503df3..ddd481d 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransition.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransition.java
@@ -1196,7 +1196,7 @@
             if (fragment.mState < Fragment.CREATED && manager.mCurState >= Fragment.CREATED
                     && !transaction.mReorderingAllowed) {
                 manager.makeActive(fragment);
-                manager.moveToState(fragment, Fragment.CREATED, 0, false);
+                manager.moveToState(fragment, Fragment.CREATED);
             }
         }
         if (setFirstOut && (containerTransition == null || containerTransition.firstOut == null)) {
diff --git a/graphics/drawable/animated/api/api_lint.ignore b/graphics/drawable/animated/api/api_lint.ignore
new file mode 100644
index 0000000..ffd0fdf
--- /dev/null
+++ b/graphics/drawable/animated/api/api_lint.ignore
@@ -0,0 +1,61 @@
+// Baseline format: 1.0
+MissingNullability: androidx.vectordrawable.graphics.drawable.Animatable2Compat.AnimationCallback#onAnimationEnd(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `onAnimationEnd`
+MissingNullability: androidx.vectordrawable.graphics.drawable.Animatable2Compat.AnimationCallback#onAnimationStart(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `onAnimationStart`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#applyTheme(android.content.res.Resources.Theme) parameter #0:
+    Missing nullability on parameter `t` in method `applyTheme`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#clearAnimationCallbacks(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `dr` in method `clearAnimationCallbacks`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#createFromXmlInner(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme):
+    Missing nullability on method `createFromXmlInner` return
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#createFromXmlInner(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #0:
+    Missing nullability on parameter `context` in method `createFromXmlInner`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#createFromXmlInner(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #1:
+    Missing nullability on parameter `r` in method `createFromXmlInner`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#createFromXmlInner(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #2:
+    Missing nullability on parameter `parser` in method `createFromXmlInner`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#createFromXmlInner(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #3:
+    Missing nullability on parameter `attrs` in method `createFromXmlInner`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#createFromXmlInner(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #4:
+    Missing nullability on parameter `theme` in method `createFromXmlInner`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#getColorFilter():
+    Missing nullability on method `getColorFilter` return
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#getConstantState():
+    Missing nullability on method `getConstantState` return
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `res` in method `inflate`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `parser` in method `inflate`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) parameter #2:
+    Missing nullability on parameter `attrs` in method `inflate`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #0:
+    Missing nullability on parameter `res` in method `inflate`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #1:
+    Missing nullability on parameter `parser` in method `inflate`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #2:
+    Missing nullability on parameter `attrs` in method `inflate`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #3:
+    Missing nullability on parameter `theme` in method `inflate`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#mutate():
+    Missing nullability on method `mutate` return
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#onBoundsChange(android.graphics.Rect) parameter #0:
+    Missing nullability on parameter `bounds` in method `onBoundsChange`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#onStateChange(int[]) parameter #0:
+    Missing nullability on parameter `state` in method `onStateChange`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#registerAnimationCallback(android.graphics.drawable.Drawable, androidx.vectordrawable.graphics.drawable.Animatable2Compat.AnimationCallback) parameter #0:
+    Missing nullability on parameter `dr` in method `registerAnimationCallback`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#registerAnimationCallback(android.graphics.drawable.Drawable, androidx.vectordrawable.graphics.drawable.Animatable2Compat.AnimationCallback) parameter #1:
+    Missing nullability on parameter `callback` in method `registerAnimationCallback`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#setColorFilter(android.graphics.ColorFilter) parameter #0:
+    Missing nullability on parameter `colorFilter` in method `setColorFilter`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#setTintList(android.content.res.ColorStateList) parameter #0:
+    Missing nullability on parameter `tint` in method `setTintList`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#setTintMode(android.graphics.PorterDuff.Mode) parameter #0:
+    Missing nullability on parameter `tintMode` in method `setTintMode`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#unregisterAnimationCallback(android.graphics.drawable.Drawable, androidx.vectordrawable.graphics.drawable.Animatable2Compat.AnimationCallback) parameter #0:
+    Missing nullability on parameter `dr` in method `unregisterAnimationCallback`
+MissingNullability: androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat#unregisterAnimationCallback(android.graphics.drawable.Drawable, androidx.vectordrawable.graphics.drawable.Animatable2Compat.AnimationCallback) parameter #1:
+    Missing nullability on parameter `callback` in method `unregisterAnimationCallback`
diff --git a/graphics/drawable/static/api/api_lint.ignore b/graphics/drawable/static/api/api_lint.ignore
new file mode 100644
index 0000000..5021276
--- /dev/null
+++ b/graphics/drawable/static/api/api_lint.ignore
@@ -0,0 +1,47 @@
+// Baseline format: 1.0
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#createFromXmlInner(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme):
+    Missing nullability on method `createFromXmlInner` return
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#createFromXmlInner(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #0:
+    Missing nullability on parameter `r` in method `createFromXmlInner`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#createFromXmlInner(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #1:
+    Missing nullability on parameter `parser` in method `createFromXmlInner`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#createFromXmlInner(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #2:
+    Missing nullability on parameter `attrs` in method `createFromXmlInner`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#createFromXmlInner(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #3:
+    Missing nullability on parameter `theme` in method `createFromXmlInner`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#getColorFilter():
+    Missing nullability on method `getColorFilter` return
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#getConstantState():
+    Missing nullability on method `getConstantState` return
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `res` in method `inflate`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `parser` in method `inflate`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) parameter #2:
+    Missing nullability on parameter `attrs` in method `inflate`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #0:
+    Missing nullability on parameter `res` in method `inflate`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #1:
+    Missing nullability on parameter `parser` in method `inflate`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #2:
+    Missing nullability on parameter `attrs` in method `inflate`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) parameter #3:
+    Missing nullability on parameter `theme` in method `inflate`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#mutate():
+    Missing nullability on method `mutate` return
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#onBoundsChange(android.graphics.Rect) parameter #0:
+    Missing nullability on parameter `bounds` in method `onBoundsChange`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#onStateChange(int[]) parameter #0:
+    Missing nullability on parameter `stateSet` in method `onStateChange`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#scheduleSelf(Runnable, long) parameter #0:
+    Missing nullability on parameter `what` in method `scheduleSelf`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#setColorFilter(android.graphics.ColorFilter) parameter #0:
+    Missing nullability on parameter `colorFilter` in method `setColorFilter`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#setTintList(android.content.res.ColorStateList) parameter #0:
+    Missing nullability on parameter `tint` in method `setTintList`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#setTintMode(android.graphics.PorterDuff.Mode) parameter #0:
+    Missing nullability on parameter `tintMode` in method `setTintMode`
+MissingNullability: androidx.vectordrawable.graphics.drawable.VectorDrawableCompat#unscheduleSelf(Runnable) parameter #0:
+    Missing nullability on parameter `what` in method `unscheduleSelf`
diff --git a/gridlayout/api/api_lint.ignore b/gridlayout/api/api_lint.ignore
new file mode 100644
index 0000000..207a53f
--- /dev/null
+++ b/gridlayout/api/api_lint.ignore
@@ -0,0 +1,97 @@
+// Baseline format: 1.0
+MissingNullability: androidx.gridlayout.widget.GridLayout#BASELINE:
+    Missing nullability on field `BASELINE` in class `class androidx.gridlayout.widget.GridLayout`
+MissingNullability: androidx.gridlayout.widget.GridLayout#BOTTOM:
+    Missing nullability on field `BOTTOM` in class `class androidx.gridlayout.widget.GridLayout`
+MissingNullability: androidx.gridlayout.widget.GridLayout#CENTER:
+    Missing nullability on field `CENTER` in class `class androidx.gridlayout.widget.GridLayout`
+MissingNullability: androidx.gridlayout.widget.GridLayout#END:
+    Missing nullability on field `END` in class `class androidx.gridlayout.widget.GridLayout`
+MissingNullability: androidx.gridlayout.widget.GridLayout#FILL:
+    Missing nullability on field `FILL` in class `class androidx.gridlayout.widget.GridLayout`
+MissingNullability: androidx.gridlayout.widget.GridLayout#GridLayout(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `GridLayout`
+MissingNullability: androidx.gridlayout.widget.GridLayout#GridLayout(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `GridLayout`
+MissingNullability: androidx.gridlayout.widget.GridLayout#GridLayout(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `GridLayout`
+MissingNullability: androidx.gridlayout.widget.GridLayout#GridLayout(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `GridLayout`
+MissingNullability: androidx.gridlayout.widget.GridLayout#GridLayout(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `GridLayout`
+MissingNullability: androidx.gridlayout.widget.GridLayout#LEFT:
+    Missing nullability on field `LEFT` in class `class androidx.gridlayout.widget.GridLayout`
+MissingNullability: androidx.gridlayout.widget.GridLayout#RIGHT:
+    Missing nullability on field `RIGHT` in class `class androidx.gridlayout.widget.GridLayout`
+MissingNullability: androidx.gridlayout.widget.GridLayout#START:
+    Missing nullability on field `START` in class `class androidx.gridlayout.widget.GridLayout`
+MissingNullability: androidx.gridlayout.widget.GridLayout#TOP:
+    Missing nullability on field `TOP` in class `class androidx.gridlayout.widget.GridLayout`
+MissingNullability: androidx.gridlayout.widget.GridLayout#checkLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `checkLayoutParams`
+MissingNullability: androidx.gridlayout.widget.GridLayout#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.gridlayout.widget.GridLayout#generateLayoutParams(android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.gridlayout.widget.GridLayout#generateLayoutParams(android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.gridlayout.widget.GridLayout#generateLayoutParams(android.view.ViewGroup.LayoutParams):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.gridlayout.widget.GridLayout#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `lp` in method `generateLayoutParams`
+MissingNullability: androidx.gridlayout.widget.GridLayout#getPrinter():
+    Missing nullability on method `getPrinter` return
+MissingNullability: androidx.gridlayout.widget.GridLayout#setPrinter(android.util.Printer) parameter #0:
+    Missing nullability on parameter `printer` in method `setPrinter`
+MissingNullability: androidx.gridlayout.widget.GridLayout#spec(int):
+    Missing nullability on method `spec` return
+MissingNullability: androidx.gridlayout.widget.GridLayout#spec(int, androidx.gridlayout.widget.GridLayout.Alignment):
+    Missing nullability on method `spec` return
+MissingNullability: androidx.gridlayout.widget.GridLayout#spec(int, androidx.gridlayout.widget.GridLayout.Alignment) parameter #1:
+    Missing nullability on parameter `alignment` in method `spec`
+MissingNullability: androidx.gridlayout.widget.GridLayout#spec(int, androidx.gridlayout.widget.GridLayout.Alignment, float):
+    Missing nullability on method `spec` return
+MissingNullability: androidx.gridlayout.widget.GridLayout#spec(int, androidx.gridlayout.widget.GridLayout.Alignment, float) parameter #1:
+    Missing nullability on parameter `alignment` in method `spec`
+MissingNullability: androidx.gridlayout.widget.GridLayout#spec(int, float):
+    Missing nullability on method `spec` return
+MissingNullability: androidx.gridlayout.widget.GridLayout#spec(int, int):
+    Missing nullability on method `spec` return
+MissingNullability: androidx.gridlayout.widget.GridLayout#spec(int, int, androidx.gridlayout.widget.GridLayout.Alignment):
+    Missing nullability on method `spec` return
+MissingNullability: androidx.gridlayout.widget.GridLayout#spec(int, int, androidx.gridlayout.widget.GridLayout.Alignment) parameter #2:
+    Missing nullability on parameter `alignment` in method `spec`
+MissingNullability: androidx.gridlayout.widget.GridLayout#spec(int, int, androidx.gridlayout.widget.GridLayout.Alignment, float):
+    Missing nullability on method `spec` return
+MissingNullability: androidx.gridlayout.widget.GridLayout#spec(int, int, androidx.gridlayout.widget.GridLayout.Alignment, float) parameter #2:
+    Missing nullability on parameter `alignment` in method `spec`
+MissingNullability: androidx.gridlayout.widget.GridLayout#spec(int, int, float):
+    Missing nullability on method `spec` return
+MissingNullability: androidx.gridlayout.widget.GridLayout.Alignment#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.gridlayout.widget.GridLayout.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `LayoutParams`
+MissingNullability: androidx.gridlayout.widget.GridLayout.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `LayoutParams`
+MissingNullability: androidx.gridlayout.widget.GridLayout.LayoutParams#LayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `params` in method `LayoutParams`
+MissingNullability: androidx.gridlayout.widget.GridLayout.LayoutParams#LayoutParams(android.view.ViewGroup.MarginLayoutParams) parameter #0:
+    Missing nullability on parameter `params` in method `LayoutParams`
+MissingNullability: androidx.gridlayout.widget.GridLayout.LayoutParams#LayoutParams(androidx.gridlayout.widget.GridLayout.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.gridlayout.widget.GridLayout.LayoutParams#LayoutParams(androidx.gridlayout.widget.GridLayout.Spec, androidx.gridlayout.widget.GridLayout.Spec) parameter #0:
+    Missing nullability on parameter `rowSpec` in method `LayoutParams`
+MissingNullability: androidx.gridlayout.widget.GridLayout.LayoutParams#LayoutParams(androidx.gridlayout.widget.GridLayout.Spec, androidx.gridlayout.widget.GridLayout.Spec) parameter #1:
+    Missing nullability on parameter `columnSpec` in method `LayoutParams`
+MissingNullability: androidx.gridlayout.widget.GridLayout.LayoutParams#columnSpec:
+    Missing nullability on field `columnSpec` in class `class androidx.gridlayout.widget.GridLayout.LayoutParams`
+MissingNullability: androidx.gridlayout.widget.GridLayout.LayoutParams#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.gridlayout.widget.GridLayout.LayoutParams#rowSpec:
+    Missing nullability on field `rowSpec` in class `class androidx.gridlayout.widget.GridLayout.LayoutParams`
+MissingNullability: androidx.gridlayout.widget.GridLayout.LayoutParams#setBaseAttributes(android.content.res.TypedArray, int, int) parameter #0:
+    Missing nullability on parameter `attributes` in method `setBaseAttributes`
+MissingNullability: androidx.gridlayout.widget.GridLayout.Spec#equals(Object) parameter #0:
+    Missing nullability on parameter `that` in method `equals`
+MissingNullability: androidx.gridlayout.widget.GridLayout.Spec#getAbsoluteAlignment(boolean):
+    Missing nullability on method `getAbsoluteAlignment` return
diff --git a/heifwriter/api/api_lint.ignore b/heifwriter/api/api_lint.ignore
index 3dd94ae..5409709 100644
--- a/heifwriter/api/api_lint.ignore
+++ b/heifwriter/api/api_lint.ignore
@@ -3,6 +3,22 @@
     Methods must not throw generic exceptions (`java.lang.Exception`)
 
 
+MissingNullability: androidx.heifwriter.HeifWriter.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.heifwriter.HeifWriter.Builder#setGridEnabled(boolean):
+    Missing nullability on method `setGridEnabled` return
+MissingNullability: androidx.heifwriter.HeifWriter.Builder#setHandler(android.os.Handler):
+    Missing nullability on method `setHandler` return
+MissingNullability: androidx.heifwriter.HeifWriter.Builder#setMaxImages(int):
+    Missing nullability on method `setMaxImages` return
+MissingNullability: androidx.heifwriter.HeifWriter.Builder#setPrimaryIndex(int):
+    Missing nullability on method `setPrimaryIndex` return
+MissingNullability: androidx.heifwriter.HeifWriter.Builder#setQuality(int):
+    Missing nullability on method `setQuality` return
+MissingNullability: androidx.heifwriter.HeifWriter.Builder#setRotation(int):
+    Missing nullability on method `setRotation` return
+
+
 NoClone: androidx.heifwriter.HeifWriter.Builder#Builder(java.io.FileDescriptor, int, int, int) parameter #0:
     Must use ParcelFileDescriptor instead of FileDescriptor in parameter fd in androidx.heifwriter.HeifWriter.Builder(java.io.FileDescriptor fd, int width, int height, int inputMode)
 
diff --git a/inspection/inspection-agent/src/main/java/androidx/inspection/agent/Agent.java b/inspection/inspection-agent/src/main/java/androidx/inspection/agent/Agent.java
deleted file mode 100644
index fd7b5df..0000000
--- a/inspection/inspection-agent/src/main/java/androidx/inspection/agent/Agent.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2019 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.inspection.agent;
-
-/**
- *  Implementation of this class are responsible to handle command from frontend and
- *  send back events.
- */
-public abstract class Agent {
-}
diff --git a/inspection/inspection-agent/src/test/java/androidx/inspection/agent/AgentTest.kt b/inspection/inspection-agent/src/test/java/androidx/inspection/agent/AgentTest.kt
deleted file mode 100644
index a352d2bb..0000000
--- a/inspection/inspection-agent/src/test/java/androidx/inspection/agent/AgentTest.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2019 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.inspection.agent
-
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@RunWith(JUnit4::class)
-class AgentTest {
-
-    @Test
-    fun dummyTest() {
-        val value = object : Agent() {}
-        assertThat(value).isNotNull()
-    }
-}
\ No newline at end of file
diff --git a/inspection/inspection-agent/build.gradle b/inspection/inspection/build.gradle
similarity index 100%
rename from inspection/inspection-agent/build.gradle
rename to inspection/inspection/build.gradle
diff --git a/inspection/inspection/src/main/java/androidx/inspection/Inspector.java b/inspection/inspection/src/main/java/androidx/inspection/Inspector.java
new file mode 100644
index 0000000..c7686ad7
--- /dev/null
+++ b/inspection/inspection/src/main/java/androidx/inspection/Inspector.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2019 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.inspection;
+
+/**
+ *  Implementation of this class are responsible to handle command from frontend and
+ *  send back events.
+ */
+public abstract class Inspector {
+    /**
+     * Called when this inspector was disposed and no longer needed.
+     * <p>
+     * Agent should use this callback to unsubscribe from any events that it is listening to.
+     */
+    public void onDispose() {
+    }
+}
diff --git a/inspection/inspection/src/main/java/androidx/inspection/InspectorFactory.java b/inspection/inspection/src/main/java/androidx/inspection/InspectorFactory.java
new file mode 100644
index 0000000..f0e3568
--- /dev/null
+++ b/inspection/inspection/src/main/java/androidx/inspection/InspectorFactory.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2019 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.inspection;
+
+import androidx.annotation.NonNull;
+
+/**
+ * A factory that is responsible for creation of an inspector for your library.
+ * <p>
+ * Implementations of this class should be registered
+ * as "META-INF/services/androidx.inspection.inspection.InspectorFactory"
+ * and should have a default constructor.
+ *
+ * @param <T> inspector created by this factory
+ */
+public abstract class InspectorFactory<T extends Inspector> {
+    private final String mInspectorId;
+
+    /**
+     * Identifier of an inspector that created by this factory.
+     *
+     * @param inspectorId an id of an inspector that is served by this factory.
+     */
+    public InspectorFactory(@NonNull String inspectorId) {
+        mInspectorId = inspectorId;
+    }
+
+    /**
+     * @return an id of an inspector that is served by this factory.
+     */
+    @NonNull
+    public final String getInspectorId() {
+        return mInspectorId;
+    }
+
+    // TODO: pass the connection in this method
+    /**
+     * @return a new instance of an inspector.
+     */
+    @NonNull
+    public abstract T createInspector();
+}
diff --git a/inspection/inspection/src/test/java/androidx/inspection/InspectorTest.kt b/inspection/inspection/src/test/java/androidx/inspection/InspectorTest.kt
new file mode 100644
index 0000000..a19ad5b
--- /dev/null
+++ b/inspection/inspection/src/test/java/androidx/inspection/InspectorTest.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2019 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.inspection
+
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class InspectorTest {
+
+    @Test
+    fun dummyTest() {
+        val value = object : Inspector() {}
+        assertThat(value).isNotNull()
+    }
+}
\ No newline at end of file
diff --git a/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/config/ConfigParser.kt b/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/config/ConfigParser.kt
index 3a5f36c5..b219c14 100644
--- a/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/config/ConfigParser.kt
+++ b/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/config/ConfigParser.kt
@@ -49,7 +49,10 @@
 
     fun loadDefaultConfig(): Config? {
         Log.v(TAG, "Using the default config '%s'", Config.DEFAULT_CONFIG_RES_PATH)
-        val inputStream = javaClass.getResourceAsStream(Config.DEFAULT_CONFIG_RES_PATH)
+
+        // Use getResource().openStream() instead of getResourceAsStream() as the latter can result
+        // in concurrency issues (see http://issuetracker.google.com/137929327 for details).
+        val inputStream = javaClass.getResource(Config.DEFAULT_CONFIG_RES_PATH).openStream()
         inputStream.reader().use {
             return parseFromString(it.readText())
         }
diff --git a/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/archive/Archive.kt b/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/archive/Archive.kt
index f7c8a674..b728ed3 100644
--- a/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/archive/Archive.kt
+++ b/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/archive/Archive.kt
@@ -103,8 +103,13 @@
         }
 
         // Create directories if they don't exist yet
-        if (outputPath.parent == null) {
-            Files.createDirectories(outputPath.parent)
+        if (outputPath.parent != null) {
+            // By default createDirectories should check if the directory already exists and not
+            // throw anything. However apparently it does not consider "tmp" to be directory and
+            // throws exception. That's why we need to check for exists here.
+            if (!Files.exists(outputPath.parent)) {
+                Files.createDirectories(outputPath.parent)
+            }
         }
 
         Log.i(TAG, "Writing archive: %s", outputPath.toUri())
diff --git a/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/transform/proguard/ProGuardTypesMapper.kt b/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/transform/proguard/ProGuardTypesMapper.kt
index 63399b7..ca59f0a 100644
--- a/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/transform/proguard/ProGuardTypesMapper.kt
+++ b/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/transform/proguard/ProGuardTypesMapper.kt
@@ -207,6 +207,7 @@
         type.fullName
             .substringAfterLast("/") // grabs class name
             .split("(?=\\p{Upper})".toRegex())
+            .filter { it.isNotEmpty() }
             .forEach { lastSegment += it; result.add(lastSegment + "*") }
 
         result.reverse()
diff --git a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/proguard/ProGuardTypesMapperTest.kt b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/proguard/ProGuardTypesMapperTest.kt
index 453066f..d0c5a48 100644
--- a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/proguard/ProGuardTypesMapperTest.kt
+++ b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/proguard/ProGuardTypesMapperTest.kt
@@ -243,8 +243,7 @@
             .getsRewrittenTo("support.v7.Activity")
     }
 
-    // Temporarily disabled due to b/120234632.
-    fun proGuard_solver_wildcard_shouldRewrite() {
+    @Test fun proGuard_solver_wildcard_shouldRewrite() {
         ProGuardTester()
             .forGivenPrefixes(
                 "support/"
@@ -259,8 +258,7 @@
             .getsRewrittenTo("test.preference.**")
     }
 
-    // Temporarily disabled due to b/120234632.
-    fun proGuard_solver_wildcard2_shouldRewrite() {
+    @Test fun proGuard_solver_wildcard2_shouldRewrite() {
         ProGuardTester()
             .forGivenPrefixes(
                 "support/"
@@ -274,8 +272,7 @@
             .getsRewrittenTo("test.preference.**")
     }
 
-    // Temporarily disabled due to b/120234632.
-    fun proGuard_solver_wildcard3_shouldRewrite() {
+    @Test fun proGuard_solver_wildcard3_shouldRewrite() {
         ProGuardTester()
             .forGivenPrefixes(
                 "support/"
diff --git a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/proguard/ProguardSamplesTest.kt b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/proguard/ProguardSamplesTest.kt
index e8b11db..ad5917d 100644
--- a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/proguard/ProguardSamplesTest.kt
+++ b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/proguard/ProguardSamplesTest.kt
@@ -237,8 +237,7 @@
             )
     }
 
-    // Temporarily disabled due to b/120236364.
-    fun proGuard_sample5() {
+    @Test fun proGuard_sample5() {
         ProGuardTester()
             .forGivenPrefixes(
                 "support/"
diff --git a/leanback-preference/api/api_lint.ignore b/leanback-preference/api/api_lint.ignore
index 1ec1d8d..3876a1b 100644
--- a/leanback-preference/api/api_lint.ignore
+++ b/leanback-preference/api/api_lint.ignore
@@ -3,3 +3,171 @@
     Inconsistent extra value; expected `androidx.leanback.preference.extra.IME_OPTIONS`, was `ime_option`
 ActionValue: androidx.leanback.preference.LeanbackEditTextPreferenceDialogFragmentCompat#EXTRA_INPUT_TYPE:
     Inconsistent extra value; expected `androidx.leanback.preference.extra.INPUT_TYPE`, was `input_type`
+
+
+MissingNullability: androidx.leanback.preference.BaseLeanbackPreferenceFragment#onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateRecyclerView` return
+MissingNullability: androidx.leanback.preference.BaseLeanbackPreferenceFragment#onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateRecyclerView`
+MissingNullability: androidx.leanback.preference.BaseLeanbackPreferenceFragment#onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `parent` in method `onCreateRecyclerView`
+MissingNullability: androidx.leanback.preference.BaseLeanbackPreferenceFragment#onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateRecyclerView`
+MissingNullability: androidx.leanback.preference.BaseLeanbackPreferenceFragmentCompat#onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateRecyclerView` return
+MissingNullability: androidx.leanback.preference.BaseLeanbackPreferenceFragmentCompat#onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateRecyclerView`
+MissingNullability: androidx.leanback.preference.BaseLeanbackPreferenceFragmentCompat#onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `parent` in method `onCreateRecyclerView`
+MissingNullability: androidx.leanback.preference.BaseLeanbackPreferenceFragmentCompat#onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateRecyclerView`
+MissingNullability: androidx.leanback.preference.LeanbackEditTextPreferenceDialogFragmentCompat#newInstance(String):
+    Missing nullability on method `newInstance` return
+MissingNullability: androidx.leanback.preference.LeanbackEditTextPreferenceDialogFragmentCompat#newInstance(String) parameter #0:
+    Missing nullability on parameter `key` in method `newInstance`
+MissingNullability: androidx.leanback.preference.LeanbackEditTextPreferenceDialogFragmentCompat#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.preference.LeanbackEditTextPreferenceDialogFragmentCompat#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.preference.LeanbackEditTextPreferenceDialogFragmentCompat#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackEditTextPreferenceDialogFragmentCompat#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment#newInstanceMulti(String):
+    Missing nullability on method `newInstanceMulti` return
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment#newInstanceMulti(String) parameter #0:
+    Missing nullability on parameter `key` in method `newInstanceMulti`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment#newInstanceSingle(String):
+    Missing nullability on method `newInstanceSingle` return
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment#newInstanceSingle(String) parameter #0:
+    Missing nullability on parameter `key` in method `newInstanceSingle`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment#onCreateAdapter():
+    Missing nullability on method `onCreateAdapter` return
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment#onSaveInstanceState(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `outState` in method `onSaveInstanceState`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.AdapterMulti#AdapterMulti(CharSequence[], CharSequence[], java.util.Set<java.lang.String>) parameter #0:
+    Missing nullability on parameter `entries` in method `AdapterMulti`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.AdapterMulti#AdapterMulti(CharSequence[], CharSequence[], java.util.Set<java.lang.String>) parameter #1:
+    Missing nullability on parameter `entryValues` in method `AdapterMulti`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.AdapterMulti#AdapterMulti(CharSequence[], CharSequence[], java.util.Set<java.lang.String>) parameter #2:
+    Missing nullability on parameter `initialSelections` in method `AdapterMulti`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.AdapterMulti#onBindViewHolder(androidx.leanback.preference.LeanbackListPreferenceDialogFragment.ViewHolder, int) parameter #0:
+    Missing nullability on parameter `holder` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.AdapterMulti#onCreateViewHolder(android.view.ViewGroup, int):
+    Missing nullability on method `onCreateViewHolder` return
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.AdapterMulti#onCreateViewHolder(android.view.ViewGroup, int) parameter #0:
+    Missing nullability on parameter `parent` in method `onCreateViewHolder`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.AdapterMulti#onItemClick(androidx.leanback.preference.LeanbackListPreferenceDialogFragment.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onItemClick`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.AdapterSingle#AdapterSingle(CharSequence[], CharSequence[], CharSequence) parameter #0:
+    Missing nullability on parameter `entries` in method `AdapterSingle`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.AdapterSingle#AdapterSingle(CharSequence[], CharSequence[], CharSequence) parameter #1:
+    Missing nullability on parameter `entryValues` in method `AdapterSingle`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.AdapterSingle#AdapterSingle(CharSequence[], CharSequence[], CharSequence) parameter #2:
+    Missing nullability on parameter `selectedValue` in method `AdapterSingle`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.AdapterSingle#onBindViewHolder(androidx.leanback.preference.LeanbackListPreferenceDialogFragment.ViewHolder, int) parameter #0:
+    Missing nullability on parameter `holder` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.AdapterSingle#onCreateViewHolder(android.view.ViewGroup, int):
+    Missing nullability on method `onCreateViewHolder` return
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.AdapterSingle#onCreateViewHolder(android.view.ViewGroup, int) parameter #0:
+    Missing nullability on parameter `parent` in method `onCreateViewHolder`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.AdapterSingle#onItemClick(androidx.leanback.preference.LeanbackListPreferenceDialogFragment.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onItemClick`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.ViewHolder#getContainer():
+    Missing nullability on method `getContainer` return
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.ViewHolder#getTitleView():
+    Missing nullability on method `getTitleView` return
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.ViewHolder#getWidgetView():
+    Missing nullability on method `getWidgetView` return
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.ViewHolder#onClick(android.view.View) parameter #0:
+    Missing nullability on parameter `v` in method `onClick`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragment.ViewHolder.OnItemClickListener#onItemClick(androidx.leanback.preference.LeanbackListPreferenceDialogFragment.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onItemClick`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragmentCompat#newInstanceMulti(String):
+    Missing nullability on method `newInstanceMulti` return
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragmentCompat#newInstanceMulti(String) parameter #0:
+    Missing nullability on parameter `key` in method `newInstanceMulti`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragmentCompat#newInstanceSingle(String):
+    Missing nullability on method `newInstanceSingle` return
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragmentCompat#newInstanceSingle(String) parameter #0:
+    Missing nullability on parameter `key` in method `newInstanceSingle`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragmentCompat#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragmentCompat#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragmentCompat#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragmentCompat#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragmentCompat.ViewHolder#getContainer():
+    Missing nullability on method `getContainer` return
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragmentCompat.ViewHolder#getTitleView():
+    Missing nullability on method `getTitleView` return
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragmentCompat.ViewHolder#getWidgetView():
+    Missing nullability on method `getWidgetView` return
+MissingNullability: androidx.leanback.preference.LeanbackListPreferenceDialogFragmentCompat.ViewHolder#onClick(android.view.View) parameter #0:
+    Missing nullability on parameter `v` in method `onClick`
+MissingNullability: androidx.leanback.preference.LeanbackPreferenceDialogFragment#getPreference():
+    Missing nullability on method `getPreference` return
+MissingNullability: androidx.leanback.preference.LeanbackPreferenceDialogFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.preference.LeanbackPreferenceDialogFragmentCompat#getPreference():
+    Missing nullability on method `getPreference` return
+MissingNullability: androidx.leanback.preference.LeanbackPreferenceDialogFragmentCompat#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.preference.LeanbackPreferenceFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.preference.LeanbackPreferenceFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackPreferenceFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackPreferenceFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackPreferenceFragment#onViewCreated(android.view.View, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `view` in method `onViewCreated`
+MissingNullability: androidx.leanback.preference.LeanbackPreferenceFragment#onViewCreated(android.view.View, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `savedInstanceState` in method `onViewCreated`
+MissingNullability: androidx.leanback.preference.LeanbackPreferenceFragment#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.leanback.preference.LeanbackPreferenceFragmentCompat#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.preference.LeanbackPreferenceFragmentCompat#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackPreferenceFragmentCompat#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackPreferenceFragmentCompat#onViewCreated(android.view.View, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `savedInstanceState` in method `onViewCreated`
+MissingNullability: androidx.leanback.preference.LeanbackPreferenceFragmentCompat#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.leanback.preference.LeanbackSettingsFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.preference.LeanbackSettingsFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackSettingsFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackSettingsFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackSettingsFragment#onPreferenceDisplayDialog(androidx.preference.PreferenceFragment, androidx.preference.Preference) parameter #1:
+    Missing nullability on parameter `pref` in method `onPreferenceDisplayDialog`
+MissingNullability: androidx.leanback.preference.LeanbackSettingsFragment#onViewCreated(android.view.View, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `view` in method `onViewCreated`
+MissingNullability: androidx.leanback.preference.LeanbackSettingsFragment#onViewCreated(android.view.View, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `savedInstanceState` in method `onViewCreated`
+MissingNullability: androidx.leanback.preference.LeanbackSettingsFragmentCompat#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.preference.LeanbackSettingsFragmentCompat#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackSettingsFragmentCompat#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.preference.LeanbackSettingsFragmentCompat#onPreferenceDisplayDialog(androidx.preference.PreferenceFragmentCompat, androidx.preference.Preference) parameter #1:
+    Missing nullability on parameter `pref` in method `onPreferenceDisplayDialog`
+MissingNullability: androidx.leanback.preference.LeanbackSettingsFragmentCompat#onViewCreated(android.view.View, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `savedInstanceState` in method `onViewCreated`
diff --git a/leanback-preference/build.gradle b/leanback-preference/build.gradle
index d91fa03..e4b9361 100644
--- a/leanback-preference/build.gradle
+++ b/leanback-preference/build.gradle
@@ -12,7 +12,7 @@
     implementation("androidx.collection:collection:1.0.0")
     api("androidx.appcompat:appcompat:1.0.0")
     api("androidx.recyclerview:recyclerview:1.0.0")
-    api(project(":preference"))
+    api(project(":preference:preference"))
     api(project(":leanback"))
 }
 
diff --git a/leanback/api/api_lint.ignore b/leanback/api/api_lint.ignore
index 47e6f64..c863f70 100644
--- a/leanback/api/api_lint.ignore
+++ b/leanback/api/api_lint.ignore
@@ -69,6 +69,3518 @@
     Listeners should be an interface, or otherwise renamed Callback: OnChildViewHolderSelectedListener
 
 
+MissingNullability: androidx.leanback.app.BackgroundManager#attach(android.view.Window) parameter #0:
+    Missing nullability on parameter `window` in method `attach`
+MissingNullability: androidx.leanback.app.BackgroundManager#attachToView(android.view.View) parameter #0:
+    Missing nullability on parameter `sceneRoot` in method `attachToView`
+MissingNullability: androidx.leanback.app.BackgroundManager#getDrawable():
+    Missing nullability on method `getDrawable` return
+MissingNullability: androidx.leanback.app.BackgroundManager#getInstance(android.app.Activity):
+    Missing nullability on method `getInstance` return
+MissingNullability: androidx.leanback.app.BackgroundManager#getInstance(android.app.Activity) parameter #0:
+    Missing nullability on parameter `activity` in method `getInstance`
+MissingNullability: androidx.leanback.app.BackgroundManager#setBitmap(android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `bitmap` in method `setBitmap`
+MissingNullability: androidx.leanback.app.BackgroundManager#setDimLayer(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setDimLayer`
+MissingNullability: androidx.leanback.app.BackgroundManager#setDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setDrawable`
+MissingNullability: androidx.leanback.app.BaseFragment#createEntranceTransition():
+    Missing nullability on method `createEntranceTransition` return
+MissingNullability: androidx.leanback.app.BaseFragment#getProgressBarManager():
+    Missing nullability on method `getProgressBarManager` return
+MissingNullability: androidx.leanback.app.BaseFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.app.BaseFragment#runEntranceTransition(Object) parameter #0:
+    Missing nullability on parameter `entranceTransition` in method `runEntranceTransition`
+MissingNullability: androidx.leanback.app.BaseSupportFragment#createEntranceTransition():
+    Missing nullability on method `createEntranceTransition` return
+MissingNullability: androidx.leanback.app.BaseSupportFragment#getProgressBarManager():
+    Missing nullability on method `getProgressBarManager` return
+MissingNullability: androidx.leanback.app.BaseSupportFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.app.BaseSupportFragment#runEntranceTransition(Object) parameter #0:
+    Missing nullability on parameter `entranceTransition` in method `runEntranceTransition`
+MissingNullability: androidx.leanback.app.BrandedFragment#getBadgeDrawable():
+    Missing nullability on method `getBadgeDrawable` return
+MissingNullability: androidx.leanback.app.BrandedFragment#getSearchAffordanceColors():
+    Missing nullability on method `getSearchAffordanceColors` return
+MissingNullability: androidx.leanback.app.BrandedFragment#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.leanback.app.BrandedFragment#getTitleView():
+    Missing nullability on method `getTitleView` return
+MissingNullability: androidx.leanback.app.BrandedFragment#getTitleViewAdapter():
+    Missing nullability on method `getTitleViewAdapter` return
+MissingNullability: androidx.leanback.app.BrandedFragment#installTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `installTitleView`
+MissingNullability: androidx.leanback.app.BrandedFragment#installTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `parent` in method `installTitleView`
+MissingNullability: androidx.leanback.app.BrandedFragment#installTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `installTitleView`
+MissingNullability: androidx.leanback.app.BrandedFragment#onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onInflateTitleView` return
+MissingNullability: androidx.leanback.app.BrandedFragment#onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onInflateTitleView`
+MissingNullability: androidx.leanback.app.BrandedFragment#onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `parent` in method `onInflateTitleView`
+MissingNullability: androidx.leanback.app.BrandedFragment#onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onInflateTitleView`
+MissingNullability: androidx.leanback.app.BrandedFragment#onSaveInstanceState(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `outState` in method `onSaveInstanceState`
+MissingNullability: androidx.leanback.app.BrandedFragment#setBadgeDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setBadgeDrawable`
+MissingNullability: androidx.leanback.app.BrandedFragment#setOnSearchClickedListener(android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnSearchClickedListener`
+MissingNullability: androidx.leanback.app.BrandedFragment#setSearchAffordanceColors(androidx.leanback.widget.SearchOrbView.Colors) parameter #0:
+    Missing nullability on parameter `colors` in method `setSearchAffordanceColors`
+MissingNullability: androidx.leanback.app.BrandedFragment#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.leanback.app.BrandedFragment#setTitleView(android.view.View) parameter #0:
+    Missing nullability on parameter `titleView` in method `setTitleView`
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#getBadgeDrawable():
+    Missing nullability on method `getBadgeDrawable` return
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#getSearchAffordanceColors():
+    Missing nullability on method `getSearchAffordanceColors` return
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#getTitleView():
+    Missing nullability on method `getTitleView` return
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#getTitleViewAdapter():
+    Missing nullability on method `getTitleViewAdapter` return
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#installTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `installTitleView`
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#installTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `parent` in method `installTitleView`
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#installTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `installTitleView`
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onInflateTitleView` return
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onInflateTitleView`
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `parent` in method `onInflateTitleView`
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onInflateTitleView`
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#onSaveInstanceState(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `outState` in method `onSaveInstanceState`
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#setBadgeDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setBadgeDrawable`
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#setOnSearchClickedListener(android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnSearchClickedListener`
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#setSearchAffordanceColors(androidx.leanback.widget.SearchOrbView.Colors) parameter #0:
+    Missing nullability on parameter `colors` in method `setSearchAffordanceColors`
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.leanback.app.BrandedSupportFragment#setTitleView(android.view.View) parameter #0:
+    Missing nullability on parameter `titleView` in method `setTitleView`
+MissingNullability: androidx.leanback.app.BrowseFragment#createArgs(android.os.Bundle, String, int):
+    Missing nullability on method `createArgs` return
+MissingNullability: androidx.leanback.app.BrowseFragment#createArgs(android.os.Bundle, String, int) parameter #0:
+    Missing nullability on parameter `args` in method `createArgs`
+MissingNullability: androidx.leanback.app.BrowseFragment#createArgs(android.os.Bundle, String, int) parameter #1:
+    Missing nullability on parameter `title` in method `createArgs`
+MissingNullability: androidx.leanback.app.BrowseFragment#createEntranceTransition():
+    Missing nullability on method `createEntranceTransition` return
+MissingNullability: androidx.leanback.app.BrowseFragment#getAdapter():
+    Missing nullability on method `getAdapter` return
+MissingNullability: androidx.leanback.app.BrowseFragment#getHeadersFragment():
+    Missing nullability on method `getHeadersFragment` return
+MissingNullability: androidx.leanback.app.BrowseFragment#getMainFragment():
+    Missing nullability on method `getMainFragment` return
+MissingNullability: androidx.leanback.app.BrowseFragment#getMainFragmentRegistry():
+    Missing nullability on method `getMainFragmentRegistry` return
+MissingNullability: androidx.leanback.app.BrowseFragment#getOnItemViewClickedListener():
+    Missing nullability on method `getOnItemViewClickedListener` return
+MissingNullability: androidx.leanback.app.BrowseFragment#getOnItemViewSelectedListener():
+    Missing nullability on method `getOnItemViewSelectedListener` return
+MissingNullability: androidx.leanback.app.BrowseFragment#getRowsFragment():
+    Missing nullability on method `getRowsFragment` return
+MissingNullability: androidx.leanback.app.BrowseFragment#getSelectedRowViewHolder():
+    Missing nullability on method `getSelectedRowViewHolder` return
+MissingNullability: androidx.leanback.app.BrowseFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.app.BrowseFragment#onCreateHeadersFragment():
+    Missing nullability on method `onCreateHeadersFragment` return
+MissingNullability: androidx.leanback.app.BrowseFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.app.BrowseFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.BrowseFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.BrowseFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.BrowseFragment#onSaveInstanceState(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `outState` in method `onSaveInstanceState`
+MissingNullability: androidx.leanback.app.BrowseFragment#runEntranceTransition(Object) parameter #0:
+    Missing nullability on parameter `entranceTransition` in method `runEntranceTransition`
+MissingNullability: androidx.leanback.app.BrowseFragment#setAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setAdapter`
+MissingNullability: androidx.leanback.app.BrowseFragment#setBrowseTransitionListener(androidx.leanback.app.BrowseFragment.BrowseTransitionListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setBrowseTransitionListener`
+MissingNullability: androidx.leanback.app.BrowseFragment#setHeaderPresenterSelector(androidx.leanback.widget.PresenterSelector) parameter #0:
+    Missing nullability on parameter `headerPresenterSelector` in method `setHeaderPresenterSelector`
+MissingNullability: androidx.leanback.app.BrowseFragment#setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.app.BrowseFragment#setOnItemViewSelectedListener(androidx.leanback.widget.OnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.app.BrowseFragment#setSelectedPosition(int, boolean, androidx.leanback.widget.Presenter.ViewHolderTask) parameter #2:
+    Missing nullability on parameter `rowHolderTask` in method `setSelectedPosition`
+MissingNullability: androidx.leanback.app.BrowseFragment.FragmentFactory#createFragment(Object) parameter #0:
+    Missing nullability on parameter `row` in method `createFragment`
+MissingNullability: androidx.leanback.app.BrowseFragment.FragmentHost#notifyDataReady(androidx.leanback.app.BrowseFragment.MainFragmentAdapter) parameter #0:
+    Missing nullability on parameter `fragmentAdapter` in method `notifyDataReady`
+MissingNullability: androidx.leanback.app.BrowseFragment.FragmentHost#notifyViewCreated(androidx.leanback.app.BrowseFragment.MainFragmentAdapter) parameter #0:
+    Missing nullability on parameter `fragmentAdapter` in method `notifyViewCreated`
+MissingNullability: androidx.leanback.app.BrowseFragment.ListRowFragmentFactory#createFragment(Object):
+    Missing nullability on method `createFragment` return
+MissingNullability: androidx.leanback.app.BrowseFragment.ListRowFragmentFactory#createFragment(Object) parameter #0:
+    Missing nullability on parameter `row` in method `createFragment`
+MissingNullability: androidx.leanback.app.BrowseFragment.MainFragmentAdapter#getFragmentHost():
+    Missing nullability on method `getFragmentHost` return
+MissingNullability: androidx.leanback.app.BrowseFragment.MainFragmentAdapterProvider#getMainFragmentAdapter():
+    Missing nullability on method `getMainFragmentAdapter` return
+MissingNullability: androidx.leanback.app.BrowseFragment.MainFragmentAdapterRegistry#createFragment(Object):
+    Missing nullability on method `createFragment` return
+MissingNullability: androidx.leanback.app.BrowseFragment.MainFragmentAdapterRegistry#createFragment(Object) parameter #0:
+    Missing nullability on parameter `item` in method `createFragment`
+MissingNullability: androidx.leanback.app.BrowseFragment.MainFragmentAdapterRegistry#registerFragment(Class<?>, androidx.leanback.app.BrowseFragment.FragmentFactory) parameter #0:
+    Missing nullability on parameter `rowClass` in method `registerFragment`
+MissingNullability: androidx.leanback.app.BrowseFragment.MainFragmentAdapterRegistry#registerFragment(Class<?>, androidx.leanback.app.BrowseFragment.FragmentFactory) parameter #1:
+    Missing nullability on parameter `factory` in method `registerFragment`
+MissingNullability: androidx.leanback.app.BrowseFragment.MainFragmentRowsAdapter#findRowViewHolderByPosition(int):
+    Missing nullability on method `findRowViewHolderByPosition` return
+MissingNullability: androidx.leanback.app.BrowseFragment.MainFragmentRowsAdapter#setAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setAdapter`
+MissingNullability: androidx.leanback.app.BrowseFragment.MainFragmentRowsAdapter#setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.app.BrowseFragment.MainFragmentRowsAdapter#setOnItemViewSelectedListener(androidx.leanback.widget.OnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.app.BrowseFragment.MainFragmentRowsAdapter#setSelectedPosition(int, boolean, androidx.leanback.widget.Presenter.ViewHolderTask) parameter #2:
+    Missing nullability on parameter `rowHolderTask` in method `setSelectedPosition`
+MissingNullability: androidx.leanback.app.BrowseFragment.MainFragmentRowsAdapterProvider#getMainFragmentRowsAdapter():
+    Missing nullability on method `getMainFragmentRowsAdapter` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#createArgs(android.os.Bundle, String, int):
+    Missing nullability on method `createArgs` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#createArgs(android.os.Bundle, String, int) parameter #0:
+    Missing nullability on parameter `args` in method `createArgs`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#createArgs(android.os.Bundle, String, int) parameter #1:
+    Missing nullability on parameter `title` in method `createArgs`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#createEntranceTransition():
+    Missing nullability on method `createEntranceTransition` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#getAdapter():
+    Missing nullability on method `getAdapter` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#getHeadersSupportFragment():
+    Missing nullability on method `getHeadersSupportFragment` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#getMainFragment():
+    Missing nullability on method `getMainFragment` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#getMainFragmentRegistry():
+    Missing nullability on method `getMainFragmentRegistry` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#getOnItemViewClickedListener():
+    Missing nullability on method `getOnItemViewClickedListener` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#getOnItemViewSelectedListener():
+    Missing nullability on method `getOnItemViewSelectedListener` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#getRowsSupportFragment():
+    Missing nullability on method `getRowsSupportFragment` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#getSelectedRowViewHolder():
+    Missing nullability on method `getSelectedRowViewHolder` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#onCreateHeadersSupportFragment():
+    Missing nullability on method `onCreateHeadersSupportFragment` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#onSaveInstanceState(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `outState` in method `onSaveInstanceState`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#runEntranceTransition(Object) parameter #0:
+    Missing nullability on parameter `entranceTransition` in method `runEntranceTransition`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#setAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setAdapter`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#setBrowseTransitionListener(androidx.leanback.app.BrowseSupportFragment.BrowseTransitionListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setBrowseTransitionListener`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#setHeaderPresenterSelector(androidx.leanback.widget.PresenterSelector) parameter #0:
+    Missing nullability on parameter `headerPresenterSelector` in method `setHeaderPresenterSelector`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#setOnItemViewSelectedListener(androidx.leanback.widget.OnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment#setSelectedPosition(int, boolean, androidx.leanback.widget.Presenter.ViewHolderTask) parameter #2:
+    Missing nullability on parameter `rowHolderTask` in method `setSelectedPosition`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.FragmentFactory#createFragment(Object) parameter #0:
+    Missing nullability on parameter `row` in method `createFragment`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.FragmentHost#notifyDataReady(androidx.leanback.app.BrowseSupportFragment.MainFragmentAdapter) parameter #0:
+    Missing nullability on parameter `fragmentAdapter` in method `notifyDataReady`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.FragmentHost#notifyViewCreated(androidx.leanback.app.BrowseSupportFragment.MainFragmentAdapter) parameter #0:
+    Missing nullability on parameter `fragmentAdapter` in method `notifyViewCreated`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.ListRowFragmentFactory#createFragment(Object):
+    Missing nullability on method `createFragment` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.ListRowFragmentFactory#createFragment(Object) parameter #0:
+    Missing nullability on parameter `row` in method `createFragment`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.MainFragmentAdapter#getFragmentHost():
+    Missing nullability on method `getFragmentHost` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.MainFragmentAdapterProvider#getMainFragmentAdapter():
+    Missing nullability on method `getMainFragmentAdapter` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.MainFragmentAdapterRegistry#createFragment(Object):
+    Missing nullability on method `createFragment` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.MainFragmentAdapterRegistry#createFragment(Object) parameter #0:
+    Missing nullability on parameter `item` in method `createFragment`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.MainFragmentAdapterRegistry#registerFragment(Class<?>, androidx.leanback.app.BrowseSupportFragment.FragmentFactory) parameter #0:
+    Missing nullability on parameter `rowClass` in method `registerFragment`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.MainFragmentAdapterRegistry#registerFragment(Class<?>, androidx.leanback.app.BrowseSupportFragment.FragmentFactory) parameter #1:
+    Missing nullability on parameter `factory` in method `registerFragment`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.MainFragmentRowsAdapter#findRowViewHolderByPosition(int):
+    Missing nullability on method `findRowViewHolderByPosition` return
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.MainFragmentRowsAdapter#setAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setAdapter`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.MainFragmentRowsAdapter#setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.MainFragmentRowsAdapter#setOnItemViewSelectedListener(androidx.leanback.widget.OnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.MainFragmentRowsAdapter#setSelectedPosition(int, boolean, androidx.leanback.widget.Presenter.ViewHolderTask) parameter #2:
+    Missing nullability on parameter `rowHolderTask` in method `setSelectedPosition`
+MissingNullability: androidx.leanback.app.BrowseSupportFragment.MainFragmentRowsAdapterProvider#getMainFragmentRowsAdapter():
+    Missing nullability on method `getMainFragmentRowsAdapter` return
+MissingNullability: androidx.leanback.app.DetailsFragment#createEntranceTransition():
+    Missing nullability on method `createEntranceTransition` return
+MissingNullability: androidx.leanback.app.DetailsFragment#getAdapter():
+    Missing nullability on method `getAdapter` return
+MissingNullability: androidx.leanback.app.DetailsFragment#getOnItemViewClickedListener():
+    Missing nullability on method `getOnItemViewClickedListener` return
+MissingNullability: androidx.leanback.app.DetailsFragment#getParallax():
+    Missing nullability on method `getParallax` return
+MissingNullability: androidx.leanback.app.DetailsFragment#getRowsFragment():
+    Missing nullability on method `getRowsFragment` return
+MissingNullability: androidx.leanback.app.DetailsFragment#inflateTitle(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `inflateTitle`
+MissingNullability: androidx.leanback.app.DetailsFragment#inflateTitle(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `parent` in method `inflateTitle`
+MissingNullability: androidx.leanback.app.DetailsFragment#inflateTitle(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `inflateTitle`
+MissingNullability: androidx.leanback.app.DetailsFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.app.DetailsFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.app.DetailsFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.DetailsFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.DetailsFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.DetailsFragment#onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onInflateTitleView` return
+MissingNullability: androidx.leanback.app.DetailsFragment#onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onInflateTitleView`
+MissingNullability: androidx.leanback.app.DetailsFragment#onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `parent` in method `onInflateTitleView`
+MissingNullability: androidx.leanback.app.DetailsFragment#onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onInflateTitleView`
+MissingNullability: androidx.leanback.app.DetailsFragment#onSetDetailsOverviewRowStatus(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter, androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int) parameter #0:
+    Missing nullability on parameter `presenter` in method `onSetDetailsOverviewRowStatus`
+MissingNullability: androidx.leanback.app.DetailsFragment#onSetDetailsOverviewRowStatus(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter, androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int) parameter #1:
+    Missing nullability on parameter `viewHolder` in method `onSetDetailsOverviewRowStatus`
+MissingNullability: androidx.leanback.app.DetailsFragment#onSetRowStatus(androidx.leanback.widget.RowPresenter, androidx.leanback.widget.RowPresenter.ViewHolder, int, int, int) parameter #0:
+    Missing nullability on parameter `presenter` in method `onSetRowStatus`
+MissingNullability: androidx.leanback.app.DetailsFragment#onSetRowStatus(androidx.leanback.widget.RowPresenter, androidx.leanback.widget.RowPresenter.ViewHolder, int, int, int) parameter #1:
+    Missing nullability on parameter `viewHolder` in method `onSetRowStatus`
+MissingNullability: androidx.leanback.app.DetailsFragment#runEntranceTransition(Object) parameter #0:
+    Missing nullability on parameter `entranceTransition` in method `runEntranceTransition`
+MissingNullability: androidx.leanback.app.DetailsFragment#setAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setAdapter`
+MissingNullability: androidx.leanback.app.DetailsFragment#setOnItemViewClickedListener(androidx.leanback.widget.BaseOnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.app.DetailsFragment#setOnItemViewSelectedListener(androidx.leanback.widget.BaseOnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.app.DetailsFragment#setupDetailsOverviewRowPresenter(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter) parameter #0:
+    Missing nullability on parameter `presenter` in method `setupDetailsOverviewRowPresenter`
+MissingNullability: androidx.leanback.app.DetailsFragment#setupPresenter(androidx.leanback.widget.Presenter) parameter #0:
+    Missing nullability on parameter `rowPresenter` in method `setupPresenter`
+MissingNullability: androidx.leanback.app.DetailsFragmentBackgroundController#DetailsFragmentBackgroundController(androidx.leanback.app.DetailsFragment) parameter #0:
+    Missing nullability on parameter `fragment` in method `DetailsFragmentBackgroundController`
+MissingNullability: androidx.leanback.app.DetailsFragmentBackgroundController#findOrCreateVideoFragment():
+    Missing nullability on method `findOrCreateVideoFragment` return
+MissingNullability: androidx.leanback.app.DetailsFragmentBackgroundController#getBottomDrawable():
+    Missing nullability on method `getBottomDrawable` return
+MissingNullability: androidx.leanback.app.DetailsFragmentBackgroundController#getCoverBitmap():
+    Missing nullability on method `getCoverBitmap` return
+MissingNullability: androidx.leanback.app.DetailsFragmentBackgroundController#getCoverDrawable():
+    Missing nullability on method `getCoverDrawable` return
+MissingNullability: androidx.leanback.app.DetailsFragmentBackgroundController#getPlaybackGlue():
+    Missing nullability on method `getPlaybackGlue` return
+MissingNullability: androidx.leanback.app.DetailsFragmentBackgroundController#onCreateGlueHost():
+    Missing nullability on method `onCreateGlueHost` return
+MissingNullability: androidx.leanback.app.DetailsFragmentBackgroundController#onCreateVideoFragment():
+    Missing nullability on method `onCreateVideoFragment` return
+MissingNullability: androidx.leanback.app.DetailsFragmentBackgroundController#setCoverBitmap(android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `bitmap` in method `setCoverBitmap`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#createEntranceTransition():
+    Missing nullability on method `createEntranceTransition` return
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#getAdapter():
+    Missing nullability on method `getAdapter` return
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#getOnItemViewClickedListener():
+    Missing nullability on method `getOnItemViewClickedListener` return
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#getParallax():
+    Missing nullability on method `getParallax` return
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#getRowsSupportFragment():
+    Missing nullability on method `getRowsSupportFragment` return
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#inflateTitle(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `inflateTitle`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#inflateTitle(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `parent` in method `inflateTitle`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#inflateTitle(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `inflateTitle`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onInflateTitleView` return
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onInflateTitleView`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `parent` in method `onInflateTitleView`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onInflateTitleView`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#onSetDetailsOverviewRowStatus(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter, androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int) parameter #0:
+    Missing nullability on parameter `presenter` in method `onSetDetailsOverviewRowStatus`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#onSetDetailsOverviewRowStatus(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter, androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int) parameter #1:
+    Missing nullability on parameter `viewHolder` in method `onSetDetailsOverviewRowStatus`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#onSetRowStatus(androidx.leanback.widget.RowPresenter, androidx.leanback.widget.RowPresenter.ViewHolder, int, int, int) parameter #0:
+    Missing nullability on parameter `presenter` in method `onSetRowStatus`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#onSetRowStatus(androidx.leanback.widget.RowPresenter, androidx.leanback.widget.RowPresenter.ViewHolder, int, int, int) parameter #1:
+    Missing nullability on parameter `viewHolder` in method `onSetRowStatus`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#runEntranceTransition(Object) parameter #0:
+    Missing nullability on parameter `entranceTransition` in method `runEntranceTransition`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#setAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setAdapter`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#setOnItemViewClickedListener(androidx.leanback.widget.BaseOnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#setOnItemViewSelectedListener(androidx.leanback.widget.BaseOnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#setupDetailsOverviewRowPresenter(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter) parameter #0:
+    Missing nullability on parameter `presenter` in method `setupDetailsOverviewRowPresenter`
+MissingNullability: androidx.leanback.app.DetailsSupportFragment#setupPresenter(androidx.leanback.widget.Presenter) parameter #0:
+    Missing nullability on parameter `rowPresenter` in method `setupPresenter`
+MissingNullability: androidx.leanback.app.DetailsSupportFragmentBackgroundController#DetailsSupportFragmentBackgroundController(androidx.leanback.app.DetailsSupportFragment) parameter #0:
+    Missing nullability on parameter `fragment` in method `DetailsSupportFragmentBackgroundController`
+MissingNullability: androidx.leanback.app.DetailsSupportFragmentBackgroundController#findOrCreateVideoSupportFragment():
+    Missing nullability on method `findOrCreateVideoSupportFragment` return
+MissingNullability: androidx.leanback.app.DetailsSupportFragmentBackgroundController#getBottomDrawable():
+    Missing nullability on method `getBottomDrawable` return
+MissingNullability: androidx.leanback.app.DetailsSupportFragmentBackgroundController#getCoverBitmap():
+    Missing nullability on method `getCoverBitmap` return
+MissingNullability: androidx.leanback.app.DetailsSupportFragmentBackgroundController#getCoverDrawable():
+    Missing nullability on method `getCoverDrawable` return
+MissingNullability: androidx.leanback.app.DetailsSupportFragmentBackgroundController#getPlaybackGlue():
+    Missing nullability on method `getPlaybackGlue` return
+MissingNullability: androidx.leanback.app.DetailsSupportFragmentBackgroundController#onCreateGlueHost():
+    Missing nullability on method `onCreateGlueHost` return
+MissingNullability: androidx.leanback.app.DetailsSupportFragmentBackgroundController#onCreateVideoSupportFragment():
+    Missing nullability on method `onCreateVideoSupportFragment` return
+MissingNullability: androidx.leanback.app.DetailsSupportFragmentBackgroundController#setCoverBitmap(android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `bitmap` in method `setCoverBitmap`
+MissingNullability: androidx.leanback.app.ErrorFragment#getBackgroundDrawable():
+    Missing nullability on method `getBackgroundDrawable` return
+MissingNullability: androidx.leanback.app.ErrorFragment#getButtonClickListener():
+    Missing nullability on method `getButtonClickListener` return
+MissingNullability: androidx.leanback.app.ErrorFragment#getButtonText():
+    Missing nullability on method `getButtonText` return
+MissingNullability: androidx.leanback.app.ErrorFragment#getImageDrawable():
+    Missing nullability on method `getImageDrawable` return
+MissingNullability: androidx.leanback.app.ErrorFragment#getMessage():
+    Missing nullability on method `getMessage` return
+MissingNullability: androidx.leanback.app.ErrorFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.app.ErrorFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.ErrorFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.ErrorFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.ErrorFragment#setBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setBackgroundDrawable`
+MissingNullability: androidx.leanback.app.ErrorFragment#setButtonClickListener(android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `clickListener` in method `setButtonClickListener`
+MissingNullability: androidx.leanback.app.ErrorFragment#setButtonText(String) parameter #0:
+    Missing nullability on parameter `text` in method `setButtonText`
+MissingNullability: androidx.leanback.app.ErrorFragment#setImageDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setImageDrawable`
+MissingNullability: androidx.leanback.app.ErrorFragment#setMessage(CharSequence) parameter #0:
+    Missing nullability on parameter `message` in method `setMessage`
+MissingNullability: androidx.leanback.app.ErrorSupportFragment#getBackgroundDrawable():
+    Missing nullability on method `getBackgroundDrawable` return
+MissingNullability: androidx.leanback.app.ErrorSupportFragment#getButtonClickListener():
+    Missing nullability on method `getButtonClickListener` return
+MissingNullability: androidx.leanback.app.ErrorSupportFragment#getButtonText():
+    Missing nullability on method `getButtonText` return
+MissingNullability: androidx.leanback.app.ErrorSupportFragment#getImageDrawable():
+    Missing nullability on method `getImageDrawable` return
+MissingNullability: androidx.leanback.app.ErrorSupportFragment#getMessage():
+    Missing nullability on method `getMessage` return
+MissingNullability: androidx.leanback.app.ErrorSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.app.ErrorSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.ErrorSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.ErrorSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.ErrorSupportFragment#setBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setBackgroundDrawable`
+MissingNullability: androidx.leanback.app.ErrorSupportFragment#setButtonClickListener(android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `clickListener` in method `setButtonClickListener`
+MissingNullability: androidx.leanback.app.ErrorSupportFragment#setButtonText(String) parameter #0:
+    Missing nullability on parameter `text` in method `setButtonText`
+MissingNullability: androidx.leanback.app.ErrorSupportFragment#setImageDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setImageDrawable`
+MissingNullability: androidx.leanback.app.ErrorSupportFragment#setMessage(CharSequence) parameter #0:
+    Missing nullability on parameter `message` in method `setMessage`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#add(android.app.FragmentManager, androidx.leanback.app.GuidedStepFragment) parameter #0:
+    Missing nullability on parameter `fragmentManager` in method `add`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#add(android.app.FragmentManager, androidx.leanback.app.GuidedStepFragment) parameter #1:
+    Missing nullability on parameter `fragment` in method `add`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#add(android.app.FragmentManager, androidx.leanback.app.GuidedStepFragment, int) parameter #0:
+    Missing nullability on parameter `fragmentManager` in method `add`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#add(android.app.FragmentManager, androidx.leanback.app.GuidedStepFragment, int) parameter #1:
+    Missing nullability on parameter `fragment` in method `add`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#addAsRoot(android.app.Activity, androidx.leanback.app.GuidedStepFragment, int) parameter #0:
+    Missing nullability on parameter `activity` in method `addAsRoot`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#addAsRoot(android.app.Activity, androidx.leanback.app.GuidedStepFragment, int) parameter #1:
+    Missing nullability on parameter `fragment` in method `addAsRoot`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#expandAction(androidx.leanback.widget.GuidedAction, boolean) parameter #0:
+    Missing nullability on parameter `action` in method `expandAction`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#expandSubActions(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `expandSubActions`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#findActionById(long):
+    Missing nullability on method `findActionById` return
+MissingNullability: androidx.leanback.app.GuidedStepFragment#findButtonActionById(long):
+    Missing nullability on method `findButtonActionById` return
+MissingNullability: androidx.leanback.app.GuidedStepFragment#getActionItemView(int):
+    Missing nullability on method `getActionItemView` return
+MissingNullability: androidx.leanback.app.GuidedStepFragment#getActions():
+    Missing nullability on method `getActions` return
+MissingNullability: androidx.leanback.app.GuidedStepFragment#getButtonActionItemView(int):
+    Missing nullability on method `getButtonActionItemView` return
+MissingNullability: androidx.leanback.app.GuidedStepFragment#getButtonActions():
+    Missing nullability on method `getButtonActions` return
+MissingNullability: androidx.leanback.app.GuidedStepFragment#getCurrentGuidedStepFragment(android.app.FragmentManager):
+    Missing nullability on method `getCurrentGuidedStepFragment` return
+MissingNullability: androidx.leanback.app.GuidedStepFragment#getCurrentGuidedStepFragment(android.app.FragmentManager) parameter #0:
+    Missing nullability on parameter `fm` in method `getCurrentGuidedStepFragment`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#getGuidanceStylist():
+    Missing nullability on method `getGuidanceStylist` return
+MissingNullability: androidx.leanback.app.GuidedStepFragment#getGuidedActionsStylist():
+    Missing nullability on method `getGuidedActionsStylist` return
+MissingNullability: androidx.leanback.app.GuidedStepFragment#getGuidedButtonActionsStylist():
+    Missing nullability on method `getGuidedButtonActionsStylist` return
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onAddSharedElementTransition(android.app.FragmentTransaction, androidx.leanback.app.GuidedStepFragment) parameter #0:
+    Missing nullability on parameter `ft` in method `onAddSharedElementTransition`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onAddSharedElementTransition(android.app.FragmentTransaction, androidx.leanback.app.GuidedStepFragment) parameter #1:
+    Missing nullability on parameter `disappearing` in method `onAddSharedElementTransition`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onCreateActions(java.util.List<androidx.leanback.widget.GuidedAction>, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateActions`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onCreateActionsStylist():
+    Missing nullability on method `onCreateActionsStylist` return
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateBackgroundView` return
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateBackgroundView`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateBackgroundView`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateBackgroundView`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onCreateButtonActions(java.util.List<androidx.leanback.widget.GuidedAction>, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateButtonActions`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onCreateButtonActionsStylist():
+    Missing nullability on method `onCreateButtonActionsStylist` return
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onCreateGuidance(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateGuidance`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onCreateGuidanceStylist():
+    Missing nullability on method `onCreateGuidanceStylist` return
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onGuidedActionClicked(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `onGuidedActionClicked`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onGuidedActionEditCanceled(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `onGuidedActionEditCanceled`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onGuidedActionEdited(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `onGuidedActionEdited`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onGuidedActionEditedAndProceed(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `onGuidedActionEditedAndProceed`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onGuidedActionFocused(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `onGuidedActionFocused`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onSaveInstanceState(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `outState` in method `onSaveInstanceState`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#onSubGuidedActionClicked(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `onSubGuidedActionClicked`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#openInEditMode(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `openInEditMode`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#popBackStackToGuidedStepFragment(Class<?>, int) parameter #0:
+    Missing nullability on parameter `guidedStepFragmentClass` in method `popBackStackToGuidedStepFragment`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#setActions(java.util.List<androidx.leanback.widget.GuidedAction>) parameter #0:
+    Missing nullability on parameter `actions` in method `setActions`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#setActionsDiffCallback(androidx.leanback.widget.DiffCallback<androidx.leanback.widget.GuidedAction>) parameter #0:
+    Missing nullability on parameter `diffCallback` in method `setActionsDiffCallback`
+MissingNullability: androidx.leanback.app.GuidedStepFragment#setButtonActions(java.util.List<androidx.leanback.widget.GuidedAction>) parameter #0:
+    Missing nullability on parameter `actions` in method `setButtonActions`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#add(androidx.fragment.app.FragmentManager, androidx.leanback.app.GuidedStepSupportFragment) parameter #0:
+    Missing nullability on parameter `fragmentManager` in method `add`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#add(androidx.fragment.app.FragmentManager, androidx.leanback.app.GuidedStepSupportFragment) parameter #1:
+    Missing nullability on parameter `fragment` in method `add`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#add(androidx.fragment.app.FragmentManager, androidx.leanback.app.GuidedStepSupportFragment, int) parameter #0:
+    Missing nullability on parameter `fragmentManager` in method `add`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#add(androidx.fragment.app.FragmentManager, androidx.leanback.app.GuidedStepSupportFragment, int) parameter #1:
+    Missing nullability on parameter `fragment` in method `add`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#addAsRoot(androidx.fragment.app.FragmentActivity, androidx.leanback.app.GuidedStepSupportFragment, int) parameter #0:
+    Missing nullability on parameter `activity` in method `addAsRoot`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#addAsRoot(androidx.fragment.app.FragmentActivity, androidx.leanback.app.GuidedStepSupportFragment, int) parameter #1:
+    Missing nullability on parameter `fragment` in method `addAsRoot`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#expandAction(androidx.leanback.widget.GuidedAction, boolean) parameter #0:
+    Missing nullability on parameter `action` in method `expandAction`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#expandSubActions(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `expandSubActions`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#findActionById(long):
+    Missing nullability on method `findActionById` return
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#findButtonActionById(long):
+    Missing nullability on method `findButtonActionById` return
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#getActionItemView(int):
+    Missing nullability on method `getActionItemView` return
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#getActions():
+    Missing nullability on method `getActions` return
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#getButtonActionItemView(int):
+    Missing nullability on method `getButtonActionItemView` return
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#getButtonActions():
+    Missing nullability on method `getButtonActions` return
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#getCurrentGuidedStepSupportFragment(androidx.fragment.app.FragmentManager):
+    Missing nullability on method `getCurrentGuidedStepSupportFragment` return
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#getCurrentGuidedStepSupportFragment(androidx.fragment.app.FragmentManager) parameter #0:
+    Missing nullability on parameter `fm` in method `getCurrentGuidedStepSupportFragment`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#getGuidanceStylist():
+    Missing nullability on method `getGuidanceStylist` return
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#getGuidedActionsStylist():
+    Missing nullability on method `getGuidedActionsStylist` return
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#getGuidedButtonActionsStylist():
+    Missing nullability on method `getGuidedButtonActionsStylist` return
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onAddSharedElementTransition(androidx.fragment.app.FragmentTransaction, androidx.leanback.app.GuidedStepSupportFragment) parameter #0:
+    Missing nullability on parameter `ft` in method `onAddSharedElementTransition`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onAddSharedElementTransition(androidx.fragment.app.FragmentTransaction, androidx.leanback.app.GuidedStepSupportFragment) parameter #1:
+    Missing nullability on parameter `disappearing` in method `onAddSharedElementTransition`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onCreateActions(java.util.List<androidx.leanback.widget.GuidedAction>, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateActions`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onCreateActionsStylist():
+    Missing nullability on method `onCreateActionsStylist` return
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateBackgroundView` return
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateBackgroundView`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateBackgroundView`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateBackgroundView`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onCreateButtonActions(java.util.List<androidx.leanback.widget.GuidedAction>, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateButtonActions`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onCreateButtonActionsStylist():
+    Missing nullability on method `onCreateButtonActionsStylist` return
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onCreateGuidance(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateGuidance`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onCreateGuidanceStylist():
+    Missing nullability on method `onCreateGuidanceStylist` return
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onGuidedActionClicked(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `onGuidedActionClicked`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onGuidedActionEditCanceled(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `onGuidedActionEditCanceled`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onGuidedActionEdited(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `onGuidedActionEdited`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onGuidedActionEditedAndProceed(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `onGuidedActionEditedAndProceed`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onGuidedActionFocused(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `onGuidedActionFocused`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onSaveInstanceState(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `outState` in method `onSaveInstanceState`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#onSubGuidedActionClicked(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `onSubGuidedActionClicked`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#openInEditMode(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `openInEditMode`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#popBackStackToGuidedStepSupportFragment(Class<?>, int) parameter #0:
+    Missing nullability on parameter `guidedStepFragmentClass` in method `popBackStackToGuidedStepSupportFragment`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#setActions(java.util.List<androidx.leanback.widget.GuidedAction>) parameter #0:
+    Missing nullability on parameter `actions` in method `setActions`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#setActionsDiffCallback(androidx.leanback.widget.DiffCallback<androidx.leanback.widget.GuidedAction>) parameter #0:
+    Missing nullability on parameter `diffCallback` in method `setActionsDiffCallback`
+MissingNullability: androidx.leanback.app.GuidedStepSupportFragment#setButtonActions(java.util.List<androidx.leanback.widget.GuidedAction>) parameter #0:
+    Missing nullability on parameter `actions` in method `setButtonActions`
+MissingNullability: androidx.leanback.app.HeadersFragment#setOnHeaderClickedListener(androidx.leanback.app.HeadersFragment.OnHeaderClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnHeaderClickedListener`
+MissingNullability: androidx.leanback.app.HeadersFragment#setOnHeaderViewSelectedListener(androidx.leanback.app.HeadersFragment.OnHeaderViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnHeaderViewSelectedListener`
+MissingNullability: androidx.leanback.app.HeadersFragment.OnHeaderClickedListener#onHeaderClicked(androidx.leanback.widget.RowHeaderPresenter.ViewHolder, androidx.leanback.widget.Row) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onHeaderClicked`
+MissingNullability: androidx.leanback.app.HeadersFragment.OnHeaderClickedListener#onHeaderClicked(androidx.leanback.widget.RowHeaderPresenter.ViewHolder, androidx.leanback.widget.Row) parameter #1:
+    Missing nullability on parameter `row` in method `onHeaderClicked`
+MissingNullability: androidx.leanback.app.HeadersFragment.OnHeaderViewSelectedListener#onHeaderSelected(androidx.leanback.widget.RowHeaderPresenter.ViewHolder, androidx.leanback.widget.Row) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onHeaderSelected`
+MissingNullability: androidx.leanback.app.HeadersFragment.OnHeaderViewSelectedListener#onHeaderSelected(androidx.leanback.widget.RowHeaderPresenter.ViewHolder, androidx.leanback.widget.Row) parameter #1:
+    Missing nullability on parameter `row` in method `onHeaderSelected`
+MissingNullability: androidx.leanback.app.HeadersSupportFragment#setOnHeaderClickedListener(androidx.leanback.app.HeadersSupportFragment.OnHeaderClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnHeaderClickedListener`
+MissingNullability: androidx.leanback.app.HeadersSupportFragment#setOnHeaderViewSelectedListener(androidx.leanback.app.HeadersSupportFragment.OnHeaderViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnHeaderViewSelectedListener`
+MissingNullability: androidx.leanback.app.HeadersSupportFragment.OnHeaderClickedListener#onHeaderClicked(androidx.leanback.widget.RowHeaderPresenter.ViewHolder, androidx.leanback.widget.Row) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onHeaderClicked`
+MissingNullability: androidx.leanback.app.HeadersSupportFragment.OnHeaderClickedListener#onHeaderClicked(androidx.leanback.widget.RowHeaderPresenter.ViewHolder, androidx.leanback.widget.Row) parameter #1:
+    Missing nullability on parameter `row` in method `onHeaderClicked`
+MissingNullability: androidx.leanback.app.HeadersSupportFragment.OnHeaderViewSelectedListener#onHeaderSelected(androidx.leanback.widget.RowHeaderPresenter.ViewHolder, androidx.leanback.widget.Row) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onHeaderSelected`
+MissingNullability: androidx.leanback.app.HeadersSupportFragment.OnHeaderViewSelectedListener#onHeaderSelected(androidx.leanback.widget.RowHeaderPresenter.ViewHolder, androidx.leanback.widget.Row) parameter #1:
+    Missing nullability on parameter `row` in method `onHeaderSelected`
+MissingNullability: androidx.leanback.app.OnboardingFragment#getPageDescription(int):
+    Missing nullability on method `getPageDescription` return
+MissingNullability: androidx.leanback.app.OnboardingFragment#getPageTitle(int):
+    Missing nullability on method `getPageTitle` return
+MissingNullability: androidx.leanback.app.OnboardingFragment#getStartButtonText():
+    Missing nullability on method `getStartButtonText` return
+MissingNullability: androidx.leanback.app.OnboardingFragment#onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateBackgroundView`
+MissingNullability: androidx.leanback.app.OnboardingFragment#onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateBackgroundView`
+MissingNullability: androidx.leanback.app.OnboardingFragment#onCreateContentView(android.view.LayoutInflater, android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateContentView`
+MissingNullability: androidx.leanback.app.OnboardingFragment#onCreateContentView(android.view.LayoutInflater, android.view.ViewGroup) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateContentView`
+MissingNullability: androidx.leanback.app.OnboardingFragment#onCreateDescriptionAnimator():
+    Missing nullability on method `onCreateDescriptionAnimator` return
+MissingNullability: androidx.leanback.app.OnboardingFragment#onCreateForegroundView(android.view.LayoutInflater, android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateForegroundView`
+MissingNullability: androidx.leanback.app.OnboardingFragment#onCreateForegroundView(android.view.LayoutInflater, android.view.ViewGroup) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateForegroundView`
+MissingNullability: androidx.leanback.app.OnboardingFragment#onCreateTitleAnimator():
+    Missing nullability on method `onCreateTitleAnimator` return
+MissingNullability: androidx.leanback.app.OnboardingFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.OnboardingFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.OnboardingFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.OnboardingFragment#onSaveInstanceState(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `outState` in method `onSaveInstanceState`
+MissingNullability: androidx.leanback.app.OnboardingFragment#setStartButtonText(CharSequence) parameter #0:
+    Missing nullability on parameter `text` in method `setStartButtonText`
+MissingNullability: androidx.leanback.app.OnboardingSupportFragment#getPageDescription(int):
+    Missing nullability on method `getPageDescription` return
+MissingNullability: androidx.leanback.app.OnboardingSupportFragment#getPageTitle(int):
+    Missing nullability on method `getPageTitle` return
+MissingNullability: androidx.leanback.app.OnboardingSupportFragment#getStartButtonText():
+    Missing nullability on method `getStartButtonText` return
+MissingNullability: androidx.leanback.app.OnboardingSupportFragment#onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateBackgroundView`
+MissingNullability: androidx.leanback.app.OnboardingSupportFragment#onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateBackgroundView`
+MissingNullability: androidx.leanback.app.OnboardingSupportFragment#onCreateContentView(android.view.LayoutInflater, android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateContentView`
+MissingNullability: androidx.leanback.app.OnboardingSupportFragment#onCreateContentView(android.view.LayoutInflater, android.view.ViewGroup) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateContentView`
+MissingNullability: androidx.leanback.app.OnboardingSupportFragment#onCreateDescriptionAnimator():
+    Missing nullability on method `onCreateDescriptionAnimator` return
+MissingNullability: androidx.leanback.app.OnboardingSupportFragment#onCreateForegroundView(android.view.LayoutInflater, android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateForegroundView`
+MissingNullability: androidx.leanback.app.OnboardingSupportFragment#onCreateForegroundView(android.view.LayoutInflater, android.view.ViewGroup) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateForegroundView`
+MissingNullability: androidx.leanback.app.OnboardingSupportFragment#onCreateTitleAnimator():
+    Missing nullability on method `onCreateTitleAnimator` return
+MissingNullability: androidx.leanback.app.OnboardingSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.OnboardingSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.OnboardingSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.OnboardingSupportFragment#onSaveInstanceState(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `outState` in method `onSaveInstanceState`
+MissingNullability: androidx.leanback.app.OnboardingSupportFragment#setStartButtonText(CharSequence) parameter #0:
+    Missing nullability on parameter `text` in method `setStartButtonText`
+MissingNullability: androidx.leanback.app.PlaybackFragment#getAdapter():
+    Missing nullability on method `getAdapter` return
+MissingNullability: androidx.leanback.app.PlaybackFragment#getProgressBarManager():
+    Missing nullability on method `getProgressBarManager` return
+MissingNullability: androidx.leanback.app.PlaybackFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.app.PlaybackFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.app.PlaybackFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.PlaybackFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.PlaybackFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.PlaybackFragment#onError(int, CharSequence) parameter #1:
+    Missing nullability on parameter `errorMessage` in method `onError`
+MissingNullability: androidx.leanback.app.PlaybackFragment#setAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setAdapter`
+MissingNullability: androidx.leanback.app.PlaybackFragment#setHostCallback(androidx.leanback.media.PlaybackGlueHost.HostCallback) parameter #0:
+    Missing nullability on parameter `hostCallback` in method `setHostCallback`
+MissingNullability: androidx.leanback.app.PlaybackFragment#setOnItemViewClickedListener(androidx.leanback.widget.BaseOnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.app.PlaybackFragment#setOnItemViewSelectedListener(androidx.leanback.widget.BaseOnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.app.PlaybackFragment#setOnKeyInterceptListener(android.view.View.OnKeyListener) parameter #0:
+    Missing nullability on parameter `handler` in method `setOnKeyInterceptListener`
+MissingNullability: androidx.leanback.app.PlaybackFragment#setOnPlaybackItemViewClickedListener(androidx.leanback.widget.BaseOnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnPlaybackItemViewClickedListener`
+MissingNullability: androidx.leanback.app.PlaybackFragment#setPlaybackRow(androidx.leanback.widget.Row) parameter #0:
+    Missing nullability on parameter `row` in method `setPlaybackRow`
+MissingNullability: androidx.leanback.app.PlaybackFragment#setPlaybackRowPresenter(androidx.leanback.widget.PlaybackRowPresenter) parameter #0:
+    Missing nullability on parameter `presenter` in method `setPlaybackRowPresenter`
+MissingNullability: androidx.leanback.app.PlaybackFragment#setPlaybackSeekUiClient(androidx.leanback.widget.PlaybackSeekUi.Client) parameter #0:
+    Missing nullability on parameter `client` in method `setPlaybackSeekUiClient`
+MissingNullability: androidx.leanback.app.PlaybackFragmentGlueHost#PlaybackFragmentGlueHost(androidx.leanback.app.PlaybackFragment) parameter #0:
+    Missing nullability on parameter `fragment` in method `PlaybackFragmentGlueHost`
+MissingNullability: androidx.leanback.app.PlaybackFragmentGlueHost#getPlayerCallback():
+    Missing nullability on method `getPlayerCallback` return
+MissingNullability: androidx.leanback.app.PlaybackFragmentGlueHost#setHostCallback(androidx.leanback.media.PlaybackGlueHost.HostCallback) parameter #0:
+    Missing nullability on parameter `callback` in method `setHostCallback`
+MissingNullability: androidx.leanback.app.PlaybackFragmentGlueHost#setOnActionClickedListener(androidx.leanback.widget.OnActionClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnActionClickedListener`
+MissingNullability: androidx.leanback.app.PlaybackFragmentGlueHost#setOnKeyInterceptListener(android.view.View.OnKeyListener) parameter #0:
+    Missing nullability on parameter `onKeyListener` in method `setOnKeyInterceptListener`
+MissingNullability: androidx.leanback.app.PlaybackFragmentGlueHost#setPlaybackRow(androidx.leanback.widget.Row) parameter #0:
+    Missing nullability on parameter `row` in method `setPlaybackRow`
+MissingNullability: androidx.leanback.app.PlaybackFragmentGlueHost#setPlaybackRowPresenter(androidx.leanback.widget.PlaybackRowPresenter) parameter #0:
+    Missing nullability on parameter `presenter` in method `setPlaybackRowPresenter`
+MissingNullability: androidx.leanback.app.PlaybackFragmentGlueHost#setPlaybackSeekUiClient(androidx.leanback.widget.PlaybackSeekUi.Client) parameter #0:
+    Missing nullability on parameter `client` in method `setPlaybackSeekUiClient`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#getAdapter():
+    Missing nullability on method `getAdapter` return
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#getProgressBarManager():
+    Missing nullability on method `getProgressBarManager` return
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#onError(int, CharSequence) parameter #1:
+    Missing nullability on parameter `errorMessage` in method `onError`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#setAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setAdapter`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#setHostCallback(androidx.leanback.media.PlaybackGlueHost.HostCallback) parameter #0:
+    Missing nullability on parameter `hostCallback` in method `setHostCallback`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#setOnItemViewClickedListener(androidx.leanback.widget.BaseOnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#setOnItemViewSelectedListener(androidx.leanback.widget.BaseOnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#setOnKeyInterceptListener(android.view.View.OnKeyListener) parameter #0:
+    Missing nullability on parameter `handler` in method `setOnKeyInterceptListener`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#setOnPlaybackItemViewClickedListener(androidx.leanback.widget.BaseOnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnPlaybackItemViewClickedListener`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#setPlaybackRow(androidx.leanback.widget.Row) parameter #0:
+    Missing nullability on parameter `row` in method `setPlaybackRow`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#setPlaybackRowPresenter(androidx.leanback.widget.PlaybackRowPresenter) parameter #0:
+    Missing nullability on parameter `presenter` in method `setPlaybackRowPresenter`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragment#setPlaybackSeekUiClient(androidx.leanback.widget.PlaybackSeekUi.Client) parameter #0:
+    Missing nullability on parameter `client` in method `setPlaybackSeekUiClient`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragmentGlueHost#PlaybackSupportFragmentGlueHost(androidx.leanback.app.PlaybackSupportFragment) parameter #0:
+    Missing nullability on parameter `fragment` in method `PlaybackSupportFragmentGlueHost`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragmentGlueHost#getPlayerCallback():
+    Missing nullability on method `getPlayerCallback` return
+MissingNullability: androidx.leanback.app.PlaybackSupportFragmentGlueHost#setHostCallback(androidx.leanback.media.PlaybackGlueHost.HostCallback) parameter #0:
+    Missing nullability on parameter `callback` in method `setHostCallback`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragmentGlueHost#setOnActionClickedListener(androidx.leanback.widget.OnActionClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnActionClickedListener`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragmentGlueHost#setOnKeyInterceptListener(android.view.View.OnKeyListener) parameter #0:
+    Missing nullability on parameter `onKeyListener` in method `setOnKeyInterceptListener`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragmentGlueHost#setPlaybackRow(androidx.leanback.widget.Row) parameter #0:
+    Missing nullability on parameter `row` in method `setPlaybackRow`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragmentGlueHost#setPlaybackRowPresenter(androidx.leanback.widget.PlaybackRowPresenter) parameter #0:
+    Missing nullability on parameter `presenter` in method `setPlaybackRowPresenter`
+MissingNullability: androidx.leanback.app.PlaybackSupportFragmentGlueHost#setPlaybackSeekUiClient(androidx.leanback.widget.PlaybackSeekUi.Client) parameter #0:
+    Missing nullability on parameter `client` in method `setPlaybackSeekUiClient`
+MissingNullability: androidx.leanback.app.ProgressBarManager#setProgressBarView(android.view.View) parameter #0:
+    Missing nullability on parameter `progressBarView` in method `setProgressBarView`
+MissingNullability: androidx.leanback.app.ProgressBarManager#setRootView(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `rootView` in method `setRootView`
+MissingNullability: androidx.leanback.app.RowsFragment#findGridViewFromRoot(android.view.View):
+    Missing nullability on method `findGridViewFromRoot` return
+MissingNullability: androidx.leanback.app.RowsFragment#findGridViewFromRoot(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `findGridViewFromRoot`
+MissingNullability: androidx.leanback.app.RowsFragment#findRowViewHolderByPosition(int):
+    Missing nullability on method `findRowViewHolderByPosition` return
+MissingNullability: androidx.leanback.app.RowsFragment#getMainFragmentAdapter():
+    Missing nullability on method `getMainFragmentAdapter` return
+MissingNullability: androidx.leanback.app.RowsFragment#getMainFragmentRowsAdapter():
+    Missing nullability on method `getMainFragmentRowsAdapter` return
+MissingNullability: androidx.leanback.app.RowsFragment#getOnItemViewClickedListener():
+    Missing nullability on method `getOnItemViewClickedListener` return
+MissingNullability: androidx.leanback.app.RowsFragment#getOnItemViewSelectedListener():
+    Missing nullability on method `getOnItemViewSelectedListener` return
+MissingNullability: androidx.leanback.app.RowsFragment#getRowViewHolder(int):
+    Missing nullability on method `getRowViewHolder` return
+MissingNullability: androidx.leanback.app.RowsFragment#setOnItemViewClickedListener(androidx.leanback.widget.BaseOnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.app.RowsFragment#setOnItemViewSelectedListener(androidx.leanback.widget.BaseOnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.app.RowsFragment#setSelectedPosition(int, boolean, androidx.leanback.widget.Presenter.ViewHolderTask) parameter #2:
+    Missing nullability on parameter `rowHolderTask` in method `setSelectedPosition`
+MissingNullability: androidx.leanback.app.RowsFragment.MainFragmentAdapter#MainFragmentAdapter(androidx.leanback.app.RowsFragment) parameter #0:
+    Missing nullability on parameter `fragment` in method `MainFragmentAdapter`
+MissingNullability: androidx.leanback.app.RowsFragment.MainFragmentRowsAdapter#MainFragmentRowsAdapter(androidx.leanback.app.RowsFragment) parameter #0:
+    Missing nullability on parameter `fragment` in method `MainFragmentRowsAdapter`
+MissingNullability: androidx.leanback.app.RowsFragment.MainFragmentRowsAdapter#findRowViewHolderByPosition(int):
+    Missing nullability on method `findRowViewHolderByPosition` return
+MissingNullability: androidx.leanback.app.RowsFragment.MainFragmentRowsAdapter#setAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setAdapter`
+MissingNullability: androidx.leanback.app.RowsFragment.MainFragmentRowsAdapter#setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.app.RowsFragment.MainFragmentRowsAdapter#setOnItemViewSelectedListener(androidx.leanback.widget.OnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.app.RowsFragment.MainFragmentRowsAdapter#setSelectedPosition(int, boolean, androidx.leanback.widget.Presenter.ViewHolderTask) parameter #2:
+    Missing nullability on parameter `rowHolderTask` in method `setSelectedPosition`
+MissingNullability: androidx.leanback.app.RowsSupportFragment#findGridViewFromRoot(android.view.View):
+    Missing nullability on method `findGridViewFromRoot` return
+MissingNullability: androidx.leanback.app.RowsSupportFragment#findGridViewFromRoot(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `findGridViewFromRoot`
+MissingNullability: androidx.leanback.app.RowsSupportFragment#findRowViewHolderByPosition(int):
+    Missing nullability on method `findRowViewHolderByPosition` return
+MissingNullability: androidx.leanback.app.RowsSupportFragment#getMainFragmentAdapter():
+    Missing nullability on method `getMainFragmentAdapter` return
+MissingNullability: androidx.leanback.app.RowsSupportFragment#getMainFragmentRowsAdapter():
+    Missing nullability on method `getMainFragmentRowsAdapter` return
+MissingNullability: androidx.leanback.app.RowsSupportFragment#getOnItemViewClickedListener():
+    Missing nullability on method `getOnItemViewClickedListener` return
+MissingNullability: androidx.leanback.app.RowsSupportFragment#getOnItemViewSelectedListener():
+    Missing nullability on method `getOnItemViewSelectedListener` return
+MissingNullability: androidx.leanback.app.RowsSupportFragment#getRowViewHolder(int):
+    Missing nullability on method `getRowViewHolder` return
+MissingNullability: androidx.leanback.app.RowsSupportFragment#setOnItemViewClickedListener(androidx.leanback.widget.BaseOnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.app.RowsSupportFragment#setOnItemViewSelectedListener(androidx.leanback.widget.BaseOnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.app.RowsSupportFragment#setSelectedPosition(int, boolean, androidx.leanback.widget.Presenter.ViewHolderTask) parameter #2:
+    Missing nullability on parameter `rowHolderTask` in method `setSelectedPosition`
+MissingNullability: androidx.leanback.app.RowsSupportFragment.MainFragmentAdapter#MainFragmentAdapter(androidx.leanback.app.RowsSupportFragment) parameter #0:
+    Missing nullability on parameter `fragment` in method `MainFragmentAdapter`
+MissingNullability: androidx.leanback.app.RowsSupportFragment.MainFragmentRowsAdapter#MainFragmentRowsAdapter(androidx.leanback.app.RowsSupportFragment) parameter #0:
+    Missing nullability on parameter `fragment` in method `MainFragmentRowsAdapter`
+MissingNullability: androidx.leanback.app.RowsSupportFragment.MainFragmentRowsAdapter#findRowViewHolderByPosition(int):
+    Missing nullability on method `findRowViewHolderByPosition` return
+MissingNullability: androidx.leanback.app.RowsSupportFragment.MainFragmentRowsAdapter#setAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setAdapter`
+MissingNullability: androidx.leanback.app.RowsSupportFragment.MainFragmentRowsAdapter#setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.app.RowsSupportFragment.MainFragmentRowsAdapter#setOnItemViewSelectedListener(androidx.leanback.widget.OnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.app.RowsSupportFragment.MainFragmentRowsAdapter#setSelectedPosition(int, boolean, androidx.leanback.widget.Presenter.ViewHolderTask) parameter #2:
+    Missing nullability on parameter `rowHolderTask` in method `setSelectedPosition`
+MissingNullability: androidx.leanback.app.SearchFragment#createArgs(android.os.Bundle, String):
+    Missing nullability on method `createArgs` return
+MissingNullability: androidx.leanback.app.SearchFragment#createArgs(android.os.Bundle, String) parameter #0:
+    Missing nullability on parameter `args` in method `createArgs`
+MissingNullability: androidx.leanback.app.SearchFragment#createArgs(android.os.Bundle, String) parameter #1:
+    Missing nullability on parameter `query` in method `createArgs`
+MissingNullability: androidx.leanback.app.SearchFragment#createArgs(android.os.Bundle, String, String):
+    Missing nullability on method `createArgs` return
+MissingNullability: androidx.leanback.app.SearchFragment#createArgs(android.os.Bundle, String, String) parameter #0:
+    Missing nullability on parameter `args` in method `createArgs`
+MissingNullability: androidx.leanback.app.SearchFragment#createArgs(android.os.Bundle, String, String) parameter #1:
+    Missing nullability on parameter `query` in method `createArgs`
+MissingNullability: androidx.leanback.app.SearchFragment#createArgs(android.os.Bundle, String, String) parameter #2:
+    Missing nullability on parameter `title` in method `createArgs`
+MissingNullability: androidx.leanback.app.SearchFragment#displayCompletions(android.view.inputmethod.CompletionInfo[]) parameter #0:
+    Missing nullability on parameter `completions` in method `displayCompletions`
+MissingNullability: androidx.leanback.app.SearchFragment#displayCompletions(java.util.List<java.lang.String>) parameter #0:
+    Missing nullability on parameter `completions` in method `displayCompletions`
+MissingNullability: androidx.leanback.app.SearchFragment#getBadgeDrawable():
+    Missing nullability on method `getBadgeDrawable` return
+MissingNullability: androidx.leanback.app.SearchFragment#getRecognizerIntent():
+    Missing nullability on method `getRecognizerIntent` return
+MissingNullability: androidx.leanback.app.SearchFragment#getRowsFragment():
+    Missing nullability on method `getRowsFragment` return
+MissingNullability: androidx.leanback.app.SearchFragment#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.leanback.app.SearchFragment#newInstance(String):
+    Missing nullability on method `newInstance` return
+MissingNullability: androidx.leanback.app.SearchFragment#newInstance(String) parameter #0:
+    Missing nullability on parameter `query` in method `newInstance`
+MissingNullability: androidx.leanback.app.SearchFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.app.SearchFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.app.SearchFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.SearchFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.SearchFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.SearchFragment#onRequestPermissionsResult(int, String[], int[]) parameter #1:
+    Missing nullability on parameter `permissions` in method `onRequestPermissionsResult`
+MissingNullability: androidx.leanback.app.SearchFragment#onRequestPermissionsResult(int, String[], int[]) parameter #2:
+    Missing nullability on parameter `grantResults` in method `onRequestPermissionsResult`
+MissingNullability: androidx.leanback.app.SearchFragment#setBadgeDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setBadgeDrawable`
+MissingNullability: androidx.leanback.app.SearchFragment#setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.app.SearchFragment#setOnItemViewSelectedListener(androidx.leanback.widget.OnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.app.SearchFragment#setSearchAffordanceColors(androidx.leanback.widget.SearchOrbView.Colors) parameter #0:
+    Missing nullability on parameter `colors` in method `setSearchAffordanceColors`
+MissingNullability: androidx.leanback.app.SearchFragment#setSearchAffordanceColorsInListening(androidx.leanback.widget.SearchOrbView.Colors) parameter #0:
+    Missing nullability on parameter `colors` in method `setSearchAffordanceColorsInListening`
+MissingNullability: androidx.leanback.app.SearchFragment#setSearchQuery(String, boolean) parameter #0:
+    Missing nullability on parameter `query` in method `setSearchQuery`
+MissingNullability: androidx.leanback.app.SearchFragment#setSearchQuery(android.content.Intent, boolean) parameter #0:
+    Missing nullability on parameter `intent` in method `setSearchQuery`
+MissingNullability: androidx.leanback.app.SearchFragment#setSearchResultProvider(androidx.leanback.app.SearchFragment.SearchResultProvider) parameter #0:
+    Missing nullability on parameter `searchResultProvider` in method `setSearchResultProvider`
+MissingNullability: androidx.leanback.app.SearchFragment#setSpeechRecognitionCallback(androidx.leanback.widget.SpeechRecognitionCallback) parameter #0:
+    Missing nullability on parameter `callback` in method `setSpeechRecognitionCallback`
+MissingNullability: androidx.leanback.app.SearchFragment#setTitle(String) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.leanback.app.SearchFragment.SearchResultProvider#getResultsAdapter():
+    Missing nullability on method `getResultsAdapter` return
+MissingNullability: androidx.leanback.app.SearchFragment.SearchResultProvider#onQueryTextChange(String) parameter #0:
+    Missing nullability on parameter `newQuery` in method `onQueryTextChange`
+MissingNullability: androidx.leanback.app.SearchFragment.SearchResultProvider#onQueryTextSubmit(String) parameter #0:
+    Missing nullability on parameter `query` in method `onQueryTextSubmit`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#createArgs(android.os.Bundle, String):
+    Missing nullability on method `createArgs` return
+MissingNullability: androidx.leanback.app.SearchSupportFragment#createArgs(android.os.Bundle, String) parameter #0:
+    Missing nullability on parameter `args` in method `createArgs`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#createArgs(android.os.Bundle, String) parameter #1:
+    Missing nullability on parameter `query` in method `createArgs`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#createArgs(android.os.Bundle, String, String):
+    Missing nullability on method `createArgs` return
+MissingNullability: androidx.leanback.app.SearchSupportFragment#createArgs(android.os.Bundle, String, String) parameter #0:
+    Missing nullability on parameter `args` in method `createArgs`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#createArgs(android.os.Bundle, String, String) parameter #1:
+    Missing nullability on parameter `query` in method `createArgs`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#createArgs(android.os.Bundle, String, String) parameter #2:
+    Missing nullability on parameter `title` in method `createArgs`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#displayCompletions(android.view.inputmethod.CompletionInfo[]) parameter #0:
+    Missing nullability on parameter `completions` in method `displayCompletions`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#displayCompletions(java.util.List<java.lang.String>) parameter #0:
+    Missing nullability on parameter `completions` in method `displayCompletions`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#getBadgeDrawable():
+    Missing nullability on method `getBadgeDrawable` return
+MissingNullability: androidx.leanback.app.SearchSupportFragment#getRecognizerIntent():
+    Missing nullability on method `getRecognizerIntent` return
+MissingNullability: androidx.leanback.app.SearchSupportFragment#getRowsSupportFragment():
+    Missing nullability on method `getRowsSupportFragment` return
+MissingNullability: androidx.leanback.app.SearchSupportFragment#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.leanback.app.SearchSupportFragment#newInstance(String):
+    Missing nullability on method `newInstance` return
+MissingNullability: androidx.leanback.app.SearchSupportFragment#newInstance(String) parameter #0:
+    Missing nullability on parameter `query` in method `newInstance`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.app.SearchSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#onRequestPermissionsResult(int, String[], int[]) parameter #1:
+    Missing nullability on parameter `permissions` in method `onRequestPermissionsResult`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#onRequestPermissionsResult(int, String[], int[]) parameter #2:
+    Missing nullability on parameter `grantResults` in method `onRequestPermissionsResult`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#setBadgeDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setBadgeDrawable`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#setOnItemViewSelectedListener(androidx.leanback.widget.OnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#setSearchAffordanceColors(androidx.leanback.widget.SearchOrbView.Colors) parameter #0:
+    Missing nullability on parameter `colors` in method `setSearchAffordanceColors`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#setSearchAffordanceColorsInListening(androidx.leanback.widget.SearchOrbView.Colors) parameter #0:
+    Missing nullability on parameter `colors` in method `setSearchAffordanceColorsInListening`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#setSearchQuery(String, boolean) parameter #0:
+    Missing nullability on parameter `query` in method `setSearchQuery`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#setSearchQuery(android.content.Intent, boolean) parameter #0:
+    Missing nullability on parameter `intent` in method `setSearchQuery`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#setSearchResultProvider(androidx.leanback.app.SearchSupportFragment.SearchResultProvider) parameter #0:
+    Missing nullability on parameter `searchResultProvider` in method `setSearchResultProvider`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#setSpeechRecognitionCallback(androidx.leanback.widget.SpeechRecognitionCallback) parameter #0:
+    Missing nullability on parameter `callback` in method `setSpeechRecognitionCallback`
+MissingNullability: androidx.leanback.app.SearchSupportFragment#setTitle(String) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.leanback.app.SearchSupportFragment.SearchResultProvider#getResultsAdapter():
+    Missing nullability on method `getResultsAdapter` return
+MissingNullability: androidx.leanback.app.SearchSupportFragment.SearchResultProvider#onQueryTextChange(String) parameter #0:
+    Missing nullability on parameter `newQuery` in method `onQueryTextChange`
+MissingNullability: androidx.leanback.app.SearchSupportFragment.SearchResultProvider#onQueryTextSubmit(String) parameter #0:
+    Missing nullability on parameter `query` in method `onQueryTextSubmit`
+MissingNullability: androidx.leanback.app.VerticalGridFragment#createEntranceTransition():
+    Missing nullability on method `createEntranceTransition` return
+MissingNullability: androidx.leanback.app.VerticalGridFragment#getAdapter():
+    Missing nullability on method `getAdapter` return
+MissingNullability: androidx.leanback.app.VerticalGridFragment#getGridPresenter():
+    Missing nullability on method `getGridPresenter` return
+MissingNullability: androidx.leanback.app.VerticalGridFragment#getOnItemViewClickedListener():
+    Missing nullability on method `getOnItemViewClickedListener` return
+MissingNullability: androidx.leanback.app.VerticalGridFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.app.VerticalGridFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.VerticalGridFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.VerticalGridFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.VerticalGridFragment#runEntranceTransition(Object) parameter #0:
+    Missing nullability on parameter `entranceTransition` in method `runEntranceTransition`
+MissingNullability: androidx.leanback.app.VerticalGridFragment#setAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setAdapter`
+MissingNullability: androidx.leanback.app.VerticalGridFragment#setGridPresenter(androidx.leanback.widget.VerticalGridPresenter) parameter #0:
+    Missing nullability on parameter `gridPresenter` in method `setGridPresenter`
+MissingNullability: androidx.leanback.app.VerticalGridFragment#setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.app.VerticalGridFragment#setOnItemViewSelectedListener(androidx.leanback.widget.OnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.app.VerticalGridSupportFragment#createEntranceTransition():
+    Missing nullability on method `createEntranceTransition` return
+MissingNullability: androidx.leanback.app.VerticalGridSupportFragment#getAdapter():
+    Missing nullability on method `getAdapter` return
+MissingNullability: androidx.leanback.app.VerticalGridSupportFragment#getGridPresenter():
+    Missing nullability on method `getGridPresenter` return
+MissingNullability: androidx.leanback.app.VerticalGridSupportFragment#getOnItemViewClickedListener():
+    Missing nullability on method `getOnItemViewClickedListener` return
+MissingNullability: androidx.leanback.app.VerticalGridSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.app.VerticalGridSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.VerticalGridSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.VerticalGridSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.VerticalGridSupportFragment#runEntranceTransition(Object) parameter #0:
+    Missing nullability on parameter `entranceTransition` in method `runEntranceTransition`
+MissingNullability: androidx.leanback.app.VerticalGridSupportFragment#setAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setAdapter`
+MissingNullability: androidx.leanback.app.VerticalGridSupportFragment#setGridPresenter(androidx.leanback.widget.VerticalGridPresenter) parameter #0:
+    Missing nullability on parameter `gridPresenter` in method `setGridPresenter`
+MissingNullability: androidx.leanback.app.VerticalGridSupportFragment#setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.app.VerticalGridSupportFragment#setOnItemViewSelectedListener(androidx.leanback.widget.OnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.app.VideoFragment#getSurfaceView():
+    Missing nullability on method `getSurfaceView` return
+MissingNullability: androidx.leanback.app.VideoFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.app.VideoFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.VideoFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.VideoFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.VideoFragment#setSurfaceHolderCallback(android.view.SurfaceHolder.Callback) parameter #0:
+    Missing nullability on parameter `callback` in method `setSurfaceHolderCallback`
+MissingNullability: androidx.leanback.app.VideoFragmentGlueHost#VideoFragmentGlueHost(androidx.leanback.app.VideoFragment) parameter #0:
+    Missing nullability on parameter `fragment` in method `VideoFragmentGlueHost`
+MissingNullability: androidx.leanback.app.VideoFragmentGlueHost#setSurfaceHolderCallback(android.view.SurfaceHolder.Callback) parameter #0:
+    Missing nullability on parameter `callback` in method `setSurfaceHolderCallback`
+MissingNullability: androidx.leanback.app.VideoSupportFragment#getSurfaceView():
+    Missing nullability on method `getSurfaceView` return
+MissingNullability: androidx.leanback.app.VideoSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.app.VideoSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.app.VideoSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.app.VideoSupportFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.leanback.app.VideoSupportFragment#setSurfaceHolderCallback(android.view.SurfaceHolder.Callback) parameter #0:
+    Missing nullability on parameter `callback` in method `setSurfaceHolderCallback`
+MissingNullability: androidx.leanback.app.VideoSupportFragmentGlueHost#VideoSupportFragmentGlueHost(androidx.leanback.app.VideoSupportFragment) parameter #0:
+    Missing nullability on parameter `fragment` in method `VideoSupportFragmentGlueHost`
+MissingNullability: androidx.leanback.app.VideoSupportFragmentGlueHost#setSurfaceHolderCallback(android.view.SurfaceHolder.Callback) parameter #0:
+    Missing nullability on parameter `callback` in method `setSurfaceHolderCallback`
+MissingNullability: androidx.leanback.database.CursorMapper#bind(android.database.Cursor):
+    Missing nullability on method `bind` return
+MissingNullability: androidx.leanback.database.CursorMapper#bind(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `cursor` in method `bind`
+MissingNullability: androidx.leanback.database.CursorMapper#bindColumns(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `cursor` in method `bindColumns`
+MissingNullability: androidx.leanback.database.CursorMapper#convert(android.database.Cursor):
+    Missing nullability on method `convert` return
+MissingNullability: androidx.leanback.database.CursorMapper#convert(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `cursor` in method `convert`
+MissingNullability: androidx.leanback.graphics.BoundsRule#BoundsRule(androidx.leanback.graphics.BoundsRule) parameter #0:
+    Missing nullability on parameter `boundsRule` in method `BoundsRule`
+MissingNullability: androidx.leanback.graphics.BoundsRule#bottom:
+    Missing nullability on field `bottom` in class `class androidx.leanback.graphics.BoundsRule`
+MissingNullability: androidx.leanback.graphics.BoundsRule#calculateBounds(android.graphics.Rect, android.graphics.Rect) parameter #0:
+    Missing nullability on parameter `rect` in method `calculateBounds`
+MissingNullability: androidx.leanback.graphics.BoundsRule#calculateBounds(android.graphics.Rect, android.graphics.Rect) parameter #1:
+    Missing nullability on parameter `result` in method `calculateBounds`
+MissingNullability: androidx.leanback.graphics.BoundsRule#left:
+    Missing nullability on field `left` in class `class androidx.leanback.graphics.BoundsRule`
+MissingNullability: androidx.leanback.graphics.BoundsRule#right:
+    Missing nullability on field `right` in class `class androidx.leanback.graphics.BoundsRule`
+MissingNullability: androidx.leanback.graphics.BoundsRule#top:
+    Missing nullability on field `top` in class `class androidx.leanback.graphics.BoundsRule`
+MissingNullability: androidx.leanback.graphics.BoundsRule.ValueRule#absoluteValue(int):
+    Missing nullability on method `absoluteValue` return
+MissingNullability: androidx.leanback.graphics.BoundsRule.ValueRule#inheritFromParent(float):
+    Missing nullability on method `inheritFromParent` return
+MissingNullability: androidx.leanback.graphics.BoundsRule.ValueRule#inheritFromParentWithOffset(float, int):
+    Missing nullability on method `inheritFromParentWithOffset` return
+MissingNullability: androidx.leanback.graphics.ColorFilterCache#getColorFilterCache(int):
+    Missing nullability on method `getColorFilterCache` return
+MissingNullability: androidx.leanback.graphics.ColorFilterCache#getFilterForLevel(float):
+    Missing nullability on method `getFilterForLevel` return
+MissingNullability: androidx.leanback.graphics.ColorFilterDimmer#applyFilterToView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `applyFilterToView`
+MissingNullability: androidx.leanback.graphics.ColorFilterDimmer#create(androidx.leanback.graphics.ColorFilterCache, float, float):
+    Missing nullability on method `create` return
+MissingNullability: androidx.leanback.graphics.ColorFilterDimmer#create(androidx.leanback.graphics.ColorFilterCache, float, float) parameter #0:
+    Missing nullability on parameter `dimmer` in method `create`
+MissingNullability: androidx.leanback.graphics.ColorFilterDimmer#createDefault(android.content.Context):
+    Missing nullability on method `createDefault` return
+MissingNullability: androidx.leanback.graphics.ColorFilterDimmer#createDefault(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `createDefault`
+MissingNullability: androidx.leanback.graphics.ColorFilterDimmer#getColorFilter():
+    Missing nullability on method `getColorFilter` return
+MissingNullability: androidx.leanback.graphics.ColorFilterDimmer#getPaint():
+    Missing nullability on method `getPaint` return
+MissingNullability: androidx.leanback.graphics.ColorOverlayDimmer#createColorOverlayDimmer(int, float, float):
+    Missing nullability on method `createColorOverlayDimmer` return
+MissingNullability: androidx.leanback.graphics.ColorOverlayDimmer#createDefault(android.content.Context):
+    Missing nullability on method `createDefault` return
+MissingNullability: androidx.leanback.graphics.ColorOverlayDimmer#createDefault(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `createDefault`
+MissingNullability: androidx.leanback.graphics.ColorOverlayDimmer#drawColorOverlay(android.graphics.Canvas, android.view.View, boolean) parameter #0:
+    Missing nullability on parameter `c` in method `drawColorOverlay`
+MissingNullability: androidx.leanback.graphics.ColorOverlayDimmer#drawColorOverlay(android.graphics.Canvas, android.view.View, boolean) parameter #1:
+    Missing nullability on parameter `v` in method `drawColorOverlay`
+MissingNullability: androidx.leanback.graphics.ColorOverlayDimmer#getPaint():
+    Missing nullability on method `getPaint` return
+MissingNullability: androidx.leanback.graphics.CompositeDrawable#addChildDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `addChildDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable#getChildAt(int):
+    Missing nullability on method `getChildAt` return
+MissingNullability: androidx.leanback.graphics.CompositeDrawable#getConstantState():
+    Missing nullability on method `getConstantState` return
+MissingNullability: androidx.leanback.graphics.CompositeDrawable#getDrawable(int):
+    Missing nullability on method `getDrawable` return
+MissingNullability: androidx.leanback.graphics.CompositeDrawable#invalidateDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `who` in method `invalidateDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable#mutate():
+    Missing nullability on method `mutate` return
+MissingNullability: androidx.leanback.graphics.CompositeDrawable#onBoundsChange(android.graphics.Rect) parameter #0:
+    Missing nullability on parameter `bounds` in method `onBoundsChange`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable#removeDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `removeDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable#scheduleDrawable(android.graphics.drawable.Drawable, Runnable, long) parameter #0:
+    Missing nullability on parameter `who` in method `scheduleDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable#scheduleDrawable(android.graphics.drawable.Drawable, Runnable, long) parameter #1:
+    Missing nullability on parameter `what` in method `scheduleDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable#setChildDrawableAt(int, android.graphics.drawable.Drawable) parameter #1:
+    Missing nullability on parameter `drawable` in method `setChildDrawableAt`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable#setColorFilter(android.graphics.ColorFilter) parameter #0:
+    Missing nullability on parameter `colorFilter` in method `setColorFilter`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable#unscheduleDrawable(android.graphics.drawable.Drawable, Runnable) parameter #0:
+    Missing nullability on parameter `who` in method `unscheduleDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable#unscheduleDrawable(android.graphics.drawable.Drawable, Runnable) parameter #1:
+    Missing nullability on parameter `what` in method `unscheduleDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable.ChildDrawable#BOTTOM_ABSOLUTE:
+    Missing nullability on field `BOTTOM_ABSOLUTE` in class `class androidx.leanback.graphics.CompositeDrawable.ChildDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable.ChildDrawable#BOTTOM_FRACTION:
+    Missing nullability on field `BOTTOM_FRACTION` in class `class androidx.leanback.graphics.CompositeDrawable.ChildDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable.ChildDrawable#ChildDrawable(android.graphics.drawable.Drawable, androidx.leanback.graphics.CompositeDrawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `ChildDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable.ChildDrawable#ChildDrawable(android.graphics.drawable.Drawable, androidx.leanback.graphics.CompositeDrawable) parameter #1:
+    Missing nullability on parameter `parent` in method `ChildDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable.ChildDrawable#LEFT_ABSOLUTE:
+    Missing nullability on field `LEFT_ABSOLUTE` in class `class androidx.leanback.graphics.CompositeDrawable.ChildDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable.ChildDrawable#LEFT_FRACTION:
+    Missing nullability on field `LEFT_FRACTION` in class `class androidx.leanback.graphics.CompositeDrawable.ChildDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable.ChildDrawable#RIGHT_ABSOLUTE:
+    Missing nullability on field `RIGHT_ABSOLUTE` in class `class androidx.leanback.graphics.CompositeDrawable.ChildDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable.ChildDrawable#RIGHT_FRACTION:
+    Missing nullability on field `RIGHT_FRACTION` in class `class androidx.leanback.graphics.CompositeDrawable.ChildDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable.ChildDrawable#TOP_ABSOLUTE:
+    Missing nullability on field `TOP_ABSOLUTE` in class `class androidx.leanback.graphics.CompositeDrawable.ChildDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable.ChildDrawable#TOP_FRACTION:
+    Missing nullability on field `TOP_FRACTION` in class `class androidx.leanback.graphics.CompositeDrawable.ChildDrawable`
+MissingNullability: androidx.leanback.graphics.CompositeDrawable.ChildDrawable#getBoundsRule():
+    Missing nullability on method `getBoundsRule` return
+MissingNullability: androidx.leanback.graphics.CompositeDrawable.ChildDrawable#getDrawable():
+    Missing nullability on method `getDrawable` return
+MissingNullability: androidx.leanback.graphics.FitWidthBitmapDrawable#PROPERTY_VERTICAL_OFFSET:
+    Missing nullability on field `PROPERTY_VERTICAL_OFFSET` in class `class androidx.leanback.graphics.FitWidthBitmapDrawable`
+MissingNullability: androidx.leanback.graphics.FitWidthBitmapDrawable#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
+MissingNullability: androidx.leanback.graphics.FitWidthBitmapDrawable#getBitmap():
+    Missing nullability on method `getBitmap` return
+MissingNullability: androidx.leanback.graphics.FitWidthBitmapDrawable#getConstantState():
+    Missing nullability on method `getConstantState` return
+MissingNullability: androidx.leanback.graphics.FitWidthBitmapDrawable#getSource():
+    Missing nullability on method `getSource` return
+MissingNullability: androidx.leanback.graphics.FitWidthBitmapDrawable#mutate():
+    Missing nullability on method `mutate` return
+MissingNullability: androidx.leanback.graphics.FitWidthBitmapDrawable#setBitmap(android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `bitmap` in method `setBitmap`
+MissingNullability: androidx.leanback.graphics.FitWidthBitmapDrawable#setColorFilter(android.graphics.ColorFilter) parameter #0:
+    Missing nullability on parameter `colorFilter` in method `setColorFilter`
+MissingNullability: androidx.leanback.graphics.FitWidthBitmapDrawable#setSource(android.graphics.Rect) parameter #0:
+    Missing nullability on parameter `source` in method `setSource`
+MissingNullability: androidx.leanback.media.MediaControllerAdapter#MediaControllerAdapter(android.support.v4.media.session.MediaControllerCompat) parameter #0:
+    Missing nullability on parameter `controller` in method `MediaControllerAdapter`
+MissingNullability: androidx.leanback.media.MediaControllerAdapter#getMediaArt(android.content.Context):
+    Missing nullability on method `getMediaArt` return
+MissingNullability: androidx.leanback.media.MediaControllerAdapter#getMediaArt(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `getMediaArt`
+MissingNullability: androidx.leanback.media.MediaControllerAdapter#getMediaController():
+    Missing nullability on method `getMediaController` return
+MissingNullability: androidx.leanback.media.MediaControllerAdapter#getMediaSubtitle():
+    Missing nullability on method `getMediaSubtitle` return
+MissingNullability: androidx.leanback.media.MediaControllerAdapter#getMediaTitle():
+    Missing nullability on method `getMediaTitle` return
+MissingNullability: androidx.leanback.media.MediaControllerAdapter#onAttachedToHost(androidx.leanback.media.PlaybackGlueHost) parameter #0:
+    Missing nullability on parameter `host` in method `onAttachedToHost`
+MissingNullability: androidx.leanback.media.MediaControllerGlue#MediaControllerGlue(android.content.Context, int[], int[]) parameter #0:
+    Missing nullability on parameter `context` in method `MediaControllerGlue`
+MissingNullability: androidx.leanback.media.MediaControllerGlue#MediaControllerGlue(android.content.Context, int[], int[]) parameter #1:
+    Missing nullability on parameter `fastForwardSpeeds` in method `MediaControllerGlue`
+MissingNullability: androidx.leanback.media.MediaControllerGlue#MediaControllerGlue(android.content.Context, int[], int[]) parameter #2:
+    Missing nullability on parameter `rewindSpeeds` in method `MediaControllerGlue`
+MissingNullability: androidx.leanback.media.MediaControllerGlue#attachToMediaController(android.support.v4.media.session.MediaControllerCompat) parameter #0:
+    Missing nullability on parameter `mediaController` in method `attachToMediaController`
+MissingNullability: androidx.leanback.media.MediaControllerGlue#getMediaArt():
+    Missing nullability on method `getMediaArt` return
+MissingNullability: androidx.leanback.media.MediaControllerGlue#getMediaController():
+    Missing nullability on method `getMediaController` return
+MissingNullability: androidx.leanback.media.MediaControllerGlue#getMediaSubtitle():
+    Missing nullability on method `getMediaSubtitle` return
+MissingNullability: androidx.leanback.media.MediaControllerGlue#getMediaTitle():
+    Missing nullability on method `getMediaTitle` return
+MissingNullability: androidx.leanback.media.MediaPlayerAdapter#MediaPlayerAdapter(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `MediaPlayerAdapter`
+MissingNullability: androidx.leanback.media.MediaPlayerAdapter#getMediaPlayer():
+    Missing nullability on method `getMediaPlayer` return
+MissingNullability: androidx.leanback.media.MediaPlayerAdapter#onAttachedToHost(androidx.leanback.media.PlaybackGlueHost) parameter #0:
+    Missing nullability on parameter `host` in method `onAttachedToHost`
+MissingNullability: androidx.leanback.media.MediaPlayerAdapter#setDataSource(android.net.Uri) parameter #0:
+    Missing nullability on parameter `uri` in method `setDataSource`
+MissingNullability: androidx.leanback.media.PlaybackBannerControlGlue#PlaybackBannerControlGlue(android.content.Context, int[], T) parameter #0:
+    Missing nullability on parameter `context` in method `PlaybackBannerControlGlue`
+MissingNullability: androidx.leanback.media.PlaybackBannerControlGlue#PlaybackBannerControlGlue(android.content.Context, int[], T) parameter #1:
+    Missing nullability on parameter `seekSpeeds` in method `PlaybackBannerControlGlue`
+MissingNullability: androidx.leanback.media.PlaybackBannerControlGlue#PlaybackBannerControlGlue(android.content.Context, int[], int[], T) parameter #0:
+    Missing nullability on parameter `context` in method `PlaybackBannerControlGlue`
+MissingNullability: androidx.leanback.media.PlaybackBannerControlGlue#PlaybackBannerControlGlue(android.content.Context, int[], int[], T) parameter #1:
+    Missing nullability on parameter `fastForwardSpeeds` in method `PlaybackBannerControlGlue`
+MissingNullability: androidx.leanback.media.PlaybackBannerControlGlue#PlaybackBannerControlGlue(android.content.Context, int[], int[], T) parameter #2:
+    Missing nullability on parameter `rewindSpeeds` in method `PlaybackBannerControlGlue`
+MissingNullability: androidx.leanback.media.PlaybackBannerControlGlue#onActionClicked(androidx.leanback.widget.Action) parameter #0:
+    Missing nullability on parameter `action` in method `onActionClicked`
+MissingNullability: androidx.leanback.media.PlaybackBannerControlGlue#onCreatePrimaryActions(androidx.leanback.widget.ArrayObjectAdapter) parameter #0:
+    Missing nullability on parameter `primaryActionsAdapter` in method `onCreatePrimaryActions`
+MissingNullability: androidx.leanback.media.PlaybackBannerControlGlue#onCreateRowPresenter():
+    Missing nullability on method `onCreateRowPresenter` return
+MissingNullability: androidx.leanback.media.PlaybackBannerControlGlue#onKey(android.view.View, int, android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `v` in method `onKey`
+MissingNullability: androidx.leanback.media.PlaybackBannerControlGlue#onKey(android.view.View, int, android.view.KeyEvent) parameter #2:
+    Missing nullability on parameter `event` in method `onKey`
+MissingNullability: androidx.leanback.media.PlaybackBannerControlGlue#setControlsRow(androidx.leanback.widget.PlaybackControlsRow) parameter #0:
+    Missing nullability on parameter `controlsRow` in method `setControlsRow`
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#PlaybackBaseControlGlue(android.content.Context, T) parameter #0:
+    Missing nullability on parameter `context` in method `PlaybackBaseControlGlue`
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#getArt():
+    Missing nullability on method `getArt` return
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#getControlsRow():
+    Missing nullability on method `getControlsRow` return
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#getPlaybackRowPresenter():
+    Missing nullability on method `getPlaybackRowPresenter` return
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#getSubtitle():
+    Missing nullability on method `getSubtitle` return
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#notifyItemChanged(androidx.leanback.widget.ArrayObjectAdapter, Object) parameter #0:
+    Missing nullability on parameter `adapter` in method `notifyItemChanged`
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#notifyItemChanged(androidx.leanback.widget.ArrayObjectAdapter, Object) parameter #1:
+    Missing nullability on parameter `object` in method `notifyItemChanged`
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#onActionClicked(androidx.leanback.widget.Action) parameter #0:
+    Missing nullability on parameter `action` in method `onActionClicked`
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#onAttachedToHost(androidx.leanback.media.PlaybackGlueHost) parameter #0:
+    Missing nullability on parameter `host` in method `onAttachedToHost`
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#onCreatePrimaryActions(androidx.leanback.widget.ArrayObjectAdapter) parameter #0:
+    Missing nullability on parameter `primaryActionsAdapter` in method `onCreatePrimaryActions`
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#onCreateRowPresenter():
+    Missing nullability on method `onCreateRowPresenter` return
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#onCreateSecondaryActions(androidx.leanback.widget.ArrayObjectAdapter) parameter #0:
+    Missing nullability on parameter `secondaryActionsAdapter` in method `onCreateSecondaryActions`
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#onKey(android.view.View, int, android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `v` in method `onKey`
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#onKey(android.view.View, int, android.view.KeyEvent) parameter #2:
+    Missing nullability on parameter `event` in method `onKey`
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#setArt(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `cover` in method `setArt`
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#setControlsRow(androidx.leanback.widget.PlaybackControlsRow) parameter #0:
+    Missing nullability on parameter `controlsRow` in method `setControlsRow`
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#setPlaybackRowPresenter(androidx.leanback.widget.PlaybackRowPresenter) parameter #0:
+    Missing nullability on parameter `presenter` in method `setPlaybackRowPresenter`
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#setSubtitle(CharSequence) parameter #0:
+    Missing nullability on parameter `subtitle` in method `setSubtitle`
+MissingNullability: androidx.leanback.media.PlaybackBaseControlGlue#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#PlaybackControlGlue(android.content.Context, int[]) parameter #0:
+    Missing nullability on parameter `context` in method `PlaybackControlGlue`
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#PlaybackControlGlue(android.content.Context, int[]) parameter #1:
+    Missing nullability on parameter `seekSpeeds` in method `PlaybackControlGlue`
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#PlaybackControlGlue(android.content.Context, int[], int[]) parameter #0:
+    Missing nullability on parameter `context` in method `PlaybackControlGlue`
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#PlaybackControlGlue(android.content.Context, int[], int[]) parameter #1:
+    Missing nullability on parameter `fastForwardSpeeds` in method `PlaybackControlGlue`
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#PlaybackControlGlue(android.content.Context, int[], int[]) parameter #2:
+    Missing nullability on parameter `rewindSpeeds` in method `PlaybackControlGlue`
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#getControlsRow():
+    Missing nullability on method `getControlsRow` return
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#getFastForwardSpeeds():
+    Missing nullability on method `getFastForwardSpeeds` return
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#getMediaArt():
+    Missing nullability on method `getMediaArt` return
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#getMediaSubtitle():
+    Missing nullability on method `getMediaSubtitle` return
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#getMediaTitle():
+    Missing nullability on method `getMediaTitle` return
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#getPlaybackRowPresenter():
+    Missing nullability on method `getPlaybackRowPresenter` return
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#getRewindSpeeds():
+    Missing nullability on method `getRewindSpeeds` return
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#onActionClicked(androidx.leanback.widget.Action) parameter #0:
+    Missing nullability on parameter `action` in method `onActionClicked`
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#onAttachedToHost(androidx.leanback.media.PlaybackGlueHost) parameter #0:
+    Missing nullability on parameter `host` in method `onAttachedToHost`
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#onCreatePrimaryActions(androidx.leanback.widget.SparseArrayObjectAdapter) parameter #0:
+    Missing nullability on parameter `primaryActionsAdapter` in method `onCreatePrimaryActions`
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#onCreateSecondaryActions(androidx.leanback.widget.ArrayObjectAdapter) parameter #0:
+    Missing nullability on parameter `secondaryActionsAdapter` in method `onCreateSecondaryActions`
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#onKey(android.view.View, int, android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `v` in method `onKey`
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#onKey(android.view.View, int, android.view.KeyEvent) parameter #2:
+    Missing nullability on parameter `event` in method `onKey`
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#setControlsRow(androidx.leanback.widget.PlaybackControlsRow) parameter #0:
+    Missing nullability on parameter `controlsRow` in method `setControlsRow`
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#setControlsRowPresenter(androidx.leanback.widget.PlaybackControlsRowPresenter) parameter #0:
+    Missing nullability on parameter `presenter` in method `setControlsRowPresenter`
+MissingNullability: androidx.leanback.media.PlaybackControlGlue#setPlaybackRowPresenter(androidx.leanback.widget.PlaybackRowPresenter) parameter #0:
+    Missing nullability on parameter `presenter` in method `setPlaybackRowPresenter`
+MissingNullability: androidx.leanback.media.PlaybackGlue#PlaybackGlue(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `PlaybackGlue`
+MissingNullability: androidx.leanback.media.PlaybackGlue#addPlayerCallback(androidx.leanback.media.PlaybackGlue.PlayerCallback) parameter #0:
+    Missing nullability on parameter `playerCallback` in method `addPlayerCallback`
+MissingNullability: androidx.leanback.media.PlaybackGlue#getContext():
+    Missing nullability on method `getContext` return
+MissingNullability: androidx.leanback.media.PlaybackGlue#getHost():
+    Missing nullability on method `getHost` return
+MissingNullability: androidx.leanback.media.PlaybackGlue#getPlayerCallbacks():
+    Missing nullability on method `getPlayerCallbacks` return
+MissingNullability: androidx.leanback.media.PlaybackGlue#onAttachedToHost(androidx.leanback.media.PlaybackGlueHost) parameter #0:
+    Missing nullability on parameter `host` in method `onAttachedToHost`
+MissingNullability: androidx.leanback.media.PlaybackGlue#removePlayerCallback(androidx.leanback.media.PlaybackGlue.PlayerCallback) parameter #0:
+    Missing nullability on parameter `callback` in method `removePlayerCallback`
+MissingNullability: androidx.leanback.media.PlaybackGlue#setHost(androidx.leanback.media.PlaybackGlueHost) parameter #0:
+    Missing nullability on parameter `host` in method `setHost`
+MissingNullability: androidx.leanback.media.PlaybackGlue.PlayerCallback#onPlayCompleted(androidx.leanback.media.PlaybackGlue) parameter #0:
+    Missing nullability on parameter `glue` in method `onPlayCompleted`
+MissingNullability: androidx.leanback.media.PlaybackGlue.PlayerCallback#onPlayStateChanged(androidx.leanback.media.PlaybackGlue) parameter #0:
+    Missing nullability on parameter `glue` in method `onPlayStateChanged`
+MissingNullability: androidx.leanback.media.PlaybackGlue.PlayerCallback#onPreparedStateChanged(androidx.leanback.media.PlaybackGlue) parameter #0:
+    Missing nullability on parameter `glue` in method `onPreparedStateChanged`
+MissingNullability: androidx.leanback.media.PlaybackGlueHost#getPlayerCallback():
+    Missing nullability on method `getPlayerCallback` return
+MissingNullability: androidx.leanback.media.PlaybackGlueHost#setHostCallback(androidx.leanback.media.PlaybackGlueHost.HostCallback) parameter #0:
+    Missing nullability on parameter `callback` in method `setHostCallback`
+MissingNullability: androidx.leanback.media.PlaybackGlueHost#setOnActionClickedListener(androidx.leanback.widget.OnActionClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnActionClickedListener`
+MissingNullability: androidx.leanback.media.PlaybackGlueHost#setOnKeyInterceptListener(android.view.View.OnKeyListener) parameter #0:
+    Missing nullability on parameter `onKeyListener` in method `setOnKeyInterceptListener`
+MissingNullability: androidx.leanback.media.PlaybackGlueHost#setPlaybackRow(androidx.leanback.widget.Row) parameter #0:
+    Missing nullability on parameter `row` in method `setPlaybackRow`
+MissingNullability: androidx.leanback.media.PlaybackGlueHost#setPlaybackRowPresenter(androidx.leanback.widget.PlaybackRowPresenter) parameter #0:
+    Missing nullability on parameter `presenter` in method `setPlaybackRowPresenter`
+MissingNullability: androidx.leanback.media.PlaybackGlueHost.PlayerCallback#onError(int, CharSequence) parameter #1:
+    Missing nullability on parameter `errorMessage` in method `onError`
+MissingNullability: androidx.leanback.media.PlaybackTransportControlGlue#PlaybackTransportControlGlue(android.content.Context, T) parameter #0:
+    Missing nullability on parameter `context` in method `PlaybackTransportControlGlue`
+MissingNullability: androidx.leanback.media.PlaybackTransportControlGlue#getSeekProvider():
+    Missing nullability on method `getSeekProvider` return
+MissingNullability: androidx.leanback.media.PlaybackTransportControlGlue#onActionClicked(androidx.leanback.widget.Action) parameter #0:
+    Missing nullability on parameter `action` in method `onActionClicked`
+MissingNullability: androidx.leanback.media.PlaybackTransportControlGlue#onAttachedToHost(androidx.leanback.media.PlaybackGlueHost) parameter #0:
+    Missing nullability on parameter `host` in method `onAttachedToHost`
+MissingNullability: androidx.leanback.media.PlaybackTransportControlGlue#onCreatePrimaryActions(androidx.leanback.widget.ArrayObjectAdapter) parameter #0:
+    Missing nullability on parameter `primaryActionsAdapter` in method `onCreatePrimaryActions`
+MissingNullability: androidx.leanback.media.PlaybackTransportControlGlue#onCreateRowPresenter():
+    Missing nullability on method `onCreateRowPresenter` return
+MissingNullability: androidx.leanback.media.PlaybackTransportControlGlue#onKey(android.view.View, int, android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `v` in method `onKey`
+MissingNullability: androidx.leanback.media.PlaybackTransportControlGlue#onKey(android.view.View, int, android.view.KeyEvent) parameter #2:
+    Missing nullability on parameter `event` in method `onKey`
+MissingNullability: androidx.leanback.media.PlaybackTransportControlGlue#setControlsRow(androidx.leanback.widget.PlaybackControlsRow) parameter #0:
+    Missing nullability on parameter `controlsRow` in method `setControlsRow`
+MissingNullability: androidx.leanback.media.PlaybackTransportControlGlue#setSeekProvider(androidx.leanback.widget.PlaybackSeekDataProvider) parameter #0:
+    Missing nullability on parameter `seekProvider` in method `setSeekProvider`
+MissingNullability: androidx.leanback.media.PlayerAdapter#getCallback():
+    Missing nullability on method `getCallback` return
+MissingNullability: androidx.leanback.media.PlayerAdapter#onAttachedToHost(androidx.leanback.media.PlaybackGlueHost) parameter #0:
+    Missing nullability on parameter `host` in method `onAttachedToHost`
+MissingNullability: androidx.leanback.media.PlayerAdapter#setCallback(androidx.leanback.media.PlayerAdapter.Callback) parameter #0:
+    Missing nullability on parameter `callback` in method `setCallback`
+MissingNullability: androidx.leanback.media.PlayerAdapter.Callback#onBufferedPositionChanged(androidx.leanback.media.PlayerAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `onBufferedPositionChanged`
+MissingNullability: androidx.leanback.media.PlayerAdapter.Callback#onBufferingStateChanged(androidx.leanback.media.PlayerAdapter, boolean) parameter #0:
+    Missing nullability on parameter `adapter` in method `onBufferingStateChanged`
+MissingNullability: androidx.leanback.media.PlayerAdapter.Callback#onCurrentPositionChanged(androidx.leanback.media.PlayerAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `onCurrentPositionChanged`
+MissingNullability: androidx.leanback.media.PlayerAdapter.Callback#onDurationChanged(androidx.leanback.media.PlayerAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `onDurationChanged`
+MissingNullability: androidx.leanback.media.PlayerAdapter.Callback#onError(androidx.leanback.media.PlayerAdapter, int, String) parameter #0:
+    Missing nullability on parameter `adapter` in method `onError`
+MissingNullability: androidx.leanback.media.PlayerAdapter.Callback#onError(androidx.leanback.media.PlayerAdapter, int, String) parameter #2:
+    Missing nullability on parameter `errorMessage` in method `onError`
+MissingNullability: androidx.leanback.media.PlayerAdapter.Callback#onMetadataChanged(androidx.leanback.media.PlayerAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `onMetadataChanged`
+MissingNullability: androidx.leanback.media.PlayerAdapter.Callback#onPlayCompleted(androidx.leanback.media.PlayerAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `onPlayCompleted`
+MissingNullability: androidx.leanback.media.PlayerAdapter.Callback#onPlayStateChanged(androidx.leanback.media.PlayerAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `onPlayStateChanged`
+MissingNullability: androidx.leanback.media.PlayerAdapter.Callback#onPreparedStateChanged(androidx.leanback.media.PlayerAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `onPreparedStateChanged`
+MissingNullability: androidx.leanback.media.PlayerAdapter.Callback#onVideoSizeChanged(androidx.leanback.media.PlayerAdapter, int, int) parameter #0:
+    Missing nullability on parameter `adapter` in method `onVideoSizeChanged`
+MissingNullability: androidx.leanback.media.SurfaceHolderGlueHost#setSurfaceHolderCallback(android.view.SurfaceHolder.Callback) parameter #0:
+    Missing nullability on parameter `callback` in method `setSurfaceHolderCallback`
+MissingNullability: androidx.leanback.system.Settings#getBoolean(String) parameter #0:
+    Missing nullability on parameter `key` in method `getBoolean`
+MissingNullability: androidx.leanback.system.Settings#getInstance(android.content.Context):
+    Missing nullability on method `getInstance` return
+MissingNullability: androidx.leanback.system.Settings#getInstance(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `getInstance`
+MissingNullability: androidx.leanback.system.Settings#setBoolean(String, boolean) parameter #0:
+    Missing nullability on parameter `key` in method `setBoolean`
+MissingNullability: androidx.leanback.widget.AbstractDetailsDescriptionPresenter#onBindDescription(androidx.leanback.widget.AbstractDetailsDescriptionPresenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `vh` in method `onBindDescription`
+MissingNullability: androidx.leanback.widget.AbstractDetailsDescriptionPresenter#onBindDescription(androidx.leanback.widget.AbstractDetailsDescriptionPresenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindDescription`
+MissingNullability: androidx.leanback.widget.AbstractDetailsDescriptionPresenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.AbstractDetailsDescriptionPresenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.AbstractDetailsDescriptionPresenter#onCreateViewHolder(android.view.ViewGroup):
+    Missing nullability on method `onCreateViewHolder` return
+MissingNullability: androidx.leanback.widget.AbstractDetailsDescriptionPresenter#onCreateViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `onCreateViewHolder`
+MissingNullability: androidx.leanback.widget.AbstractDetailsDescriptionPresenter#onUnbindViewHolder(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onUnbindViewHolder`
+MissingNullability: androidx.leanback.widget.AbstractDetailsDescriptionPresenter#onViewAttachedToWindow(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onViewAttachedToWindow`
+MissingNullability: androidx.leanback.widget.AbstractDetailsDescriptionPresenter#onViewDetachedFromWindow(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onViewDetachedFromWindow`
+MissingNullability: androidx.leanback.widget.AbstractDetailsDescriptionPresenter.ViewHolder#ViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.AbstractDetailsDescriptionPresenter.ViewHolder#getBody():
+    Missing nullability on method `getBody` return
+MissingNullability: androidx.leanback.widget.AbstractDetailsDescriptionPresenter.ViewHolder#getSubtitle():
+    Missing nullability on method `getSubtitle` return
+MissingNullability: androidx.leanback.widget.AbstractDetailsDescriptionPresenter.ViewHolder#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter#createRowViewHolder(android.view.ViewGroup):
+    Missing nullability on method `createRowViewHolder` return
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter#createRowViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `createRowViewHolder`
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter#getActionPresenter():
+    Missing nullability on method `getActionPresenter` return
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter#getMediaPlayState(Object) parameter #0:
+    Missing nullability on parameter `item` in method `getMediaPlayState`
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter#onBindMediaDetails(androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `vh` in method `onBindMediaDetails`
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter#onBindMediaDetails(androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindMediaDetails`
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter#onBindMediaPlayState(androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onBindMediaPlayState`
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter#onBindRowActions(androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onBindRowActions`
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter#onBindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `vh` in method `onBindRowViewHolder`
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter#onBindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindRowViewHolder`
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter#onUnbindMediaDetails(androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onUnbindMediaDetails`
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter#onUnbindMediaPlayState(androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onUnbindMediaPlayState`
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter#setActionPresenter(androidx.leanback.widget.Presenter) parameter #0:
+    Missing nullability on parameter `actionPresenter` in method `setActionPresenter`
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder#ViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder#getMediaItemActionsContainer():
+    Missing nullability on method `getMediaItemActionsContainer` return
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder#getMediaItemDetailsView():
+    Missing nullability on method `getMediaItemDetailsView` return
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder#getMediaItemDurationView():
+    Missing nullability on method `getMediaItemDurationView` return
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder#getMediaItemNameView():
+    Missing nullability on method `getMediaItemNameView` return
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder#getMediaItemNumberView():
+    Missing nullability on method `getMediaItemNumberView` return
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder#getMediaItemNumberViewFlipper():
+    Missing nullability on method `getMediaItemNumberViewFlipper` return
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder#getMediaItemPausedView():
+    Missing nullability on method `getMediaItemPausedView` return
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder#getMediaItemPlayingView():
+    Missing nullability on method `getMediaItemPlayingView` return
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder#getMediaItemRowActions():
+    Missing nullability on method `getMediaItemRowActions` return
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder#getMediaItemRowSeparator():
+    Missing nullability on method `getMediaItemRowSeparator` return
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder#getSelectorView():
+    Missing nullability on method `getSelectorView` return
+MissingNullability: androidx.leanback.widget.AbstractMediaItemPresenter.ViewHolder#notifyActionChanged(androidx.leanback.widget.MultiActionsProvider.MultiAction) parameter #0:
+    Missing nullability on parameter `action` in method `notifyActionChanged`
+MissingNullability: androidx.leanback.widget.AbstractMediaListHeaderPresenter#AbstractMediaListHeaderPresenter(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `AbstractMediaListHeaderPresenter`
+MissingNullability: androidx.leanback.widget.AbstractMediaListHeaderPresenter#createRowViewHolder(android.view.ViewGroup):
+    Missing nullability on method `createRowViewHolder` return
+MissingNullability: androidx.leanback.widget.AbstractMediaListHeaderPresenter#createRowViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `createRowViewHolder`
+MissingNullability: androidx.leanback.widget.AbstractMediaListHeaderPresenter#onBindMediaListHeaderViewHolder(androidx.leanback.widget.AbstractMediaListHeaderPresenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `vh` in method `onBindMediaListHeaderViewHolder`
+MissingNullability: androidx.leanback.widget.AbstractMediaListHeaderPresenter#onBindMediaListHeaderViewHolder(androidx.leanback.widget.AbstractMediaListHeaderPresenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindMediaListHeaderViewHolder`
+MissingNullability: androidx.leanback.widget.AbstractMediaListHeaderPresenter#onBindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `vh` in method `onBindRowViewHolder`
+MissingNullability: androidx.leanback.widget.AbstractMediaListHeaderPresenter#onBindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindRowViewHolder`
+MissingNullability: androidx.leanback.widget.AbstractMediaListHeaderPresenter.ViewHolder#ViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.AbstractMediaListHeaderPresenter.ViewHolder#getHeaderView():
+    Missing nullability on method `getHeaderView` return
+MissingNullability: androidx.leanback.widget.Action#Action(long, CharSequence) parameter #1:
+    Missing nullability on parameter `label` in method `Action`
+MissingNullability: androidx.leanback.widget.Action#Action(long, CharSequence, CharSequence) parameter #1:
+    Missing nullability on parameter `label1` in method `Action`
+MissingNullability: androidx.leanback.widget.Action#Action(long, CharSequence, CharSequence) parameter #2:
+    Missing nullability on parameter `label2` in method `Action`
+MissingNullability: androidx.leanback.widget.Action#Action(long, CharSequence, CharSequence, android.graphics.drawable.Drawable) parameter #1:
+    Missing nullability on parameter `label1` in method `Action`
+MissingNullability: androidx.leanback.widget.Action#Action(long, CharSequence, CharSequence, android.graphics.drawable.Drawable) parameter #2:
+    Missing nullability on parameter `label2` in method `Action`
+MissingNullability: androidx.leanback.widget.Action#Action(long, CharSequence, CharSequence, android.graphics.drawable.Drawable) parameter #3:
+    Missing nullability on parameter `icon` in method `Action`
+MissingNullability: androidx.leanback.widget.Action#getIcon():
+    Missing nullability on method `getIcon` return
+MissingNullability: androidx.leanback.widget.Action#getLabel1():
+    Missing nullability on method `getLabel1` return
+MissingNullability: androidx.leanback.widget.Action#getLabel2():
+    Missing nullability on method `getLabel2` return
+MissingNullability: androidx.leanback.widget.Action#setIcon(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `icon` in method `setIcon`
+MissingNullability: androidx.leanback.widget.Action#setLabel1(CharSequence) parameter #0:
+    Missing nullability on parameter `label` in method `setLabel1`
+MissingNullability: androidx.leanback.widget.Action#setLabel2(CharSequence) parameter #0:
+    Missing nullability on parameter `label` in method `setLabel2`
+MissingNullability: androidx.leanback.widget.Action#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.leanback.widget.ArrayObjectAdapter#ArrayObjectAdapter(androidx.leanback.widget.Presenter) parameter #0:
+    Missing nullability on parameter `presenter` in method `ArrayObjectAdapter`
+MissingNullability: androidx.leanback.widget.ArrayObjectAdapter#ArrayObjectAdapter(androidx.leanback.widget.PresenterSelector) parameter #0:
+    Missing nullability on parameter `presenterSelector` in method `ArrayObjectAdapter`
+MissingNullability: androidx.leanback.widget.ArrayObjectAdapter#add(Object) parameter #0:
+    Missing nullability on parameter `item` in method `add`
+MissingNullability: androidx.leanback.widget.ArrayObjectAdapter#add(int, Object) parameter #1:
+    Missing nullability on parameter `item` in method `add`
+MissingNullability: androidx.leanback.widget.ArrayObjectAdapter#addAll(int, java.util.Collection) parameter #1:
+    Missing nullability on parameter `items` in method `addAll`
+MissingNullability: androidx.leanback.widget.ArrayObjectAdapter#get(int):
+    Missing nullability on method `get` return
+MissingNullability: androidx.leanback.widget.ArrayObjectAdapter#indexOf(Object) parameter #0:
+    Missing nullability on parameter `item` in method `indexOf`
+MissingNullability: androidx.leanback.widget.ArrayObjectAdapter#remove(Object) parameter #0:
+    Missing nullability on parameter `item` in method `remove`
+MissingNullability: androidx.leanback.widget.ArrayObjectAdapter#replace(int, Object) parameter #1:
+    Missing nullability on parameter `item` in method `replace`
+MissingNullability: androidx.leanback.widget.ArrayObjectAdapter#setItems(java.util.List, androidx.leanback.widget.DiffCallback) parameter #0:
+    Missing nullability on parameter `itemList` in method `setItems`
+MissingNullability: androidx.leanback.widget.ArrayObjectAdapter#setItems(java.util.List, androidx.leanback.widget.DiffCallback) parameter #1:
+    Missing nullability on parameter `callback` in method `setItems`
+MissingNullability: androidx.leanback.widget.ArrayObjectAdapter#unmodifiableList():
+    Missing nullability on method `unmodifiableList` return
+MissingNullability: androidx.leanback.widget.BaseCardView#BaseCardView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `BaseCardView`
+MissingNullability: androidx.leanback.widget.BaseCardView#BaseCardView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `BaseCardView`
+MissingNullability: androidx.leanback.widget.BaseCardView#BaseCardView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `BaseCardView`
+MissingNullability: androidx.leanback.widget.BaseCardView#BaseCardView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `BaseCardView`
+MissingNullability: androidx.leanback.widget.BaseCardView#BaseCardView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `BaseCardView`
+MissingNullability: androidx.leanback.widget.BaseCardView#checkLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `checkLayoutParams`
+MissingNullability: androidx.leanback.widget.BaseCardView#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.leanback.widget.BaseCardView#generateLayoutParams(android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.leanback.widget.BaseCardView#generateLayoutParams(android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.leanback.widget.BaseCardView#generateLayoutParams(android.view.ViewGroup.LayoutParams):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.leanback.widget.BaseCardView#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `lp` in method `generateLayoutParams`
+MissingNullability: androidx.leanback.widget.BaseCardView#onCreateDrawableState(int):
+    Missing nullability on method `onCreateDrawableState` return
+MissingNullability: androidx.leanback.widget.BaseCardView#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.leanback.widget.BaseCardView.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `c` in method `LayoutParams`
+MissingNullability: androidx.leanback.widget.BaseCardView.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `LayoutParams`
+MissingNullability: androidx.leanback.widget.BaseCardView.LayoutParams#LayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `LayoutParams`
+MissingNullability: androidx.leanback.widget.BaseCardView.LayoutParams#LayoutParams(androidx.leanback.widget.BaseCardView.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.leanback.widget.BaseGridView#addOnChildViewHolderSelectedListener(androidx.leanback.widget.OnChildViewHolderSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `addOnChildViewHolderSelectedListener`
+MissingNullability: androidx.leanback.widget.BaseGridView#dispatchGenericFocusedEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `event` in method `dispatchGenericFocusedEvent`
+MissingNullability: androidx.leanback.widget.BaseGridView#dispatchKeyEvent(android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `event` in method `dispatchKeyEvent`
+MissingNullability: androidx.leanback.widget.BaseGridView#dispatchTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `event` in method `dispatchTouchEvent`
+MissingNullability: androidx.leanback.widget.BaseGridView#focusSearch(int):
+    Missing nullability on method `focusSearch` return
+MissingNullability: androidx.leanback.widget.BaseGridView#getOnUnhandledKeyListener():
+    Missing nullability on method `getOnUnhandledKeyListener` return
+MissingNullability: androidx.leanback.widget.BaseGridView#getViewSelectedOffsets(android.view.View, int[]) parameter #0:
+    Missing nullability on parameter `view` in method `getViewSelectedOffsets`
+MissingNullability: androidx.leanback.widget.BaseGridView#getViewSelectedOffsets(android.view.View, int[]) parameter #1:
+    Missing nullability on parameter `offsets` in method `getViewSelectedOffsets`
+MissingNullability: androidx.leanback.widget.BaseGridView#onFocusChanged(boolean, int, android.graphics.Rect) parameter #2:
+    Missing nullability on parameter `previouslyFocusedRect` in method `onFocusChanged`
+MissingNullability: androidx.leanback.widget.BaseGridView#onRequestFocusInDescendants(int, android.graphics.Rect) parameter #1:
+    Missing nullability on parameter `previouslyFocusedRect` in method `onRequestFocusInDescendants`
+MissingNullability: androidx.leanback.widget.BaseGridView#removeOnChildViewHolderSelectedListener(androidx.leanback.widget.OnChildViewHolderSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `removeOnChildViewHolderSelectedListener`
+MissingNullability: androidx.leanback.widget.BaseGridView#removeView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `removeView`
+MissingNullability: androidx.leanback.widget.BaseGridView#setOnChildLaidOutListener(androidx.leanback.widget.OnChildLaidOutListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnChildLaidOutListener`
+MissingNullability: androidx.leanback.widget.BaseGridView#setOnChildSelectedListener(androidx.leanback.widget.OnChildSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnChildSelectedListener`
+MissingNullability: androidx.leanback.widget.BaseGridView#setOnChildViewHolderSelectedListener(androidx.leanback.widget.OnChildViewHolderSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnChildViewHolderSelectedListener`
+MissingNullability: androidx.leanback.widget.BaseGridView#setOnKeyInterceptListener(androidx.leanback.widget.BaseGridView.OnKeyInterceptListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnKeyInterceptListener`
+MissingNullability: androidx.leanback.widget.BaseGridView#setOnMotionInterceptListener(androidx.leanback.widget.BaseGridView.OnMotionInterceptListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnMotionInterceptListener`
+MissingNullability: androidx.leanback.widget.BaseGridView#setOnTouchInterceptListener(androidx.leanback.widget.BaseGridView.OnTouchInterceptListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnTouchInterceptListener`
+MissingNullability: androidx.leanback.widget.BaseGridView#setOnUnhandledKeyListener(androidx.leanback.widget.BaseGridView.OnUnhandledKeyListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnUnhandledKeyListener`
+MissingNullability: androidx.leanback.widget.BaseGridView#setRecyclerListener(androidx.recyclerview.widget.RecyclerView.RecyclerListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setRecyclerListener`
+MissingNullability: androidx.leanback.widget.BaseGridView#setSelectedPosition(int, androidx.leanback.widget.ViewHolderTask) parameter #1:
+    Missing nullability on parameter `task` in method `setSelectedPosition`
+MissingNullability: androidx.leanback.widget.BaseGridView#setSelectedPositionSmooth(int, androidx.leanback.widget.ViewHolderTask) parameter #1:
+    Missing nullability on parameter `task` in method `setSelectedPositionSmooth`
+MissingNullability: androidx.leanback.widget.BaseGridView.OnKeyInterceptListener#onInterceptKeyEvent(android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `event` in method `onInterceptKeyEvent`
+MissingNullability: androidx.leanback.widget.BaseGridView.OnMotionInterceptListener#onInterceptMotionEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `event` in method `onInterceptMotionEvent`
+MissingNullability: androidx.leanback.widget.BaseGridView.OnTouchInterceptListener#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `event` in method `onInterceptTouchEvent`
+MissingNullability: androidx.leanback.widget.BaseGridView.OnUnhandledKeyListener#onUnhandledKey(android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `event` in method `onUnhandledKey`
+MissingNullability: androidx.leanback.widget.BaseOnItemViewClickedListener#onItemClicked(androidx.leanback.widget.Presenter.ViewHolder, Object, androidx.leanback.widget.RowPresenter.ViewHolder, T) parameter #0:
+    Missing nullability on parameter `itemViewHolder` in method `onItemClicked`
+MissingNullability: androidx.leanback.widget.BaseOnItemViewClickedListener#onItemClicked(androidx.leanback.widget.Presenter.ViewHolder, Object, androidx.leanback.widget.RowPresenter.ViewHolder, T) parameter #1:
+    Missing nullability on parameter `item` in method `onItemClicked`
+MissingNullability: androidx.leanback.widget.BaseOnItemViewClickedListener#onItemClicked(androidx.leanback.widget.Presenter.ViewHolder, Object, androidx.leanback.widget.RowPresenter.ViewHolder, T) parameter #2:
+    Missing nullability on parameter `rowViewHolder` in method `onItemClicked`
+MissingNullability: androidx.leanback.widget.BaseOnItemViewSelectedListener#onItemSelected(androidx.leanback.widget.Presenter.ViewHolder, Object, androidx.leanback.widget.RowPresenter.ViewHolder, T) parameter #0:
+    Missing nullability on parameter `itemViewHolder` in method `onItemSelected`
+MissingNullability: androidx.leanback.widget.BaseOnItemViewSelectedListener#onItemSelected(androidx.leanback.widget.Presenter.ViewHolder, Object, androidx.leanback.widget.RowPresenter.ViewHolder, T) parameter #1:
+    Missing nullability on parameter `item` in method `onItemSelected`
+MissingNullability: androidx.leanback.widget.BaseOnItemViewSelectedListener#onItemSelected(androidx.leanback.widget.Presenter.ViewHolder, Object, androidx.leanback.widget.RowPresenter.ViewHolder, T) parameter #2:
+    Missing nullability on parameter `rowViewHolder` in method `onItemSelected`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout#BrowseFrameLayout(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `BrowseFrameLayout`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout#BrowseFrameLayout(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `BrowseFrameLayout`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout#BrowseFrameLayout(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `BrowseFrameLayout`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout#BrowseFrameLayout(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `BrowseFrameLayout`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout#BrowseFrameLayout(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `BrowseFrameLayout`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout#dispatchKeyEvent(android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `event` in method `dispatchKeyEvent`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout#focusSearch(android.view.View, int):
+    Missing nullability on method `focusSearch` return
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout#focusSearch(android.view.View, int) parameter #0:
+    Missing nullability on parameter `focused` in method `focusSearch`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout#getOnChildFocusListener():
+    Missing nullability on method `getOnChildFocusListener` return
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout#getOnFocusSearchListener():
+    Missing nullability on method `getOnFocusSearchListener` return
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout#onRequestFocusInDescendants(int, android.graphics.Rect) parameter #1:
+    Missing nullability on parameter `previouslyFocusedRect` in method `onRequestFocusInDescendants`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout#requestChildFocus(android.view.View, android.view.View) parameter #0:
+    Missing nullability on parameter `child` in method `requestChildFocus`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout#requestChildFocus(android.view.View, android.view.View) parameter #1:
+    Missing nullability on parameter `focused` in method `requestChildFocus`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout#setOnChildFocusListener(androidx.leanback.widget.BrowseFrameLayout.OnChildFocusListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnChildFocusListener`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout#setOnDispatchKeyListener(android.view.View.OnKeyListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnDispatchKeyListener`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout#setOnFocusSearchListener(androidx.leanback.widget.BrowseFrameLayout.OnFocusSearchListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnFocusSearchListener`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout.OnChildFocusListener#onRequestChildFocus(android.view.View, android.view.View) parameter #0:
+    Missing nullability on parameter `child` in method `onRequestChildFocus`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout.OnChildFocusListener#onRequestChildFocus(android.view.View, android.view.View) parameter #1:
+    Missing nullability on parameter `focused` in method `onRequestChildFocus`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout.OnChildFocusListener#onRequestFocusInDescendants(int, android.graphics.Rect) parameter #1:
+    Missing nullability on parameter `previouslyFocusedRect` in method `onRequestFocusInDescendants`
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout.OnFocusSearchListener#onFocusSearch(android.view.View, int):
+    Missing nullability on method `onFocusSearch` return
+MissingNullability: androidx.leanback.widget.BrowseFrameLayout.OnFocusSearchListener#onFocusSearch(android.view.View, int) parameter #0:
+    Missing nullability on parameter `focused` in method `onFocusSearch`
+MissingNullability: androidx.leanback.widget.ClassPresenterSelector#addClassPresenter(Class<?>, androidx.leanback.widget.Presenter):
+    Missing nullability on method `addClassPresenter` return
+MissingNullability: androidx.leanback.widget.ClassPresenterSelector#addClassPresenter(Class<?>, androidx.leanback.widget.Presenter) parameter #0:
+    Missing nullability on parameter `cls` in method `addClassPresenter`
+MissingNullability: androidx.leanback.widget.ClassPresenterSelector#addClassPresenter(Class<?>, androidx.leanback.widget.Presenter) parameter #1:
+    Missing nullability on parameter `presenter` in method `addClassPresenter`
+MissingNullability: androidx.leanback.widget.ClassPresenterSelector#addClassPresenterSelector(Class<?>, androidx.leanback.widget.PresenterSelector):
+    Missing nullability on method `addClassPresenterSelector` return
+MissingNullability: androidx.leanback.widget.ClassPresenterSelector#addClassPresenterSelector(Class<?>, androidx.leanback.widget.PresenterSelector) parameter #0:
+    Missing nullability on parameter `cls` in method `addClassPresenterSelector`
+MissingNullability: androidx.leanback.widget.ClassPresenterSelector#addClassPresenterSelector(Class<?>, androidx.leanback.widget.PresenterSelector) parameter #1:
+    Missing nullability on parameter `presenterSelector` in method `addClassPresenterSelector`
+MissingNullability: androidx.leanback.widget.ClassPresenterSelector#getPresenter(Object):
+    Missing nullability on method `getPresenter` return
+MissingNullability: androidx.leanback.widget.ClassPresenterSelector#getPresenter(Object) parameter #0:
+    Missing nullability on parameter `item` in method `getPresenter`
+MissingNullability: androidx.leanback.widget.ClassPresenterSelector#getPresenters():
+    Missing nullability on method `getPresenters` return
+MissingNullability: androidx.leanback.widget.ControlButtonPresenterSelector#getPresenter(Object):
+    Missing nullability on method `getPresenter` return
+MissingNullability: androidx.leanback.widget.ControlButtonPresenterSelector#getPresenter(Object) parameter #0:
+    Missing nullability on parameter `item` in method `getPresenter`
+MissingNullability: androidx.leanback.widget.ControlButtonPresenterSelector#getPresenters():
+    Missing nullability on method `getPresenters` return
+MissingNullability: androidx.leanback.widget.ControlButtonPresenterSelector#getPrimaryPresenter():
+    Missing nullability on method `getPrimaryPresenter` return
+MissingNullability: androidx.leanback.widget.ControlButtonPresenterSelector#getSecondaryPresenter():
+    Missing nullability on method `getSecondaryPresenter` return
+MissingNullability: androidx.leanback.widget.CursorObjectAdapter#CursorObjectAdapter(androidx.leanback.widget.Presenter) parameter #0:
+    Missing nullability on parameter `presenter` in method `CursorObjectAdapter`
+MissingNullability: androidx.leanback.widget.CursorObjectAdapter#CursorObjectAdapter(androidx.leanback.widget.PresenterSelector) parameter #0:
+    Missing nullability on parameter `presenterSelector` in method `CursorObjectAdapter`
+MissingNullability: androidx.leanback.widget.CursorObjectAdapter#changeCursor(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `cursor` in method `changeCursor`
+MissingNullability: androidx.leanback.widget.CursorObjectAdapter#get(int):
+    Missing nullability on method `get` return
+MissingNullability: androidx.leanback.widget.CursorObjectAdapter#getCursor():
+    Missing nullability on method `getCursor` return
+MissingNullability: androidx.leanback.widget.CursorObjectAdapter#getMapper():
+    Missing nullability on method `getMapper` return
+MissingNullability: androidx.leanback.widget.CursorObjectAdapter#setMapper(androidx.leanback.database.CursorMapper) parameter #0:
+    Missing nullability on parameter `mapper` in method `setMapper`
+MissingNullability: androidx.leanback.widget.CursorObjectAdapter#swapCursor(android.database.Cursor):
+    Missing nullability on method `swapCursor` return
+MissingNullability: androidx.leanback.widget.CursorObjectAdapter#swapCursor(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `cursor` in method `swapCursor`
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter#isBoundToImage(androidx.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder, androidx.leanback.widget.DetailsOverviewRow) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `isBoundToImage`
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter#isBoundToImage(androidx.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder, androidx.leanback.widget.DetailsOverviewRow) parameter #1:
+    Missing nullability on parameter `row` in method `isBoundToImage`
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter#onCreateView(android.view.ViewGroup):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter#onCreateView(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `onCreateView`
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter#onCreateViewHolder(android.view.ViewGroup):
+    Missing nullability on method `onCreateViewHolder` return
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter#onCreateViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `onCreateViewHolder`
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter#onUnbindViewHolder(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onUnbindViewHolder`
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter#setContext(androidx.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder, androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `setContext`
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter#setContext(androidx.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder, androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter) parameter #1:
+    Missing nullability on parameter `parentViewHolder` in method `setContext`
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter#setContext(androidx.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder, androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter) parameter #2:
+    Missing nullability on parameter `parentPresenter` in method `setContext`
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder#ViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder#getParentPresenter():
+    Missing nullability on method `getParentPresenter` return
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder#getParentViewHolder():
+    Missing nullability on method `getParentViewHolder` return
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder#mParentPresenter:
+    Missing nullability on field `mParentPresenter` in class `class androidx.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder`
+MissingNullability: androidx.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder#mParentViewHolder:
+    Missing nullability on field `mParentViewHolder` in class `class androidx.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRow#DetailsOverviewRow(Object) parameter #0:
+    Missing nullability on parameter `item` in method `DetailsOverviewRow`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRow#addAction(androidx.leanback.widget.Action) parameter #0:
+    Missing nullability on parameter `action` in method `addAction`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRow#addAction(int, androidx.leanback.widget.Action) parameter #1:
+    Missing nullability on parameter `action` in method `addAction`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRow#getActionForKeyCode(int):
+    Missing nullability on method `getActionForKeyCode` return
+MissingNullability: androidx.leanback.widget.DetailsOverviewRow#getActionsAdapter():
+    Missing nullability on method `getActionsAdapter` return
+MissingNullability: androidx.leanback.widget.DetailsOverviewRow#getImageDrawable():
+    Missing nullability on method `getImageDrawable` return
+MissingNullability: androidx.leanback.widget.DetailsOverviewRow#getItem():
+    Missing nullability on method `getItem` return
+MissingNullability: androidx.leanback.widget.DetailsOverviewRow#removeAction(androidx.leanback.widget.Action) parameter #0:
+    Missing nullability on parameter `action` in method `removeAction`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRow#setActionsAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setActionsAdapter`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRow#setImageBitmap(android.content.Context, android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `context` in method `setImageBitmap`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRow#setImageBitmap(android.content.Context, android.graphics.Bitmap) parameter #1:
+    Missing nullability on parameter `bm` in method `setImageBitmap`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRow#setImageDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setImageDrawable`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRow#setItem(Object) parameter #0:
+    Missing nullability on parameter `item` in method `setItem`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRow.Listener#onActionsAdapterChanged(androidx.leanback.widget.DetailsOverviewRow) parameter #0:
+    Missing nullability on parameter `row` in method `onActionsAdapterChanged`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRow.Listener#onImageDrawableChanged(androidx.leanback.widget.DetailsOverviewRow) parameter #0:
+    Missing nullability on parameter `row` in method `onImageDrawableChanged`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRow.Listener#onItemChanged(androidx.leanback.widget.DetailsOverviewRow) parameter #0:
+    Missing nullability on parameter `row` in method `onItemChanged`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter#DetailsOverviewRowPresenter(androidx.leanback.widget.Presenter) parameter #0:
+    Missing nullability on parameter `detailsPresenter` in method `DetailsOverviewRowPresenter`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter#createRowViewHolder(android.view.ViewGroup):
+    Missing nullability on method `createRowViewHolder` return
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter#createRowViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `createRowViewHolder`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter#getOnActionClickedListener():
+    Missing nullability on method `getOnActionClickedListener` return
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter#onBindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `holder` in method `onBindRowViewHolder`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter#onBindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindRowViewHolder`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter#onRowViewAttachedToWindow(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onRowViewAttachedToWindow`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter#onRowViewDetachedFromWindow(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onRowViewDetachedFromWindow`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter#onRowViewSelected(androidx.leanback.widget.RowPresenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `vh` in method `onRowViewSelected`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter#onSelectLevelChanged(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onSelectLevelChanged`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter#onUnbindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onUnbindRowViewHolder`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter#setOnActionClickedListener(androidx.leanback.widget.OnActionClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnActionClickedListener`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter#setSharedElementEnterTransition(android.app.Activity, String) parameter #0:
+    Missing nullability on parameter `activity` in method `setSharedElementEnterTransition`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter#setSharedElementEnterTransition(android.app.Activity, String) parameter #1:
+    Missing nullability on parameter `sharedElementName` in method `setSharedElementEnterTransition`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter#setSharedElementEnterTransition(android.app.Activity, String, long) parameter #0:
+    Missing nullability on parameter `activity` in method `setSharedElementEnterTransition`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter#setSharedElementEnterTransition(android.app.Activity, String, long) parameter #1:
+    Missing nullability on parameter `sharedElementName` in method `setSharedElementEnterTransition`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter.ViewHolder#ViewHolder(android.view.View, androidx.leanback.widget.Presenter) parameter #0:
+    Missing nullability on parameter `rootView` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter.ViewHolder#ViewHolder(android.view.View, androidx.leanback.widget.Presenter) parameter #1:
+    Missing nullability on parameter `detailsPresenter` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.DetailsOverviewRowPresenter.ViewHolder#mDetailsDescriptionViewHolder:
+    Missing nullability on field `mDetailsDescriptionViewHolder` in class `class androidx.leanback.widget.DetailsOverviewRowPresenter.ViewHolder`
+MissingNullability: androidx.leanback.widget.DetailsParallax#getOverviewRowBottom():
+    Missing nullability on method `getOverviewRowBottom` return
+MissingNullability: androidx.leanback.widget.DetailsParallax#getOverviewRowTop():
+    Missing nullability on method `getOverviewRowTop` return
+MissingNullability: androidx.leanback.widget.DiffCallback#getChangePayload(Value, Value):
+    Missing nullability on method `getChangePayload` return
+MissingNullability: androidx.leanback.widget.DividerPresenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.DividerPresenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.DividerPresenter#onCreateViewHolder(android.view.ViewGroup):
+    Missing nullability on method `onCreateViewHolder` return
+MissingNullability: androidx.leanback.widget.DividerPresenter#onCreateViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `onCreateViewHolder`
+MissingNullability: androidx.leanback.widget.DividerPresenter#onUnbindViewHolder(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onUnbindViewHolder`
+MissingNullability: androidx.leanback.widget.FacetProvider#getFacet(Class<?>):
+    Missing nullability on method `getFacet` return
+MissingNullability: androidx.leanback.widget.FacetProvider#getFacet(Class<?>) parameter #0:
+    Missing nullability on parameter `facetClass` in method `getFacet`
+MissingNullability: androidx.leanback.widget.FacetProviderAdapter#getFacetProvider(int):
+    Missing nullability on method `getFacetProvider` return
+MissingNullability: androidx.leanback.widget.FocusHighlightHelper#setupBrowseItemFocusHighlight(androidx.leanback.widget.ItemBridgeAdapter, int, boolean) parameter #0:
+    Missing nullability on parameter `adapter` in method `setupBrowseItemFocusHighlight`
+MissingNullability: androidx.leanback.widget.FocusHighlightHelper#setupHeaderItemFocusHighlight(androidx.leanback.widget.ItemBridgeAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setupHeaderItemFocusHighlight`
+MissingNullability: androidx.leanback.widget.FocusHighlightHelper#setupHeaderItemFocusHighlight(androidx.leanback.widget.ItemBridgeAdapter, boolean) parameter #0:
+    Missing nullability on parameter `adapter` in method `setupHeaderItemFocusHighlight`
+MissingNullability: androidx.leanback.widget.FocusHighlightHelper#setupHeaderItemFocusHighlight(androidx.leanback.widget.VerticalGridView) parameter #0:
+    Missing nullability on parameter `gridView` in method `setupHeaderItemFocusHighlight`
+MissingNullability: androidx.leanback.widget.FocusHighlightHelper#setupHeaderItemFocusHighlight(androidx.leanback.widget.VerticalGridView, boolean) parameter #0:
+    Missing nullability on parameter `gridView` in method `setupHeaderItemFocusHighlight`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#FullWidthDetailsOverviewRowPresenter(androidx.leanback.widget.Presenter) parameter #0:
+    Missing nullability on parameter `detailsPresenter` in method `FullWidthDetailsOverviewRowPresenter`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#FullWidthDetailsOverviewRowPresenter(androidx.leanback.widget.Presenter, androidx.leanback.widget.DetailsOverviewLogoPresenter) parameter #0:
+    Missing nullability on parameter `detailsPresenter` in method `FullWidthDetailsOverviewRowPresenter`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#FullWidthDetailsOverviewRowPresenter(androidx.leanback.widget.Presenter, androidx.leanback.widget.DetailsOverviewLogoPresenter) parameter #1:
+    Missing nullability on parameter `logoPresenter` in method `FullWidthDetailsOverviewRowPresenter`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#createRowViewHolder(android.view.ViewGroup):
+    Missing nullability on method `createRowViewHolder` return
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#createRowViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `createRowViewHolder`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#getOnActionClickedListener():
+    Missing nullability on method `getOnActionClickedListener` return
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#notifyOnBindLogo(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `notifyOnBindLogo`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#onBindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `holder` in method `onBindRowViewHolder`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#onBindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindRowViewHolder`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#onLayoutLogo(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, boolean) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onLayoutLogo`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#onLayoutOverviewFrame(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, boolean) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onLayoutOverviewFrame`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#onRowViewAttachedToWindow(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onRowViewAttachedToWindow`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#onRowViewDetachedFromWindow(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onRowViewDetachedFromWindow`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#onSelectLevelChanged(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onSelectLevelChanged`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#onStateChanged(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onStateChanged`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#onUnbindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onUnbindRowViewHolder`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#setEntranceTransitionState(androidx.leanback.widget.RowPresenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `holder` in method `setEntranceTransitionState`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#setListener(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.Listener) parameter #0:
+    Missing nullability on parameter `listener` in method `setListener`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#setOnActionClickedListener(androidx.leanback.widget.OnActionClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnActionClickedListener`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter#setState(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `setState`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.Listener#onBindLogo(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onBindLogo`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder#ViewHolder(android.view.View, androidx.leanback.widget.Presenter, androidx.leanback.widget.DetailsOverviewLogoPresenter) parameter #0:
+    Missing nullability on parameter `rootView` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder#ViewHolder(android.view.View, androidx.leanback.widget.Presenter, androidx.leanback.widget.DetailsOverviewLogoPresenter) parameter #1:
+    Missing nullability on parameter `detailsPresenter` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder#ViewHolder(android.view.View, androidx.leanback.widget.Presenter, androidx.leanback.widget.DetailsOverviewLogoPresenter) parameter #2:
+    Missing nullability on parameter `logoPresenter` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder#createRowListener():
+    Missing nullability on method `createRowListener` return
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder#getActionsRow():
+    Missing nullability on method `getActionsRow` return
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder#getDetailsDescriptionFrame():
+    Missing nullability on method `getDetailsDescriptionFrame` return
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder#getDetailsDescriptionViewHolder():
+    Missing nullability on method `getDetailsDescriptionViewHolder` return
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder#getLogoViewHolder():
+    Missing nullability on method `getLogoViewHolder` return
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder#getOverviewView():
+    Missing nullability on method `getOverviewView` return
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder#mRowListener:
+    Missing nullability on field `mRowListener` in class `class androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener#onActionsAdapterChanged(androidx.leanback.widget.DetailsOverviewRow) parameter #0:
+    Missing nullability on parameter `row` in method `onActionsAdapterChanged`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener#onImageDrawableChanged(androidx.leanback.widget.DetailsOverviewRow) parameter #0:
+    Missing nullability on parameter `row` in method `onImageDrawableChanged`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener#onItemChanged(androidx.leanback.widget.DetailsOverviewRow) parameter #0:
+    Missing nullability on parameter `row` in method `onItemChanged`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewSharedElementHelper#onBindLogo(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onBindLogo`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewSharedElementHelper#setSharedElementEnterTransition(android.app.Activity, String) parameter #0:
+    Missing nullability on parameter `activity` in method `setSharedElementEnterTransition`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewSharedElementHelper#setSharedElementEnterTransition(android.app.Activity, String) parameter #1:
+    Missing nullability on parameter `sharedElementName` in method `setSharedElementEnterTransition`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewSharedElementHelper#setSharedElementEnterTransition(android.app.Activity, String, long) parameter #0:
+    Missing nullability on parameter `activity` in method `setSharedElementEnterTransition`
+MissingNullability: androidx.leanback.widget.FullWidthDetailsOverviewSharedElementHelper#setSharedElementEnterTransition(android.app.Activity, String, long) parameter #1:
+    Missing nullability on parameter `sharedElementName` in method `setSharedElementEnterTransition`
+MissingNullability: androidx.leanback.widget.GuidanceStylist#getBreadcrumbView():
+    Missing nullability on method `getBreadcrumbView` return
+MissingNullability: androidx.leanback.widget.GuidanceStylist#getDescriptionView():
+    Missing nullability on method `getDescriptionView` return
+MissingNullability: androidx.leanback.widget.GuidanceStylist#getIconView():
+    Missing nullability on method `getIconView` return
+MissingNullability: androidx.leanback.widget.GuidanceStylist#getTitleView():
+    Missing nullability on method `getTitleView` return
+MissingNullability: androidx.leanback.widget.GuidanceStylist#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, androidx.leanback.widget.GuidanceStylist.Guidance):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.widget.GuidanceStylist#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, androidx.leanback.widget.GuidanceStylist.Guidance) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.widget.GuidanceStylist#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, androidx.leanback.widget.GuidanceStylist.Guidance) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.widget.GuidanceStylist#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, androidx.leanback.widget.GuidanceStylist.Guidance) parameter #2:
+    Missing nullability on parameter `guidance` in method `onCreateView`
+MissingNullability: androidx.leanback.widget.GuidanceStylist.Guidance#Guidance(String, String, String, android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `title` in method `Guidance`
+MissingNullability: androidx.leanback.widget.GuidanceStylist.Guidance#Guidance(String, String, String, android.graphics.drawable.Drawable) parameter #1:
+    Missing nullability on parameter `description` in method `Guidance`
+MissingNullability: androidx.leanback.widget.GuidanceStylist.Guidance#Guidance(String, String, String, android.graphics.drawable.Drawable) parameter #2:
+    Missing nullability on parameter `breadcrumb` in method `Guidance`
+MissingNullability: androidx.leanback.widget.GuidanceStylist.Guidance#Guidance(String, String, String, android.graphics.drawable.Drawable) parameter #3:
+    Missing nullability on parameter `icon` in method `Guidance`
+MissingNullability: androidx.leanback.widget.GuidanceStylist.Guidance#getBreadcrumb():
+    Missing nullability on method `getBreadcrumb` return
+MissingNullability: androidx.leanback.widget.GuidanceStylist.Guidance#getDescription():
+    Missing nullability on method `getDescription` return
+MissingNullability: androidx.leanback.widget.GuidanceStylist.Guidance#getIconDrawable():
+    Missing nullability on method `getIconDrawable` return
+MissingNullability: androidx.leanback.widget.GuidanceStylist.Guidance#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.leanback.widget.GuidedAction#getAutofillHints():
+    Missing nullability on method `getAutofillHints` return
+MissingNullability: androidx.leanback.widget.GuidedAction#getDescription():
+    Missing nullability on method `getDescription` return
+MissingNullability: androidx.leanback.widget.GuidedAction#getEditDescription():
+    Missing nullability on method `getEditDescription` return
+MissingNullability: androidx.leanback.widget.GuidedAction#getEditTitle():
+    Missing nullability on method `getEditTitle` return
+MissingNullability: androidx.leanback.widget.GuidedAction#getIntent():
+    Missing nullability on method `getIntent` return
+MissingNullability: androidx.leanback.widget.GuidedAction#getSubActions():
+    Missing nullability on method `getSubActions` return
+MissingNullability: androidx.leanback.widget.GuidedAction#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.leanback.widget.GuidedAction#onRestoreInstanceState(android.os.Bundle, String) parameter #0:
+    Missing nullability on parameter `bundle` in method `onRestoreInstanceState`
+MissingNullability: androidx.leanback.widget.GuidedAction#onRestoreInstanceState(android.os.Bundle, String) parameter #1:
+    Missing nullability on parameter `key` in method `onRestoreInstanceState`
+MissingNullability: androidx.leanback.widget.GuidedAction#onSaveInstanceState(android.os.Bundle, String) parameter #0:
+    Missing nullability on parameter `bundle` in method `onSaveInstanceState`
+MissingNullability: androidx.leanback.widget.GuidedAction#onSaveInstanceState(android.os.Bundle, String) parameter #1:
+    Missing nullability on parameter `key` in method `onSaveInstanceState`
+MissingNullability: androidx.leanback.widget.GuidedAction#setDescription(CharSequence) parameter #0:
+    Missing nullability on parameter `description` in method `setDescription`
+MissingNullability: androidx.leanback.widget.GuidedAction#setEditDescription(CharSequence) parameter #0:
+    Missing nullability on parameter `editDescription` in method `setEditDescription`
+MissingNullability: androidx.leanback.widget.GuidedAction#setEditTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `editTitle` in method `setEditTitle`
+MissingNullability: androidx.leanback.widget.GuidedAction#setIntent(android.content.Intent) parameter #0:
+    Missing nullability on parameter `intent` in method `setIntent`
+MissingNullability: androidx.leanback.widget.GuidedAction#setSubActions(java.util.List<androidx.leanback.widget.GuidedAction>) parameter #0:
+    Missing nullability on parameter `actions` in method `setSubActions`
+MissingNullability: androidx.leanback.widget.GuidedAction#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.leanback.widget.GuidedAction.Builder#Builder(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `Builder`
+MissingNullability: androidx.leanback.widget.GuidedAction.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.leanback.widget.GuidedAction.BuilderBase#BuilderBase(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `BuilderBase`
+MissingNullability: androidx.leanback.widget.GuidedAction.BuilderBase#applyValues(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `applyValues`
+MissingNullability: androidx.leanback.widget.GuidedAction.BuilderBase#autofillHints(java.lang.String...) parameter #0:
+    Missing nullability on parameter `hints` in method `autofillHints`
+MissingNullability: androidx.leanback.widget.GuidedAction.BuilderBase#description(CharSequence) parameter #0:
+    Missing nullability on parameter `description` in method `description`
+MissingNullability: androidx.leanback.widget.GuidedAction.BuilderBase#editDescription(CharSequence) parameter #0:
+    Missing nullability on parameter `description` in method `editDescription`
+MissingNullability: androidx.leanback.widget.GuidedAction.BuilderBase#editTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `editTitle` in method `editTitle`
+MissingNullability: androidx.leanback.widget.GuidedAction.BuilderBase#getContext():
+    Missing nullability on method `getContext` return
+MissingNullability: androidx.leanback.widget.GuidedAction.BuilderBase#icon(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `icon` in method `icon`
+MissingNullability: androidx.leanback.widget.GuidedAction.BuilderBase#iconResourceId(int, android.content.Context) parameter #1:
+    Missing nullability on parameter `context` in method `iconResourceId`
+MissingNullability: androidx.leanback.widget.GuidedAction.BuilderBase#intent(android.content.Intent) parameter #0:
+    Missing nullability on parameter `intent` in method `intent`
+MissingNullability: androidx.leanback.widget.GuidedAction.BuilderBase#subActions(java.util.List<androidx.leanback.widget.GuidedAction>) parameter #0:
+    Missing nullability on parameter `subActions` in method `subActions`
+MissingNullability: androidx.leanback.widget.GuidedAction.BuilderBase#title(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `title`
+MissingNullability: androidx.leanback.widget.GuidedActionAutofillSupport#setOnAutofillListener(androidx.leanback.widget.GuidedActionAutofillSupport.OnAutofillListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnAutofillListener`
+MissingNullability: androidx.leanback.widget.GuidedActionAutofillSupport.OnAutofillListener#onAutofill(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onAutofill`
+MissingNullability: androidx.leanback.widget.GuidedActionDiffCallback#getInstance():
+    Missing nullability on method `getInstance` return
+MissingNullability: androidx.leanback.widget.GuidedActionEditText#GuidedActionEditText(android.content.Context) parameter #0:
+    Missing nullability on parameter `ctx` in method `GuidedActionEditText`
+MissingNullability: androidx.leanback.widget.GuidedActionEditText#GuidedActionEditText(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `ctx` in method `GuidedActionEditText`
+MissingNullability: androidx.leanback.widget.GuidedActionEditText#GuidedActionEditText(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `GuidedActionEditText`
+MissingNullability: androidx.leanback.widget.GuidedActionEditText#GuidedActionEditText(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `ctx` in method `GuidedActionEditText`
+MissingNullability: androidx.leanback.widget.GuidedActionEditText#GuidedActionEditText(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `GuidedActionEditText`
+MissingNullability: androidx.leanback.widget.GuidedActionEditText#autofill(android.view.autofill.AutofillValue) parameter #0:
+    Missing nullability on parameter `values` in method `autofill`
+MissingNullability: androidx.leanback.widget.GuidedActionEditText#onFocusChanged(boolean, int, android.graphics.Rect) parameter #2:
+    Missing nullability on parameter `previouslyFocusedRect` in method `onFocusChanged`
+MissingNullability: androidx.leanback.widget.GuidedActionEditText#onInitializeAccessibilityNodeInfo(android.view.accessibility.AccessibilityNodeInfo) parameter #0:
+    Missing nullability on parameter `info` in method `onInitializeAccessibilityNodeInfo`
+MissingNullability: androidx.leanback.widget.GuidedActionEditText#onKeyPreIme(int, android.view.KeyEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onKeyPreIme`
+MissingNullability: androidx.leanback.widget.GuidedActionEditText#setCustomSelectionActionModeCallback(android.view.ActionMode.Callback) parameter #0:
+    Missing nullability on parameter `actionModeCallback` in method `setCustomSelectionActionModeCallback`
+MissingNullability: androidx.leanback.widget.GuidedActionEditText#setImeKeyListener(androidx.leanback.widget.ImeKeyMonitor.ImeKeyListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setImeKeyListener`
+MissingNullability: androidx.leanback.widget.GuidedActionEditText#setOnAutofillListener(androidx.leanback.widget.GuidedActionAutofillSupport.OnAutofillListener) parameter #0:
+    Missing nullability on parameter `autofillListener` in method `setOnAutofillListener`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#expandAction(androidx.leanback.widget.GuidedAction, boolean) parameter #0:
+    Missing nullability on parameter `action` in method `expandAction`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#getActionsGridView():
+    Missing nullability on method `getActionsGridView` return
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#getExpandedAction():
+    Missing nullability on method `getExpandedAction` return
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#getItemViewType(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `getItemViewType`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#getSubActionsGridView():
+    Missing nullability on method `getSubActionsGridView` return
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onAnimateItemChecked(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `vh` in method `onAnimateItemChecked`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onAnimateItemFocused(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `vh` in method `onAnimateItemFocused`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onAnimateItemPressed(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `vh` in method `onAnimateItemPressed`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onAnimateItemPressedCancelled(androidx.leanback.widget.GuidedActionsStylist.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onAnimateItemPressedCancelled`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onBindActivatorView(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `vh` in method `onBindActivatorView`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onBindActivatorView(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, androidx.leanback.widget.GuidedAction) parameter #1:
+    Missing nullability on parameter `action` in method `onBindActivatorView`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onBindCheckMarkView(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `vh` in method `onBindCheckMarkView`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onBindCheckMarkView(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, androidx.leanback.widget.GuidedAction) parameter #1:
+    Missing nullability on parameter `action` in method `onBindCheckMarkView`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onBindChevronView(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `vh` in method `onBindChevronView`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onBindChevronView(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, androidx.leanback.widget.GuidedAction) parameter #1:
+    Missing nullability on parameter `action` in method `onBindChevronView`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onBindViewHolder(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `vh` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onBindViewHolder(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, androidx.leanback.widget.GuidedAction) parameter #1:
+    Missing nullability on parameter `action` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onCreateView(android.view.LayoutInflater, android.view.ViewGroup):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onCreateView(android.view.LayoutInflater, android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onCreateView(android.view.LayoutInflater, android.view.ViewGroup) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onCreateViewHolder(android.view.ViewGroup):
+    Missing nullability on method `onCreateViewHolder` return
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onCreateViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `onCreateViewHolder`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onCreateViewHolder(android.view.ViewGroup, int):
+    Missing nullability on method `onCreateViewHolder` return
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onCreateViewHolder(android.view.ViewGroup, int) parameter #0:
+    Missing nullability on parameter `parent` in method `onCreateViewHolder`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onEditingModeChange(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, androidx.leanback.widget.GuidedAction, boolean) parameter #0:
+    Missing nullability on parameter `vh` in method `onEditingModeChange`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onEditingModeChange(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, androidx.leanback.widget.GuidedAction, boolean) parameter #1:
+    Missing nullability on parameter `action` in method `onEditingModeChange`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onEditingModeChange(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, boolean, boolean) parameter #0:
+    Missing nullability on parameter `vh` in method `onEditingModeChange`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onUpdateActivatorView(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `vh` in method `onUpdateActivatorView`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onUpdateActivatorView(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, androidx.leanback.widget.GuidedAction) parameter #1:
+    Missing nullability on parameter `action` in method `onUpdateActivatorView`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#onUpdateExpandedViewHolder(androidx.leanback.widget.GuidedActionsStylist.ViewHolder) parameter #0:
+    Missing nullability on parameter `avh` in method `onUpdateExpandedViewHolder`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#openInEditMode(androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `action` in method `openInEditMode`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#setEditingMode(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, androidx.leanback.widget.GuidedAction, boolean) parameter #0:
+    Missing nullability on parameter `vh` in method `setEditingMode`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#setEditingMode(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, androidx.leanback.widget.GuidedAction, boolean) parameter #1:
+    Missing nullability on parameter `action` in method `setEditingMode`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#setExpandedViewHolder(androidx.leanback.widget.GuidedActionsStylist.ViewHolder) parameter #0:
+    Missing nullability on parameter `avh` in method `setExpandedViewHolder`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#setupImeOptions(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, androidx.leanback.widget.GuidedAction) parameter #0:
+    Missing nullability on parameter `vh` in method `setupImeOptions`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#setupImeOptions(androidx.leanback.widget.GuidedActionsStylist.ViewHolder, androidx.leanback.widget.GuidedAction) parameter #1:
+    Missing nullability on parameter `action` in method `setupImeOptions`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist#startExpandedTransition(androidx.leanback.widget.GuidedActionsStylist.ViewHolder) parameter #0:
+    Missing nullability on parameter `avh` in method `startExpandedTransition`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist.ViewHolder#ViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `v` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist.ViewHolder#ViewHolder(android.view.View, boolean) parameter #0:
+    Missing nullability on parameter `v` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist.ViewHolder#getAction():
+    Missing nullability on method `getAction` return
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist.ViewHolder#getCheckmarkView():
+    Missing nullability on method `getCheckmarkView` return
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist.ViewHolder#getChevronView():
+    Missing nullability on method `getChevronView` return
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist.ViewHolder#getContentView():
+    Missing nullability on method `getContentView` return
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist.ViewHolder#getDescriptionView():
+    Missing nullability on method `getDescriptionView` return
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist.ViewHolder#getEditableDescriptionView():
+    Missing nullability on method `getEditableDescriptionView` return
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist.ViewHolder#getEditableTitleView():
+    Missing nullability on method `getEditableTitleView` return
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist.ViewHolder#getEditingView():
+    Missing nullability on method `getEditingView` return
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist.ViewHolder#getFacet(Class<?>):
+    Missing nullability on method `getFacet` return
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist.ViewHolder#getFacet(Class<?>) parameter #0:
+    Missing nullability on parameter `facetClass` in method `getFacet`
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist.ViewHolder#getIconView():
+    Missing nullability on method `getIconView` return
+MissingNullability: androidx.leanback.widget.GuidedActionsStylist.ViewHolder#getTitleView():
+    Missing nullability on method `getTitleView` return
+MissingNullability: androidx.leanback.widget.GuidedDatePickerAction#getDatePickerFormat():
+    Missing nullability on method `getDatePickerFormat` return
+MissingNullability: androidx.leanback.widget.GuidedDatePickerAction#onRestoreInstanceState(android.os.Bundle, String) parameter #0:
+    Missing nullability on parameter `bundle` in method `onRestoreInstanceState`
+MissingNullability: androidx.leanback.widget.GuidedDatePickerAction#onRestoreInstanceState(android.os.Bundle, String) parameter #1:
+    Missing nullability on parameter `key` in method `onRestoreInstanceState`
+MissingNullability: androidx.leanback.widget.GuidedDatePickerAction#onSaveInstanceState(android.os.Bundle, String) parameter #0:
+    Missing nullability on parameter `bundle` in method `onSaveInstanceState`
+MissingNullability: androidx.leanback.widget.GuidedDatePickerAction#onSaveInstanceState(android.os.Bundle, String) parameter #1:
+    Missing nullability on parameter `key` in method `onSaveInstanceState`
+MissingNullability: androidx.leanback.widget.GuidedDatePickerAction.Builder#Builder(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `Builder`
+MissingNullability: androidx.leanback.widget.GuidedDatePickerAction.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.leanback.widget.GuidedDatePickerAction.BuilderBase#BuilderBase(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `BuilderBase`
+MissingNullability: androidx.leanback.widget.GuidedDatePickerAction.BuilderBase#applyDatePickerValues(androidx.leanback.widget.GuidedDatePickerAction) parameter #0:
+    Missing nullability on parameter `action` in method `applyDatePickerValues`
+MissingNullability: androidx.leanback.widget.GuidedDatePickerAction.BuilderBase#datePickerFormat(String) parameter #0:
+    Missing nullability on parameter `format` in method `datePickerFormat`
+MissingNullability: androidx.leanback.widget.HeaderItem#HeaderItem(String) parameter #0:
+    Missing nullability on parameter `name` in method `HeaderItem`
+MissingNullability: androidx.leanback.widget.HeaderItem#HeaderItem(long, String) parameter #1:
+    Missing nullability on parameter `name` in method `HeaderItem`
+MissingNullability: androidx.leanback.widget.HeaderItem#getContentDescription():
+    Missing nullability on method `getContentDescription` return
+MissingNullability: androidx.leanback.widget.HeaderItem#getDescription():
+    Missing nullability on method `getDescription` return
+MissingNullability: androidx.leanback.widget.HeaderItem#getName():
+    Missing nullability on method `getName` return
+MissingNullability: androidx.leanback.widget.HeaderItem#setContentDescription(CharSequence) parameter #0:
+    Missing nullability on parameter `contentDescription` in method `setContentDescription`
+MissingNullability: androidx.leanback.widget.HeaderItem#setDescription(CharSequence) parameter #0:
+    Missing nullability on parameter `description` in method `setDescription`
+MissingNullability: androidx.leanback.widget.HorizontalGridView#HorizontalGridView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `HorizontalGridView`
+MissingNullability: androidx.leanback.widget.HorizontalGridView#HorizontalGridView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `HorizontalGridView`
+MissingNullability: androidx.leanback.widget.HorizontalGridView#HorizontalGridView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `HorizontalGridView`
+MissingNullability: androidx.leanback.widget.HorizontalGridView#HorizontalGridView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `HorizontalGridView`
+MissingNullability: androidx.leanback.widget.HorizontalGridView#HorizontalGridView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `HorizontalGridView`
+MissingNullability: androidx.leanback.widget.HorizontalGridView#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
+MissingNullability: androidx.leanback.widget.HorizontalGridView#initAttributes(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `initAttributes`
+MissingNullability: androidx.leanback.widget.HorizontalGridView#initAttributes(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `initAttributes`
+MissingNullability: androidx.leanback.widget.HorizontalHoverCardSwitcher#insertView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `insertView`
+MissingNullability: androidx.leanback.widget.HorizontalHoverCardSwitcher#onViewSelected(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onViewSelected`
+MissingNullability: androidx.leanback.widget.HorizontalHoverCardSwitcher#select(androidx.leanback.widget.HorizontalGridView, android.view.View, Object) parameter #0:
+    Missing nullability on parameter `gridView` in method `select`
+MissingNullability: androidx.leanback.widget.HorizontalHoverCardSwitcher#select(androidx.leanback.widget.HorizontalGridView, android.view.View, Object) parameter #1:
+    Missing nullability on parameter `childView` in method `select`
+MissingNullability: androidx.leanback.widget.HorizontalHoverCardSwitcher#select(androidx.leanback.widget.HorizontalGridView, android.view.View, Object) parameter #2:
+    Missing nullability on parameter `object` in method `select`
+MissingNullability: androidx.leanback.widget.ImageCardView#ImageCardView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `ImageCardView`
+MissingNullability: androidx.leanback.widget.ImageCardView#ImageCardView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `ImageCardView`
+MissingNullability: androidx.leanback.widget.ImageCardView#ImageCardView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `ImageCardView`
+MissingNullability: androidx.leanback.widget.ImageCardView#ImageCardView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `ImageCardView`
+MissingNullability: androidx.leanback.widget.ImageCardView#ImageCardView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `ImageCardView`
+MissingNullability: androidx.leanback.widget.ImageCardView#ImageCardView(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `ImageCardView`
+MissingNullability: androidx.leanback.widget.ImageCardView#getBadgeImage():
+    Missing nullability on method `getBadgeImage` return
+MissingNullability: androidx.leanback.widget.ImageCardView#getContentText():
+    Missing nullability on method `getContentText` return
+MissingNullability: androidx.leanback.widget.ImageCardView#getInfoAreaBackground():
+    Missing nullability on method `getInfoAreaBackground` return
+MissingNullability: androidx.leanback.widget.ImageCardView#getMainImage():
+    Missing nullability on method `getMainImage` return
+MissingNullability: androidx.leanback.widget.ImageCardView#getMainImageView():
+    Missing nullability on method `getMainImageView` return
+MissingNullability: androidx.leanback.widget.ImageCardView#getTitleText():
+    Missing nullability on method `getTitleText` return
+MissingNullability: androidx.leanback.widget.ImageCardView#setBadgeImage(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setBadgeImage`
+MissingNullability: androidx.leanback.widget.ImageCardView#setContentText(CharSequence) parameter #0:
+    Missing nullability on parameter `text` in method `setContentText`
+MissingNullability: androidx.leanback.widget.ImageCardView#setInfoAreaBackground(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setInfoAreaBackground`
+MissingNullability: androidx.leanback.widget.ImageCardView#setMainImage(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setMainImage`
+MissingNullability: androidx.leanback.widget.ImageCardView#setMainImage(android.graphics.drawable.Drawable, boolean) parameter #0:
+    Missing nullability on parameter `drawable` in method `setMainImage`
+MissingNullability: androidx.leanback.widget.ImageCardView#setMainImageScaleType(android.widget.ImageView.ScaleType) parameter #0:
+    Missing nullability on parameter `scaleType` in method `setMainImageScaleType`
+MissingNullability: androidx.leanback.widget.ImageCardView#setTitleText(CharSequence) parameter #0:
+    Missing nullability on parameter `text` in method `setTitleText`
+MissingNullability: androidx.leanback.widget.ImeKeyMonitor#setImeKeyListener(androidx.leanback.widget.ImeKeyMonitor.ImeKeyListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setImeKeyListener`
+MissingNullability: androidx.leanback.widget.ImeKeyMonitor.ImeKeyListener#onKeyPreIme(android.widget.EditText, int, android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `editText` in method `onKeyPreIme`
+MissingNullability: androidx.leanback.widget.ImeKeyMonitor.ImeKeyListener#onKeyPreIme(android.widget.EditText, int, android.view.KeyEvent) parameter #2:
+    Missing nullability on parameter `event` in method `onKeyPreIme`
+MissingNullability: androidx.leanback.widget.ItemAlignmentFacet#getAlignmentDefs():
+    Missing nullability on method `getAlignmentDefs` return
+MissingNullability: androidx.leanback.widget.ItemAlignmentFacet#setAlignmentDefs(androidx.leanback.widget.ItemAlignmentFacet.ItemAlignmentDef[]) parameter #0:
+    Missing nullability on parameter `defs` in method `setAlignmentDefs`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#ItemBridgeAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `ItemBridgeAdapter`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#ItemBridgeAdapter(androidx.leanback.widget.ObjectAdapter, androidx.leanback.widget.PresenterSelector) parameter #0:
+    Missing nullability on parameter `adapter` in method `ItemBridgeAdapter`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#ItemBridgeAdapter(androidx.leanback.widget.ObjectAdapter, androidx.leanback.widget.PresenterSelector) parameter #1:
+    Missing nullability on parameter `presenterSelector` in method `ItemBridgeAdapter`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#getFacetProvider(int):
+    Missing nullability on method `getFacetProvider` return
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#getPresenterMapper():
+    Missing nullability on method `getPresenterMapper` return
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#getWrapper():
+    Missing nullability on method `getWrapper` return
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#onAddPresenter(androidx.leanback.widget.Presenter, int) parameter #0:
+    Missing nullability on parameter `presenter` in method `onAddPresenter`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#onAttachedToWindow(androidx.leanback.widget.ItemBridgeAdapter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onAttachedToWindow`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#onBind(androidx.leanback.widget.ItemBridgeAdapter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onBind`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#onBindViewHolder(androidx.recyclerview.widget.RecyclerView.ViewHolder, int) parameter #0:
+    Missing nullability on parameter `holder` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#onBindViewHolder(androidx.recyclerview.widget.RecyclerView.ViewHolder, int, java.util.List) parameter #0:
+    Missing nullability on parameter `holder` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#onBindViewHolder(androidx.recyclerview.widget.RecyclerView.ViewHolder, int, java.util.List) parameter #2:
+    Missing nullability on parameter `payloads` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#onCreate(androidx.leanback.widget.ItemBridgeAdapter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onCreate`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#onCreateViewHolder(android.view.ViewGroup, int):
+    Missing nullability on method `onCreateViewHolder` return
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#onCreateViewHolder(android.view.ViewGroup, int) parameter #0:
+    Missing nullability on parameter `parent` in method `onCreateViewHolder`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#onDetachedFromWindow(androidx.leanback.widget.ItemBridgeAdapter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onDetachedFromWindow`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#onFailedToRecycleView(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onFailedToRecycleView`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#onUnbind(androidx.leanback.widget.ItemBridgeAdapter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onUnbind`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#onViewAttachedToWindow(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onViewAttachedToWindow`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#onViewDetachedFromWindow(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onViewDetachedFromWindow`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#onViewRecycled(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onViewRecycled`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#setAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setAdapter`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#setAdapterListener(androidx.leanback.widget.ItemBridgeAdapter.AdapterListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setAdapterListener`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#setPresenter(androidx.leanback.widget.PresenterSelector) parameter #0:
+    Missing nullability on parameter `presenterSelector` in method `setPresenter`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#setPresenterMapper(java.util.ArrayList<androidx.leanback.widget.Presenter>) parameter #0:
+    Missing nullability on parameter `presenters` in method `setPresenterMapper`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter#setWrapper(androidx.leanback.widget.ItemBridgeAdapter.Wrapper) parameter #0:
+    Missing nullability on parameter `wrapper` in method `setWrapper`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.AdapterListener#onAddPresenter(androidx.leanback.widget.Presenter, int) parameter #0:
+    Missing nullability on parameter `presenter` in method `onAddPresenter`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.AdapterListener#onAttachedToWindow(androidx.leanback.widget.ItemBridgeAdapter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onAttachedToWindow`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.AdapterListener#onBind(androidx.leanback.widget.ItemBridgeAdapter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onBind`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.AdapterListener#onBind(androidx.leanback.widget.ItemBridgeAdapter.ViewHolder, java.util.List) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onBind`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.AdapterListener#onBind(androidx.leanback.widget.ItemBridgeAdapter.ViewHolder, java.util.List) parameter #1:
+    Missing nullability on parameter `payloads` in method `onBind`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.AdapterListener#onCreate(androidx.leanback.widget.ItemBridgeAdapter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onCreate`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.AdapterListener#onDetachedFromWindow(androidx.leanback.widget.ItemBridgeAdapter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onDetachedFromWindow`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.AdapterListener#onUnbind(androidx.leanback.widget.ItemBridgeAdapter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onUnbind`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.ViewHolder#getExtraObject():
+    Missing nullability on method `getExtraObject` return
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.ViewHolder#getFacet(Class<?>):
+    Missing nullability on method `getFacet` return
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.ViewHolder#getFacet(Class<?>) parameter #0:
+    Missing nullability on parameter `facetClass` in method `getFacet`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.ViewHolder#getItem():
+    Missing nullability on method `getItem` return
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.ViewHolder#getPresenter():
+    Missing nullability on method `getPresenter` return
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.ViewHolder#getViewHolder():
+    Missing nullability on method `getViewHolder` return
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.ViewHolder#setExtraObject(Object) parameter #0:
+    Missing nullability on parameter `object` in method `setExtraObject`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.Wrapper#createWrapper(android.view.View):
+    Missing nullability on method `createWrapper` return
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.Wrapper#createWrapper(android.view.View) parameter #0:
+    Missing nullability on parameter `root` in method `createWrapper`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.Wrapper#wrap(android.view.View, android.view.View) parameter #0:
+    Missing nullability on parameter `wrapper` in method `wrap`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapter.Wrapper#wrap(android.view.View, android.view.View) parameter #1:
+    Missing nullability on parameter `wrapped` in method `wrap`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapterShadowOverlayWrapper#ItemBridgeAdapterShadowOverlayWrapper(androidx.leanback.widget.ShadowOverlayHelper) parameter #0:
+    Missing nullability on parameter `helper` in method `ItemBridgeAdapterShadowOverlayWrapper`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapterShadowOverlayWrapper#createWrapper(android.view.View):
+    Missing nullability on method `createWrapper` return
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapterShadowOverlayWrapper#createWrapper(android.view.View) parameter #0:
+    Missing nullability on parameter `root` in method `createWrapper`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapterShadowOverlayWrapper#wrap(android.view.View, android.view.View) parameter #0:
+    Missing nullability on parameter `wrapper` in method `wrap`
+MissingNullability: androidx.leanback.widget.ItemBridgeAdapterShadowOverlayWrapper#wrap(android.view.View, android.view.View) parameter #1:
+    Missing nullability on parameter `wrapped` in method `wrap`
+MissingNullability: androidx.leanback.widget.ListRow#ListRow(androidx.leanback.widget.HeaderItem, androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `header` in method `ListRow`
+MissingNullability: androidx.leanback.widget.ListRow#ListRow(androidx.leanback.widget.HeaderItem, androidx.leanback.widget.ObjectAdapter) parameter #1:
+    Missing nullability on parameter `adapter` in method `ListRow`
+MissingNullability: androidx.leanback.widget.ListRow#ListRow(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `ListRow`
+MissingNullability: androidx.leanback.widget.ListRow#ListRow(long, androidx.leanback.widget.HeaderItem, androidx.leanback.widget.ObjectAdapter) parameter #1:
+    Missing nullability on parameter `header` in method `ListRow`
+MissingNullability: androidx.leanback.widget.ListRow#ListRow(long, androidx.leanback.widget.HeaderItem, androidx.leanback.widget.ObjectAdapter) parameter #2:
+    Missing nullability on parameter `adapter` in method `ListRow`
+MissingNullability: androidx.leanback.widget.ListRow#getAdapter():
+    Missing nullability on method `getAdapter` return
+MissingNullability: androidx.leanback.widget.ListRow#getContentDescription():
+    Missing nullability on method `getContentDescription` return
+MissingNullability: androidx.leanback.widget.ListRow#setContentDescription(CharSequence) parameter #0:
+    Missing nullability on parameter `contentDescription` in method `setContentDescription`
+MissingNullability: androidx.leanback.widget.ListRowHoverCardView#ListRowHoverCardView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `ListRowHoverCardView`
+MissingNullability: androidx.leanback.widget.ListRowHoverCardView#ListRowHoverCardView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `ListRowHoverCardView`
+MissingNullability: androidx.leanback.widget.ListRowHoverCardView#ListRowHoverCardView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `ListRowHoverCardView`
+MissingNullability: androidx.leanback.widget.ListRowHoverCardView#ListRowHoverCardView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `ListRowHoverCardView`
+MissingNullability: androidx.leanback.widget.ListRowHoverCardView#ListRowHoverCardView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `ListRowHoverCardView`
+MissingNullability: androidx.leanback.widget.ListRowHoverCardView#getDescription():
+    Missing nullability on method `getDescription` return
+MissingNullability: androidx.leanback.widget.ListRowHoverCardView#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.leanback.widget.ListRowHoverCardView#setDescription(CharSequence) parameter #0:
+    Missing nullability on parameter `text` in method `setDescription`
+MissingNullability: androidx.leanback.widget.ListRowHoverCardView#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `text` in method `setTitle`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#applySelectLevelToChild(androidx.leanback.widget.ListRowPresenter.ViewHolder, android.view.View) parameter #0:
+    Missing nullability on parameter `rowViewHolder` in method `applySelectLevelToChild`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#applySelectLevelToChild(androidx.leanback.widget.ListRowPresenter.ViewHolder, android.view.View) parameter #1:
+    Missing nullability on parameter `childView` in method `applySelectLevelToChild`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#createRowViewHolder(android.view.ViewGroup):
+    Missing nullability on method `createRowViewHolder` return
+MissingNullability: androidx.leanback.widget.ListRowPresenter#createRowViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `createRowViewHolder`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#createShadowOverlayOptions():
+    Missing nullability on method `createShadowOverlayOptions` return
+MissingNullability: androidx.leanback.widget.ListRowPresenter#dispatchItemSelectedListener(androidx.leanback.widget.RowPresenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `holder` in method `dispatchItemSelectedListener`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#freeze(androidx.leanback.widget.RowPresenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `holder` in method `freeze`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#getHoverCardPresenterSelector():
+    Missing nullability on method `getHoverCardPresenterSelector` return
+MissingNullability: androidx.leanback.widget.ListRowPresenter#getRecycledPoolSize(androidx.leanback.widget.Presenter) parameter #0:
+    Missing nullability on parameter `presenter` in method `getRecycledPoolSize`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#initializeRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `initializeRowViewHolder`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#isUsingOutlineClipping(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `isUsingOutlineClipping`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#isUsingZOrder(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `isUsingZOrder`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#onBindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `holder` in method `onBindRowViewHolder`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#onBindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindRowViewHolder`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#onRowViewExpanded(androidx.leanback.widget.RowPresenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `holder` in method `onRowViewExpanded`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#onRowViewSelected(androidx.leanback.widget.RowPresenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `holder` in method `onRowViewSelected`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#onSelectLevelChanged(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onSelectLevelChanged`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#onUnbindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onUnbindRowViewHolder`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#setEntranceTransitionState(androidx.leanback.widget.RowPresenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `holder` in method `setEntranceTransitionState`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#setHoverCardPresenterSelector(androidx.leanback.widget.PresenterSelector) parameter #0:
+    Missing nullability on parameter `selector` in method `setHoverCardPresenterSelector`
+MissingNullability: androidx.leanback.widget.ListRowPresenter#setRecycledPoolSize(androidx.leanback.widget.Presenter, int) parameter #0:
+    Missing nullability on parameter `presenter` in method `setRecycledPoolSize`
+MissingNullability: androidx.leanback.widget.ListRowPresenter.SelectItemViewHolderTask#getItemTask():
+    Missing nullability on method `getItemTask` return
+MissingNullability: androidx.leanback.widget.ListRowPresenter.SelectItemViewHolderTask#run(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `run`
+MissingNullability: androidx.leanback.widget.ListRowPresenter.SelectItemViewHolderTask#setItemTask(androidx.leanback.widget.Presenter.ViewHolderTask) parameter #0:
+    Missing nullability on parameter `itemTask` in method `setItemTask`
+MissingNullability: androidx.leanback.widget.ListRowPresenter.ViewHolder#ViewHolder(android.view.View, androidx.leanback.widget.HorizontalGridView, androidx.leanback.widget.ListRowPresenter) parameter #0:
+    Missing nullability on parameter `rootView` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.ListRowPresenter.ViewHolder#ViewHolder(android.view.View, androidx.leanback.widget.HorizontalGridView, androidx.leanback.widget.ListRowPresenter) parameter #1:
+    Missing nullability on parameter `gridView` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.ListRowPresenter.ViewHolder#ViewHolder(android.view.View, androidx.leanback.widget.HorizontalGridView, androidx.leanback.widget.ListRowPresenter) parameter #2:
+    Missing nullability on parameter `p` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.ListRowPresenter.ViewHolder#getBridgeAdapter():
+    Missing nullability on method `getBridgeAdapter` return
+MissingNullability: androidx.leanback.widget.ListRowPresenter.ViewHolder#getGridView():
+    Missing nullability on method `getGridView` return
+MissingNullability: androidx.leanback.widget.ListRowPresenter.ViewHolder#getItemViewHolder(int):
+    Missing nullability on method `getItemViewHolder` return
+MissingNullability: androidx.leanback.widget.ListRowPresenter.ViewHolder#getListRowPresenter():
+    Missing nullability on method `getListRowPresenter` return
+MissingNullability: androidx.leanback.widget.ListRowPresenter.ViewHolder#getSelectedItem():
+    Missing nullability on method `getSelectedItem` return
+MissingNullability: androidx.leanback.widget.ListRowPresenter.ViewHolder#getSelectedItemViewHolder():
+    Missing nullability on method `getSelectedItemViewHolder` return
+MissingNullability: androidx.leanback.widget.ListRowView#ListRowView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `ListRowView`
+MissingNullability: androidx.leanback.widget.ListRowView#ListRowView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `ListRowView`
+MissingNullability: androidx.leanback.widget.ListRowView#ListRowView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `ListRowView`
+MissingNullability: androidx.leanback.widget.ListRowView#ListRowView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `ListRowView`
+MissingNullability: androidx.leanback.widget.ListRowView#ListRowView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `ListRowView`
+MissingNullability: androidx.leanback.widget.ListRowView#getGridView():
+    Missing nullability on method `getGridView` return
+MissingNullability: androidx.leanback.widget.MultiActionsProvider#getActions():
+    Missing nullability on method `getActions` return
+MissingNullability: androidx.leanback.widget.MultiActionsProvider.MultiAction#getCurrentDrawable():
+    Missing nullability on method `getCurrentDrawable` return
+MissingNullability: androidx.leanback.widget.MultiActionsProvider.MultiAction#getDrawables():
+    Missing nullability on method `getDrawables` return
+MissingNullability: androidx.leanback.widget.MultiActionsProvider.MultiAction#setDrawables(android.graphics.drawable.Drawable[]) parameter #0:
+    Missing nullability on parameter `drawables` in method `setDrawables`
+MissingNullability: androidx.leanback.widget.ObjectAdapter#ObjectAdapter(androidx.leanback.widget.Presenter) parameter #0:
+    Missing nullability on parameter `presenter` in method `ObjectAdapter`
+MissingNullability: androidx.leanback.widget.ObjectAdapter#ObjectAdapter(androidx.leanback.widget.PresenterSelector) parameter #0:
+    Missing nullability on parameter `presenterSelector` in method `ObjectAdapter`
+MissingNullability: androidx.leanback.widget.ObjectAdapter#get(int):
+    Missing nullability on method `get` return
+MissingNullability: androidx.leanback.widget.ObjectAdapter#getPresenter(Object):
+    Missing nullability on method `getPresenter` return
+MissingNullability: androidx.leanback.widget.ObjectAdapter#getPresenter(Object) parameter #0:
+    Missing nullability on parameter `item` in method `getPresenter`
+MissingNullability: androidx.leanback.widget.ObjectAdapter#getPresenterSelector():
+    Missing nullability on method `getPresenterSelector` return
+MissingNullability: androidx.leanback.widget.ObjectAdapter#notifyItemRangeChanged(int, int, Object) parameter #2:
+    Missing nullability on parameter `payload` in method `notifyItemRangeChanged`
+MissingNullability: androidx.leanback.widget.ObjectAdapter#registerObserver(androidx.leanback.widget.ObjectAdapter.DataObserver) parameter #0:
+    Missing nullability on parameter `observer` in method `registerObserver`
+MissingNullability: androidx.leanback.widget.ObjectAdapter#setPresenterSelector(androidx.leanback.widget.PresenterSelector) parameter #0:
+    Missing nullability on parameter `presenterSelector` in method `setPresenterSelector`
+MissingNullability: androidx.leanback.widget.ObjectAdapter#unregisterObserver(androidx.leanback.widget.ObjectAdapter.DataObserver) parameter #0:
+    Missing nullability on parameter `observer` in method `unregisterObserver`
+MissingNullability: androidx.leanback.widget.ObjectAdapter.DataObserver#onItemRangeChanged(int, int, Object) parameter #2:
+    Missing nullability on parameter `payload` in method `onItemRangeChanged`
+MissingNullability: androidx.leanback.widget.OnActionClickedListener#onActionClicked(androidx.leanback.widget.Action) parameter #0:
+    Missing nullability on parameter `action` in method `onActionClicked`
+MissingNullability: androidx.leanback.widget.OnChildLaidOutListener#onChildLaidOut(android.view.ViewGroup, android.view.View, int, long) parameter #0:
+    Missing nullability on parameter `parent` in method `onChildLaidOut`
+MissingNullability: androidx.leanback.widget.OnChildLaidOutListener#onChildLaidOut(android.view.ViewGroup, android.view.View, int, long) parameter #1:
+    Missing nullability on parameter `view` in method `onChildLaidOut`
+MissingNullability: androidx.leanback.widget.OnChildSelectedListener#onChildSelected(android.view.ViewGroup, android.view.View, int, long) parameter #0:
+    Missing nullability on parameter `parent` in method `onChildSelected`
+MissingNullability: androidx.leanback.widget.OnChildSelectedListener#onChildSelected(android.view.ViewGroup, android.view.View, int, long) parameter #1:
+    Missing nullability on parameter `view` in method `onChildSelected`
+MissingNullability: androidx.leanback.widget.OnChildViewHolderSelectedListener#onChildViewHolderSelected(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, int) parameter #0:
+    Missing nullability on parameter `parent` in method `onChildViewHolderSelected`
+MissingNullability: androidx.leanback.widget.OnChildViewHolderSelectedListener#onChildViewHolderSelected(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, int) parameter #1:
+    Missing nullability on parameter `child` in method `onChildViewHolderSelected`
+MissingNullability: androidx.leanback.widget.OnChildViewHolderSelectedListener#onChildViewHolderSelectedAndPositioned(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, int) parameter #0:
+    Missing nullability on parameter `parent` in method `onChildViewHolderSelectedAndPositioned`
+MissingNullability: androidx.leanback.widget.OnChildViewHolderSelectedListener#onChildViewHolderSelectedAndPositioned(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, int) parameter #1:
+    Missing nullability on parameter `child` in method `onChildViewHolderSelectedAndPositioned`
+MissingNullability: androidx.leanback.widget.PageRow#PageRow(androidx.leanback.widget.HeaderItem) parameter #0:
+    Missing nullability on parameter `headerItem` in method `PageRow`
+MissingNullability: androidx.leanback.widget.Parallax#addEffect(androidx.leanback.widget.Parallax.PropertyMarkerValue...):
+    Missing nullability on method `addEffect` return
+MissingNullability: androidx.leanback.widget.Parallax#addEffect(androidx.leanback.widget.Parallax.PropertyMarkerValue...) parameter #0:
+    Missing nullability on parameter `ranges` in method `addEffect`
+MissingNullability: androidx.leanback.widget.Parallax#addProperty(String) parameter #0:
+    Missing nullability on parameter `name` in method `addProperty`
+MissingNullability: androidx.leanback.widget.Parallax#createProperty(String, int) parameter #0:
+    Missing nullability on parameter `name` in method `createProperty`
+MissingNullability: androidx.leanback.widget.Parallax#getEffects():
+    Missing nullability on method `getEffects` return
+MissingNullability: androidx.leanback.widget.Parallax#getProperties():
+    Missing nullability on method `getProperties` return
+MissingNullability: androidx.leanback.widget.Parallax#removeEffect(androidx.leanback.widget.ParallaxEffect) parameter #0:
+    Missing nullability on parameter `effect` in method `removeEffect`
+MissingNullability: androidx.leanback.widget.Parallax.FloatProperty#FloatProperty(String, int) parameter #0:
+    Missing nullability on parameter `name` in method `FloatProperty`
+MissingNullability: androidx.leanback.widget.Parallax.FloatProperty#at(float, float):
+    Missing nullability on method `at` return
+MissingNullability: androidx.leanback.widget.Parallax.FloatProperty#atAbsolute(float):
+    Missing nullability on method `atAbsolute` return
+MissingNullability: androidx.leanback.widget.Parallax.FloatProperty#atFraction(float):
+    Missing nullability on method `atFraction` return
+MissingNullability: androidx.leanback.widget.Parallax.FloatProperty#atMax():
+    Missing nullability on method `atMax` return
+MissingNullability: androidx.leanback.widget.Parallax.FloatProperty#atMin():
+    Missing nullability on method `atMin` return
+MissingNullability: androidx.leanback.widget.Parallax.FloatProperty#get(androidx.leanback.widget.Parallax):
+    Missing nullability on method `get` return
+MissingNullability: androidx.leanback.widget.Parallax.FloatProperty#get(androidx.leanback.widget.Parallax) parameter #0:
+    Missing nullability on parameter `object` in method `get`
+MissingNullability: androidx.leanback.widget.Parallax.FloatProperty#getValue(androidx.leanback.widget.Parallax) parameter #0:
+    Missing nullability on parameter `object` in method `getValue`
+MissingNullability: androidx.leanback.widget.Parallax.FloatProperty#set(androidx.leanback.widget.Parallax, Float) parameter #0:
+    Missing nullability on parameter `object` in method `set`
+MissingNullability: androidx.leanback.widget.Parallax.FloatProperty#set(androidx.leanback.widget.Parallax, Float) parameter #1:
+    Missing nullability on parameter `value` in method `set`
+MissingNullability: androidx.leanback.widget.Parallax.FloatProperty#setValue(androidx.leanback.widget.Parallax, float) parameter #0:
+    Missing nullability on parameter `object` in method `setValue`
+MissingNullability: androidx.leanback.widget.Parallax.IntProperty#IntProperty(String, int) parameter #0:
+    Missing nullability on parameter `name` in method `IntProperty`
+MissingNullability: androidx.leanback.widget.Parallax.IntProperty#at(int, float):
+    Missing nullability on method `at` return
+MissingNullability: androidx.leanback.widget.Parallax.IntProperty#atAbsolute(int):
+    Missing nullability on method `atAbsolute` return
+MissingNullability: androidx.leanback.widget.Parallax.IntProperty#atFraction(float):
+    Missing nullability on method `atFraction` return
+MissingNullability: androidx.leanback.widget.Parallax.IntProperty#atMax():
+    Missing nullability on method `atMax` return
+MissingNullability: androidx.leanback.widget.Parallax.IntProperty#atMin():
+    Missing nullability on method `atMin` return
+MissingNullability: androidx.leanback.widget.Parallax.IntProperty#get(androidx.leanback.widget.Parallax):
+    Missing nullability on method `get` return
+MissingNullability: androidx.leanback.widget.Parallax.IntProperty#get(androidx.leanback.widget.Parallax) parameter #0:
+    Missing nullability on parameter `object` in method `get`
+MissingNullability: androidx.leanback.widget.Parallax.IntProperty#getValue(androidx.leanback.widget.Parallax) parameter #0:
+    Missing nullability on parameter `object` in method `getValue`
+MissingNullability: androidx.leanback.widget.Parallax.IntProperty#set(androidx.leanback.widget.Parallax, Integer) parameter #0:
+    Missing nullability on parameter `object` in method `set`
+MissingNullability: androidx.leanback.widget.Parallax.IntProperty#set(androidx.leanback.widget.Parallax, Integer) parameter #1:
+    Missing nullability on parameter `value` in method `set`
+MissingNullability: androidx.leanback.widget.Parallax.IntProperty#setValue(androidx.leanback.widget.Parallax, int) parameter #0:
+    Missing nullability on parameter `object` in method `setValue`
+MissingNullability: androidx.leanback.widget.ParallaxEffect#addTarget(androidx.leanback.widget.ParallaxTarget) parameter #0:
+    Missing nullability on parameter `target` in method `addTarget`
+MissingNullability: androidx.leanback.widget.ParallaxEffect#getPropertyRanges():
+    Missing nullability on method `getPropertyRanges` return
+MissingNullability: androidx.leanback.widget.ParallaxEffect#getTargets():
+    Missing nullability on method `getTargets` return
+MissingNullability: androidx.leanback.widget.ParallaxEffect#performMapping(androidx.leanback.widget.Parallax) parameter #0:
+    Missing nullability on parameter `source` in method `performMapping`
+MissingNullability: androidx.leanback.widget.ParallaxEffect#removeTarget(androidx.leanback.widget.ParallaxTarget) parameter #0:
+    Missing nullability on parameter `target` in method `removeTarget`
+MissingNullability: androidx.leanback.widget.ParallaxEffect#setPropertyRanges(androidx.leanback.widget.Parallax.PropertyMarkerValue...) parameter #0:
+    Missing nullability on parameter `markerValues` in method `setPropertyRanges`
+MissingNullability: androidx.leanback.widget.ParallaxEffect#target(Object, android.animation.PropertyValuesHolder):
+    Missing nullability on method `target` return
+MissingNullability: androidx.leanback.widget.ParallaxEffect#target(Object, android.animation.PropertyValuesHolder) parameter #0:
+    Missing nullability on parameter `targetObject` in method `target`
+MissingNullability: androidx.leanback.widget.ParallaxEffect#target(Object, android.animation.PropertyValuesHolder) parameter #1:
+    Missing nullability on parameter `values` in method `target`
+MissingNullability: androidx.leanback.widget.ParallaxEffect#target(T, android.util.Property<T,V>):
+    Missing nullability on method `target` return
+MissingNullability: androidx.leanback.widget.ParallaxEffect#target(T, android.util.Property<T,V>) parameter #1:
+    Missing nullability on parameter `targetProperty` in method `target`
+MissingNullability: androidx.leanback.widget.ParallaxEffect#target(androidx.leanback.widget.ParallaxTarget):
+    Missing nullability on method `target` return
+MissingNullability: androidx.leanback.widget.ParallaxEffect#target(androidx.leanback.widget.ParallaxTarget) parameter #0:
+    Missing nullability on parameter `target` in method `target`
+MissingNullability: androidx.leanback.widget.ParallaxTarget#directUpdate(Number) parameter #0:
+    Missing nullability on parameter `value` in method `directUpdate`
+MissingNullability: androidx.leanback.widget.ParallaxTarget.DirectPropertyTarget#DirectPropertyTarget(Object, android.util.Property<T,V>) parameter #0:
+    Missing nullability on parameter `targetObject` in method `DirectPropertyTarget`
+MissingNullability: androidx.leanback.widget.ParallaxTarget.DirectPropertyTarget#DirectPropertyTarget(Object, android.util.Property<T,V>) parameter #1:
+    Missing nullability on parameter `property` in method `DirectPropertyTarget`
+MissingNullability: androidx.leanback.widget.ParallaxTarget.DirectPropertyTarget#directUpdate(Number) parameter #0:
+    Missing nullability on parameter `value` in method `directUpdate`
+MissingNullability: androidx.leanback.widget.ParallaxTarget.PropertyValuesHolderTarget#PropertyValuesHolderTarget(Object, android.animation.PropertyValuesHolder) parameter #0:
+    Missing nullability on parameter `targetObject` in method `PropertyValuesHolderTarget`
+MissingNullability: androidx.leanback.widget.ParallaxTarget.PropertyValuesHolderTarget#PropertyValuesHolderTarget(Object, android.animation.PropertyValuesHolder) parameter #1:
+    Missing nullability on parameter `values` in method `PropertyValuesHolderTarget`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow#PlaybackControlsRow(Object) parameter #0:
+    Missing nullability on parameter `item` in method `PlaybackControlsRow`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow#getActionForKeyCode(androidx.leanback.widget.ObjectAdapter, int):
+    Missing nullability on method `getActionForKeyCode` return
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow#getActionForKeyCode(androidx.leanback.widget.ObjectAdapter, int) parameter #0:
+    Missing nullability on parameter `adapter` in method `getActionForKeyCode`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow#getActionForKeyCode(int):
+    Missing nullability on method `getActionForKeyCode` return
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow#getImageDrawable():
+    Missing nullability on method `getImageDrawable` return
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow#getItem():
+    Missing nullability on method `getItem` return
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow#getPrimaryActionsAdapter():
+    Missing nullability on method `getPrimaryActionsAdapter` return
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow#getSecondaryActionsAdapter():
+    Missing nullability on method `getSecondaryActionsAdapter` return
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow#setImageBitmap(android.content.Context, android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `context` in method `setImageBitmap`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow#setImageBitmap(android.content.Context, android.graphics.Bitmap) parameter #1:
+    Missing nullability on parameter `bm` in method `setImageBitmap`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow#setImageDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setImageDrawable`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow#setOnPlaybackProgressChangedListener(androidx.leanback.widget.PlaybackControlsRow.OnPlaybackProgressCallback) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnPlaybackProgressChangedListener`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow#setPrimaryActionsAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setPrimaryActionsAdapter`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow#setSecondaryActionsAdapter(androidx.leanback.widget.ObjectAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setSecondaryActionsAdapter`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.ClosedCaptioningAction#ClosedCaptioningAction(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `ClosedCaptioningAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.ClosedCaptioningAction#ClosedCaptioningAction(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `ClosedCaptioningAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.FastForwardAction#FastForwardAction(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `FastForwardAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.FastForwardAction#FastForwardAction(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `FastForwardAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.HighQualityAction#HighQualityAction(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `HighQualityAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.HighQualityAction#HighQualityAction(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `HighQualityAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.MoreActions#MoreActions(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `MoreActions`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.MultiAction#getDrawable(int):
+    Missing nullability on method `getDrawable` return
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.MultiAction#getLabel(int):
+    Missing nullability on method `getLabel` return
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.MultiAction#getSecondaryLabel(int):
+    Missing nullability on method `getSecondaryLabel` return
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.MultiAction#setDrawables(android.graphics.drawable.Drawable[]) parameter #0:
+    Missing nullability on parameter `drawables` in method `setDrawables`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.MultiAction#setLabels(String[]) parameter #0:
+    Missing nullability on parameter `labels` in method `setLabels`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.MultiAction#setSecondaryLabels(String[]) parameter #0:
+    Missing nullability on parameter `labels` in method `setSecondaryLabels`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.OnPlaybackProgressCallback#onBufferedPositionChanged(androidx.leanback.widget.PlaybackControlsRow, long) parameter #0:
+    Missing nullability on parameter `row` in method `onBufferedPositionChanged`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.OnPlaybackProgressCallback#onCurrentPositionChanged(androidx.leanback.widget.PlaybackControlsRow, long) parameter #0:
+    Missing nullability on parameter `row` in method `onCurrentPositionChanged`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.OnPlaybackProgressCallback#onDurationChanged(androidx.leanback.widget.PlaybackControlsRow, long) parameter #0:
+    Missing nullability on parameter `row` in method `onDurationChanged`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.PictureInPictureAction#PictureInPictureAction(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `PictureInPictureAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.PlayPauseAction#PlayPauseAction(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `PlayPauseAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.RepeatAction#RepeatAction(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `RepeatAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.RepeatAction#RepeatAction(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `RepeatAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.RepeatAction#RepeatAction(android.content.Context, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `RepeatAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.RewindAction#RewindAction(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `RewindAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.RewindAction#RewindAction(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `RewindAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.ShuffleAction#ShuffleAction(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `ShuffleAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.ShuffleAction#ShuffleAction(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `ShuffleAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.SkipNextAction#SkipNextAction(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `SkipNextAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.SkipPreviousAction#SkipPreviousAction(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `SkipPreviousAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.ThumbsAction#ThumbsAction(int, android.content.Context, int, int) parameter #1:
+    Missing nullability on parameter `context` in method `ThumbsAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.ThumbsDownAction#ThumbsDownAction(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `ThumbsDownAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRow.ThumbsUpAction#ThumbsUpAction(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `ThumbsUpAction`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRowPresenter#PlaybackControlsRowPresenter(androidx.leanback.widget.Presenter) parameter #0:
+    Missing nullability on parameter `descriptionPresenter` in method `PlaybackControlsRowPresenter`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRowPresenter#createRowViewHolder(android.view.ViewGroup):
+    Missing nullability on method `createRowViewHolder` return
+MissingNullability: androidx.leanback.widget.PlaybackControlsRowPresenter#createRowViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `createRowViewHolder`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRowPresenter#getOnActionClickedListener():
+    Missing nullability on method `getOnActionClickedListener` return
+MissingNullability: androidx.leanback.widget.PlaybackControlsRowPresenter#onBindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `holder` in method `onBindRowViewHolder`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRowPresenter#onBindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindRowViewHolder`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRowPresenter#onReappear(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `rowViewHolder` in method `onReappear`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRowPresenter#onRowViewAttachedToWindow(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onRowViewAttachedToWindow`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRowPresenter#onRowViewDetachedFromWindow(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onRowViewDetachedFromWindow`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRowPresenter#onRowViewSelected(androidx.leanback.widget.RowPresenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `vh` in method `onRowViewSelected`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRowPresenter#onUnbindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onUnbindRowViewHolder`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRowPresenter#setOnActionClickedListener(androidx.leanback.widget.OnActionClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnActionClickedListener`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRowPresenter#showBottomSpace(androidx.leanback.widget.PlaybackControlsRowPresenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `vh` in method `showBottomSpace`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRowPresenter#showPrimaryActions(androidx.leanback.widget.PlaybackControlsRowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `showPrimaryActions`
+MissingNullability: androidx.leanback.widget.PlaybackControlsRowPresenter.ViewHolder#mDescriptionViewHolder:
+    Missing nullability on field `mDescriptionViewHolder` in class `class androidx.leanback.widget.PlaybackControlsRowPresenter.ViewHolder`
+MissingNullability: androidx.leanback.widget.PlaybackRowPresenter#onReappear(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `rowViewHolder` in method `onReappear`
+MissingNullability: androidx.leanback.widget.PlaybackRowPresenter.ViewHolder#ViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.PlaybackSeekDataProvider#getSeekPositions():
+    Missing nullability on method `getSeekPositions` return
+MissingNullability: androidx.leanback.widget.PlaybackSeekDataProvider#getThumbnail(int, androidx.leanback.widget.PlaybackSeekDataProvider.ResultCallback) parameter #1:
+    Missing nullability on parameter `callback` in method `getThumbnail`
+MissingNullability: androidx.leanback.widget.PlaybackSeekDataProvider.ResultCallback#onThumbnailLoaded(android.graphics.Bitmap, int) parameter #0:
+    Missing nullability on parameter `bitmap` in method `onThumbnailLoaded`
+MissingNullability: androidx.leanback.widget.PlaybackSeekUi#setPlaybackSeekUiClient(androidx.leanback.widget.PlaybackSeekUi.Client) parameter #0:
+    Missing nullability on parameter `client` in method `setPlaybackSeekUiClient`
+MissingNullability: androidx.leanback.widget.PlaybackSeekUi.Client#getPlaybackSeekDataProvider():
+    Missing nullability on method `getPlaybackSeekDataProvider` return
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter#createRowViewHolder(android.view.ViewGroup):
+    Missing nullability on method `createRowViewHolder` return
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter#createRowViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `createRowViewHolder`
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter#getOnActionClickedListener():
+    Missing nullability on method `getOnActionClickedListener` return
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter#onBindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `holder` in method `onBindRowViewHolder`
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter#onBindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindRowViewHolder`
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter#onProgressBarClicked(androidx.leanback.widget.PlaybackTransportRowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onProgressBarClicked`
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter#onReappear(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `rowViewHolder` in method `onReappear`
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter#onRowViewAttachedToWindow(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onRowViewAttachedToWindow`
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter#onRowViewDetachedFromWindow(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onRowViewDetachedFromWindow`
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter#onRowViewSelected(androidx.leanback.widget.RowPresenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `vh` in method `onRowViewSelected`
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter#onUnbindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onUnbindRowViewHolder`
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter#setDescriptionPresenter(androidx.leanback.widget.Presenter) parameter #0:
+    Missing nullability on parameter `descriptionPresenter` in method `setDescriptionPresenter`
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter#setOnActionClickedListener(androidx.leanback.widget.OnActionClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnActionClickedListener`
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter.ViewHolder#ViewHolder(android.view.View, androidx.leanback.widget.Presenter) parameter #0:
+    Missing nullability on parameter `rootView` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter.ViewHolder#ViewHolder(android.view.View, androidx.leanback.widget.Presenter) parameter #1:
+    Missing nullability on parameter `descriptionPresenter` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter.ViewHolder#getCurrentPositionView():
+    Missing nullability on method `getCurrentPositionView` return
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter.ViewHolder#getDescriptionViewHolder():
+    Missing nullability on method `getDescriptionViewHolder` return
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter.ViewHolder#getDurationView():
+    Missing nullability on method `getDurationView` return
+MissingNullability: androidx.leanback.widget.PlaybackTransportRowPresenter.ViewHolder#setPlaybackSeekUiClient(androidx.leanback.widget.PlaybackSeekUi.Client) parameter #0:
+    Missing nullability on parameter `client` in method `setPlaybackSeekUiClient`
+MissingNullability: androidx.leanback.widget.Presenter#cancelAnimationsRecursive(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `cancelAnimationsRecursive`
+MissingNullability: androidx.leanback.widget.Presenter#getFacet(Class<?>):
+    Missing nullability on method `getFacet` return
+MissingNullability: androidx.leanback.widget.Presenter#getFacet(Class<?>) parameter #0:
+    Missing nullability on parameter `facetClass` in method `getFacet`
+MissingNullability: androidx.leanback.widget.Presenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.Presenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.Presenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object, java.util.List<java.lang.Object>) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.Presenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object, java.util.List<java.lang.Object>) parameter #1:
+    Missing nullability on parameter `item` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.Presenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object, java.util.List<java.lang.Object>) parameter #2:
+    Missing nullability on parameter `payloads` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.Presenter#onCreateViewHolder(android.view.ViewGroup):
+    Missing nullability on method `onCreateViewHolder` return
+MissingNullability: androidx.leanback.widget.Presenter#onCreateViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `onCreateViewHolder`
+MissingNullability: androidx.leanback.widget.Presenter#onUnbindViewHolder(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onUnbindViewHolder`
+MissingNullability: androidx.leanback.widget.Presenter#onViewAttachedToWindow(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onViewAttachedToWindow`
+MissingNullability: androidx.leanback.widget.Presenter#onViewDetachedFromWindow(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onViewDetachedFromWindow`
+MissingNullability: androidx.leanback.widget.Presenter#setFacet(Class<?>, Object) parameter #0:
+    Missing nullability on parameter `facetClass` in method `setFacet`
+MissingNullability: androidx.leanback.widget.Presenter#setFacet(Class<?>, Object) parameter #1:
+    Missing nullability on parameter `facetImpl` in method `setFacet`
+MissingNullability: androidx.leanback.widget.Presenter#setOnClickListener(androidx.leanback.widget.Presenter.ViewHolder, android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `holder` in method `setOnClickListener`
+MissingNullability: androidx.leanback.widget.Presenter#setOnClickListener(androidx.leanback.widget.Presenter.ViewHolder, android.view.View.OnClickListener) parameter #1:
+    Missing nullability on parameter `listener` in method `setOnClickListener`
+MissingNullability: androidx.leanback.widget.Presenter.ViewHolder#ViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.Presenter.ViewHolder#getFacet(Class<?>):
+    Missing nullability on method `getFacet` return
+MissingNullability: androidx.leanback.widget.Presenter.ViewHolder#getFacet(Class<?>) parameter #0:
+    Missing nullability on parameter `facetClass` in method `getFacet`
+MissingNullability: androidx.leanback.widget.Presenter.ViewHolder#setFacet(Class<?>, Object) parameter #0:
+    Missing nullability on parameter `facetClass` in method `setFacet`
+MissingNullability: androidx.leanback.widget.Presenter.ViewHolder#setFacet(Class<?>, Object) parameter #1:
+    Missing nullability on parameter `facetImpl` in method `setFacet`
+MissingNullability: androidx.leanback.widget.Presenter.ViewHolder#view:
+    Missing nullability on field `view` in class `class androidx.leanback.widget.Presenter.ViewHolder`
+MissingNullability: androidx.leanback.widget.Presenter.ViewHolderTask#run(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `run`
+MissingNullability: androidx.leanback.widget.PresenterSelector#getPresenter(Object):
+    Missing nullability on method `getPresenter` return
+MissingNullability: androidx.leanback.widget.PresenterSelector#getPresenter(Object) parameter #0:
+    Missing nullability on parameter `item` in method `getPresenter`
+MissingNullability: androidx.leanback.widget.PresenterSelector#getPresenters():
+    Missing nullability on method `getPresenters` return
+MissingNullability: androidx.leanback.widget.PresenterSwitcher#getParentViewGroup():
+    Missing nullability on method `getParentViewGroup` return
+MissingNullability: androidx.leanback.widget.PresenterSwitcher#init(android.view.ViewGroup, androidx.leanback.widget.PresenterSelector) parameter #0:
+    Missing nullability on parameter `parent` in method `init`
+MissingNullability: androidx.leanback.widget.PresenterSwitcher#init(android.view.ViewGroup, androidx.leanback.widget.PresenterSelector) parameter #1:
+    Missing nullability on parameter `presenterSelector` in method `init`
+MissingNullability: androidx.leanback.widget.PresenterSwitcher#insertView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `insertView`
+MissingNullability: androidx.leanback.widget.PresenterSwitcher#onViewSelected(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onViewSelected`
+MissingNullability: androidx.leanback.widget.PresenterSwitcher#select(Object) parameter #0:
+    Missing nullability on parameter `object` in method `select`
+MissingNullability: androidx.leanback.widget.PresenterSwitcher#showView(android.view.View, boolean) parameter #0:
+    Missing nullability on parameter `view` in method `showView`
+MissingNullability: androidx.leanback.widget.RecyclerViewParallax#createProperty(String, int):
+    Missing nullability on method `createProperty` return
+MissingNullability: androidx.leanback.widget.RecyclerViewParallax#createProperty(String, int) parameter #0:
+    Missing nullability on parameter `name` in method `createProperty`
+MissingNullability: androidx.leanback.widget.RecyclerViewParallax#getRecyclerView():
+    Missing nullability on method `getRecyclerView` return
+MissingNullability: androidx.leanback.widget.RecyclerViewParallax#setRecyclerView(androidx.recyclerview.widget.RecyclerView) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `setRecyclerView`
+MissingNullability: androidx.leanback.widget.RecyclerViewParallax.ChildPositionProperty#adapterPosition(int):
+    Missing nullability on method `adapterPosition` return
+MissingNullability: androidx.leanback.widget.RecyclerViewParallax.ChildPositionProperty#fraction(float):
+    Missing nullability on method `fraction` return
+MissingNullability: androidx.leanback.widget.RecyclerViewParallax.ChildPositionProperty#offset(int):
+    Missing nullability on method `offset` return
+MissingNullability: androidx.leanback.widget.RecyclerViewParallax.ChildPositionProperty#viewId(int):
+    Missing nullability on method `viewId` return
+MissingNullability: androidx.leanback.widget.Row#Row(androidx.leanback.widget.HeaderItem) parameter #0:
+    Missing nullability on parameter `headerItem` in method `Row`
+MissingNullability: androidx.leanback.widget.Row#Row(long, androidx.leanback.widget.HeaderItem) parameter #1:
+    Missing nullability on parameter `headerItem` in method `Row`
+MissingNullability: androidx.leanback.widget.Row#getHeaderItem():
+    Missing nullability on method `getHeaderItem` return
+MissingNullability: androidx.leanback.widget.Row#setHeaderItem(androidx.leanback.widget.HeaderItem) parameter #0:
+    Missing nullability on parameter `headerItem` in method `setHeaderItem`
+MissingNullability: androidx.leanback.widget.RowHeaderPresenter#getFontDescent(android.widget.TextView, android.graphics.Paint) parameter #0:
+    Missing nullability on parameter `textView` in method `getFontDescent`
+MissingNullability: androidx.leanback.widget.RowHeaderPresenter#getFontDescent(android.widget.TextView, android.graphics.Paint) parameter #1:
+    Missing nullability on parameter `fontMeasurePaint` in method `getFontDescent`
+MissingNullability: androidx.leanback.widget.RowHeaderPresenter#getSpaceUnderBaseline(androidx.leanback.widget.RowHeaderPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `getSpaceUnderBaseline`
+MissingNullability: androidx.leanback.widget.RowHeaderPresenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.RowHeaderPresenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.RowHeaderPresenter#onCreateViewHolder(android.view.ViewGroup):
+    Missing nullability on method `onCreateViewHolder` return
+MissingNullability: androidx.leanback.widget.RowHeaderPresenter#onCreateViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `onCreateViewHolder`
+MissingNullability: androidx.leanback.widget.RowHeaderPresenter#onSelectLevelChanged(androidx.leanback.widget.RowHeaderPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onSelectLevelChanged`
+MissingNullability: androidx.leanback.widget.RowHeaderPresenter#onUnbindViewHolder(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onUnbindViewHolder`
+MissingNullability: androidx.leanback.widget.RowHeaderPresenter#setSelectLevel(androidx.leanback.widget.RowHeaderPresenter.ViewHolder, float) parameter #0:
+    Missing nullability on parameter `holder` in method `setSelectLevel`
+MissingNullability: androidx.leanback.widget.RowHeaderPresenter.ViewHolder#ViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.RowHeaderView#RowHeaderView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `RowHeaderView`
+MissingNullability: androidx.leanback.widget.RowHeaderView#RowHeaderView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `RowHeaderView`
+MissingNullability: androidx.leanback.widget.RowHeaderView#RowHeaderView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `RowHeaderView`
+MissingNullability: androidx.leanback.widget.RowHeaderView#RowHeaderView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `RowHeaderView`
+MissingNullability: androidx.leanback.widget.RowHeaderView#RowHeaderView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `RowHeaderView`
+MissingNullability: androidx.leanback.widget.RowHeaderView#setCustomSelectionActionModeCallback(android.view.ActionMode.Callback) parameter #0:
+    Missing nullability on parameter `actionModeCallback` in method `setCustomSelectionActionModeCallback`
+MissingNullability: androidx.leanback.widget.RowPresenter#createRowViewHolder(android.view.ViewGroup):
+    Missing nullability on method `createRowViewHolder` return
+MissingNullability: androidx.leanback.widget.RowPresenter#createRowViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `createRowViewHolder`
+MissingNullability: androidx.leanback.widget.RowPresenter#dispatchItemSelectedListener(androidx.leanback.widget.RowPresenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `vh` in method `dispatchItemSelectedListener`
+MissingNullability: androidx.leanback.widget.RowPresenter#freeze(androidx.leanback.widget.RowPresenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `holder` in method `freeze`
+MissingNullability: androidx.leanback.widget.RowPresenter#getHeaderPresenter():
+    Missing nullability on method `getHeaderPresenter` return
+MissingNullability: androidx.leanback.widget.RowPresenter#getRowViewHolder(androidx.leanback.widget.Presenter.ViewHolder):
+    Missing nullability on method `getRowViewHolder` return
+MissingNullability: androidx.leanback.widget.RowPresenter#getRowViewHolder(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `getRowViewHolder`
+MissingNullability: androidx.leanback.widget.RowPresenter#getSelectLevel(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `getSelectLevel`
+MissingNullability: androidx.leanback.widget.RowPresenter#initializeRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `initializeRowViewHolder`
+MissingNullability: androidx.leanback.widget.RowPresenter#onBindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `vh` in method `onBindRowViewHolder`
+MissingNullability: androidx.leanback.widget.RowPresenter#onBindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindRowViewHolder`
+MissingNullability: androidx.leanback.widget.RowPresenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.RowPresenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.RowPresenter#onCreateViewHolder(android.view.ViewGroup):
+    Missing nullability on method `onCreateViewHolder` return
+MissingNullability: androidx.leanback.widget.RowPresenter#onCreateViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `onCreateViewHolder`
+MissingNullability: androidx.leanback.widget.RowPresenter#onRowViewAttachedToWindow(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onRowViewAttachedToWindow`
+MissingNullability: androidx.leanback.widget.RowPresenter#onRowViewDetachedFromWindow(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onRowViewDetachedFromWindow`
+MissingNullability: androidx.leanback.widget.RowPresenter#onRowViewExpanded(androidx.leanback.widget.RowPresenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `vh` in method `onRowViewExpanded`
+MissingNullability: androidx.leanback.widget.RowPresenter#onRowViewSelected(androidx.leanback.widget.RowPresenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `vh` in method `onRowViewSelected`
+MissingNullability: androidx.leanback.widget.RowPresenter#onSelectLevelChanged(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onSelectLevelChanged`
+MissingNullability: androidx.leanback.widget.RowPresenter#onUnbindRowViewHolder(androidx.leanback.widget.RowPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `onUnbindRowViewHolder`
+MissingNullability: androidx.leanback.widget.RowPresenter#onUnbindViewHolder(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onUnbindViewHolder`
+MissingNullability: androidx.leanback.widget.RowPresenter#onViewAttachedToWindow(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onViewAttachedToWindow`
+MissingNullability: androidx.leanback.widget.RowPresenter#onViewDetachedFromWindow(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onViewDetachedFromWindow`
+MissingNullability: androidx.leanback.widget.RowPresenter#setEntranceTransitionState(androidx.leanback.widget.RowPresenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `holder` in method `setEntranceTransitionState`
+MissingNullability: androidx.leanback.widget.RowPresenter#setHeaderPresenter(androidx.leanback.widget.RowHeaderPresenter) parameter #0:
+    Missing nullability on parameter `headerPresenter` in method `setHeaderPresenter`
+MissingNullability: androidx.leanback.widget.RowPresenter#setRowViewExpanded(androidx.leanback.widget.Presenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `holder` in method `setRowViewExpanded`
+MissingNullability: androidx.leanback.widget.RowPresenter#setRowViewSelected(androidx.leanback.widget.Presenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `holder` in method `setRowViewSelected`
+MissingNullability: androidx.leanback.widget.RowPresenter#setSelectLevel(androidx.leanback.widget.Presenter.ViewHolder, float) parameter #0:
+    Missing nullability on parameter `vh` in method `setSelectLevel`
+MissingNullability: androidx.leanback.widget.RowPresenter.ViewHolder#ViewHolder(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.RowPresenter.ViewHolder#getHeaderViewHolder():
+    Missing nullability on method `getHeaderViewHolder` return
+MissingNullability: androidx.leanback.widget.RowPresenter.ViewHolder#getOnItemViewClickedListener():
+    Missing nullability on method `getOnItemViewClickedListener` return
+MissingNullability: androidx.leanback.widget.RowPresenter.ViewHolder#getOnItemViewSelectedListener():
+    Missing nullability on method `getOnItemViewSelectedListener` return
+MissingNullability: androidx.leanback.widget.RowPresenter.ViewHolder#getOnKeyListener():
+    Missing nullability on method `getOnKeyListener` return
+MissingNullability: androidx.leanback.widget.RowPresenter.ViewHolder#getRow():
+    Missing nullability on method `getRow` return
+MissingNullability: androidx.leanback.widget.RowPresenter.ViewHolder#getRowObject():
+    Missing nullability on method `getRowObject` return
+MissingNullability: androidx.leanback.widget.RowPresenter.ViewHolder#getSelectedItem():
+    Missing nullability on method `getSelectedItem` return
+MissingNullability: androidx.leanback.widget.RowPresenter.ViewHolder#getSelectedItemViewHolder():
+    Missing nullability on method `getSelectedItemViewHolder` return
+MissingNullability: androidx.leanback.widget.RowPresenter.ViewHolder#mColorDimmer:
+    Missing nullability on field `mColorDimmer` in class `class androidx.leanback.widget.RowPresenter.ViewHolder`
+MissingNullability: androidx.leanback.widget.RowPresenter.ViewHolder#setOnItemViewClickedListener(androidx.leanback.widget.BaseOnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.widget.RowPresenter.ViewHolder#setOnItemViewSelectedListener(androidx.leanback.widget.BaseOnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.widget.RowPresenter.ViewHolder#setOnKeyListener(android.view.View.OnKeyListener) parameter #0:
+    Missing nullability on parameter `keyListener` in method `setOnKeyListener`
+MissingNullability: androidx.leanback.widget.RowPresenter.ViewHolder#syncActivatedStatus(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `syncActivatedStatus`
+MissingNullability: androidx.leanback.widget.SearchBar#SearchBar(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `SearchBar`
+MissingNullability: androidx.leanback.widget.SearchBar#SearchBar(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `SearchBar`
+MissingNullability: androidx.leanback.widget.SearchBar#SearchBar(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `SearchBar`
+MissingNullability: androidx.leanback.widget.SearchBar#SearchBar(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `SearchBar`
+MissingNullability: androidx.leanback.widget.SearchBar#SearchBar(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `SearchBar`
+MissingNullability: androidx.leanback.widget.SearchBar#displayCompletions(android.view.inputmethod.CompletionInfo[]) parameter #0:
+    Missing nullability on parameter `completions` in method `displayCompletions`
+MissingNullability: androidx.leanback.widget.SearchBar#displayCompletions(java.util.List<java.lang.String>) parameter #0:
+    Missing nullability on parameter `completions` in method `displayCompletions`
+MissingNullability: androidx.leanback.widget.SearchBar#getBadgeDrawable():
+    Missing nullability on method `getBadgeDrawable` return
+MissingNullability: androidx.leanback.widget.SearchBar#getHint():
+    Missing nullability on method `getHint` return
+MissingNullability: androidx.leanback.widget.SearchBar#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.leanback.widget.SearchBar#setBadgeDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setBadgeDrawable`
+MissingNullability: androidx.leanback.widget.SearchBar#setPermissionListener(androidx.leanback.widget.SearchBar.SearchBarPermissionListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setPermissionListener`
+MissingNullability: androidx.leanback.widget.SearchBar#setSearchAffordanceColors(androidx.leanback.widget.SearchOrbView.Colors) parameter #0:
+    Missing nullability on parameter `colors` in method `setSearchAffordanceColors`
+MissingNullability: androidx.leanback.widget.SearchBar#setSearchAffordanceColorsInListening(androidx.leanback.widget.SearchOrbView.Colors) parameter #0:
+    Missing nullability on parameter `colors` in method `setSearchAffordanceColorsInListening`
+MissingNullability: androidx.leanback.widget.SearchBar#setSearchBarListener(androidx.leanback.widget.SearchBar.SearchBarListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setSearchBarListener`
+MissingNullability: androidx.leanback.widget.SearchBar#setSearchQuery(String) parameter #0:
+    Missing nullability on parameter `query` in method `setSearchQuery`
+MissingNullability: androidx.leanback.widget.SearchBar#setSpeechRecognitionCallback(androidx.leanback.widget.SpeechRecognitionCallback) parameter #0:
+    Missing nullability on parameter `request` in method `setSpeechRecognitionCallback`
+MissingNullability: androidx.leanback.widget.SearchBar#setSpeechRecognizer(android.speech.SpeechRecognizer) parameter #0:
+    Missing nullability on parameter `recognizer` in method `setSpeechRecognizer`
+MissingNullability: androidx.leanback.widget.SearchBar#setTitle(String) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.leanback.widget.SearchBar.SearchBarListener#onKeyboardDismiss(String) parameter #0:
+    Missing nullability on parameter `query` in method `onKeyboardDismiss`
+MissingNullability: androidx.leanback.widget.SearchBar.SearchBarListener#onSearchQueryChange(String) parameter #0:
+    Missing nullability on parameter `query` in method `onSearchQueryChange`
+MissingNullability: androidx.leanback.widget.SearchBar.SearchBarListener#onSearchQuerySubmit(String) parameter #0:
+    Missing nullability on parameter `query` in method `onSearchQuerySubmit`
+MissingNullability: androidx.leanback.widget.SearchEditText#SearchEditText(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `SearchEditText`
+MissingNullability: androidx.leanback.widget.SearchEditText#SearchEditText(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `SearchEditText`
+MissingNullability: androidx.leanback.widget.SearchEditText#SearchEditText(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `SearchEditText`
+MissingNullability: androidx.leanback.widget.SearchEditText#SearchEditText(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `SearchEditText`
+MissingNullability: androidx.leanback.widget.SearchEditText#SearchEditText(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `SearchEditText`
+MissingNullability: androidx.leanback.widget.SearchEditText#onKeyPreIme(int, android.view.KeyEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onKeyPreIme`
+MissingNullability: androidx.leanback.widget.SearchEditText#setOnKeyboardDismissListener(androidx.leanback.widget.SearchEditText.OnKeyboardDismissListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnKeyboardDismissListener`
+MissingNullability: androidx.leanback.widget.SearchOrbView#SearchOrbView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `SearchOrbView`
+MissingNullability: androidx.leanback.widget.SearchOrbView#SearchOrbView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `SearchOrbView`
+MissingNullability: androidx.leanback.widget.SearchOrbView#SearchOrbView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `SearchOrbView`
+MissingNullability: androidx.leanback.widget.SearchOrbView#SearchOrbView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `SearchOrbView`
+MissingNullability: androidx.leanback.widget.SearchOrbView#SearchOrbView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `SearchOrbView`
+MissingNullability: androidx.leanback.widget.SearchOrbView#getOrbColors():
+    Missing nullability on method `getOrbColors` return
+MissingNullability: androidx.leanback.widget.SearchOrbView#getOrbIcon():
+    Missing nullability on method `getOrbIcon` return
+MissingNullability: androidx.leanback.widget.SearchOrbView#onClick(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onClick`
+MissingNullability: androidx.leanback.widget.SearchOrbView#onFocusChanged(boolean, int, android.graphics.Rect) parameter #2:
+    Missing nullability on parameter `previouslyFocusedRect` in method `onFocusChanged`
+MissingNullability: androidx.leanback.widget.SearchOrbView#setOnOrbClickedListener(android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnOrbClickedListener`
+MissingNullability: androidx.leanback.widget.SearchOrbView#setOrbColors(androidx.leanback.widget.SearchOrbView.Colors) parameter #0:
+    Missing nullability on parameter `colors` in method `setOrbColors`
+MissingNullability: androidx.leanback.widget.SearchOrbView#setOrbIcon(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `icon` in method `setOrbIcon`
+MissingNullability: androidx.leanback.widget.SectionRow#SectionRow(String) parameter #0:
+    Missing nullability on parameter `name` in method `SectionRow`
+MissingNullability: androidx.leanback.widget.SectionRow#SectionRow(androidx.leanback.widget.HeaderItem) parameter #0:
+    Missing nullability on parameter `headerItem` in method `SectionRow`
+MissingNullability: androidx.leanback.widget.SectionRow#SectionRow(long, String) parameter #1:
+    Missing nullability on parameter `name` in method `SectionRow`
+MissingNullability: androidx.leanback.widget.ShadowOverlayContainer#ShadowOverlayContainer(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `ShadowOverlayContainer`
+MissingNullability: androidx.leanback.widget.ShadowOverlayContainer#ShadowOverlayContainer(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `ShadowOverlayContainer`
+MissingNullability: androidx.leanback.widget.ShadowOverlayContainer#ShadowOverlayContainer(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `ShadowOverlayContainer`
+MissingNullability: androidx.leanback.widget.ShadowOverlayContainer#ShadowOverlayContainer(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `ShadowOverlayContainer`
+MissingNullability: androidx.leanback.widget.ShadowOverlayContainer#ShadowOverlayContainer(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `ShadowOverlayContainer`
+MissingNullability: androidx.leanback.widget.ShadowOverlayContainer#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
+MissingNullability: androidx.leanback.widget.ShadowOverlayContainer#getWrappedView():
+    Missing nullability on method `getWrappedView` return
+MissingNullability: androidx.leanback.widget.ShadowOverlayContainer#prepareParentForShadow(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `prepareParentForShadow`
+MissingNullability: androidx.leanback.widget.ShadowOverlayContainer#wrap(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `wrap`
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper#createShadowOverlayContainer(android.content.Context):
+    Missing nullability on method `createShadowOverlayContainer` return
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper#createShadowOverlayContainer(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `createShadowOverlayContainer`
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper#onViewCreated(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onViewCreated`
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper#prepareParentForShadow(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `prepareParentForShadow`
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper#setNoneWrapperOverlayColor(android.view.View, int) parameter #0:
+    Missing nullability on parameter `view` in method `setNoneWrapperOverlayColor`
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper#setNoneWrapperShadowFocusLevel(android.view.View, float) parameter #0:
+    Missing nullability on parameter `view` in method `setNoneWrapperShadowFocusLevel`
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper#setOverlayColor(android.view.View, int) parameter #0:
+    Missing nullability on parameter `view` in method `setOverlayColor`
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper#setShadowFocusLevel(android.view.View, float) parameter #0:
+    Missing nullability on parameter `view` in method `setShadowFocusLevel`
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper.Builder#build(android.content.Context):
+    Missing nullability on method `build` return
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper.Builder#build(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `build`
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper.Builder#keepForegroundDrawable(boolean):
+    Missing nullability on method `keepForegroundDrawable` return
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper.Builder#needsOverlay(boolean):
+    Missing nullability on method `needsOverlay` return
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper.Builder#needsRoundedCorner(boolean):
+    Missing nullability on method `needsRoundedCorner` return
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper.Builder#needsShadow(boolean):
+    Missing nullability on method `needsShadow` return
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper.Builder#options(androidx.leanback.widget.ShadowOverlayHelper.Options):
+    Missing nullability on method `options` return
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper.Builder#options(androidx.leanback.widget.ShadowOverlayHelper.Options) parameter #0:
+    Missing nullability on parameter `options` in method `options`
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper.Builder#preferZOrder(boolean):
+    Missing nullability on method `preferZOrder` return
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper.Options#DEFAULT:
+    Missing nullability on field `DEFAULT` in class `class androidx.leanback.widget.ShadowOverlayHelper.Options`
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper.Options#dynamicShadowZ(float, float):
+    Missing nullability on method `dynamicShadowZ` return
+MissingNullability: androidx.leanback.widget.ShadowOverlayHelper.Options#roundedCornerRadius(int):
+    Missing nullability on method `roundedCornerRadius` return
+MissingNullability: androidx.leanback.widget.SinglePresenterSelector#SinglePresenterSelector(androidx.leanback.widget.Presenter) parameter #0:
+    Missing nullability on parameter `presenter` in method `SinglePresenterSelector`
+MissingNullability: androidx.leanback.widget.SinglePresenterSelector#getPresenter(Object):
+    Missing nullability on method `getPresenter` return
+MissingNullability: androidx.leanback.widget.SinglePresenterSelector#getPresenter(Object) parameter #0:
+    Missing nullability on parameter `item` in method `getPresenter`
+MissingNullability: androidx.leanback.widget.SinglePresenterSelector#getPresenters():
+    Missing nullability on method `getPresenters` return
+MissingNullability: androidx.leanback.widget.SparseArrayObjectAdapter#SparseArrayObjectAdapter(androidx.leanback.widget.Presenter) parameter #0:
+    Missing nullability on parameter `presenter` in method `SparseArrayObjectAdapter`
+MissingNullability: androidx.leanback.widget.SparseArrayObjectAdapter#SparseArrayObjectAdapter(androidx.leanback.widget.PresenterSelector) parameter #0:
+    Missing nullability on parameter `presenterSelector` in method `SparseArrayObjectAdapter`
+MissingNullability: androidx.leanback.widget.SparseArrayObjectAdapter#get(int):
+    Missing nullability on method `get` return
+MissingNullability: androidx.leanback.widget.SparseArrayObjectAdapter#indexOf(Object) parameter #0:
+    Missing nullability on parameter `item` in method `indexOf`
+MissingNullability: androidx.leanback.widget.SparseArrayObjectAdapter#lookup(int):
+    Missing nullability on method `lookup` return
+MissingNullability: androidx.leanback.widget.SparseArrayObjectAdapter#set(int, Object) parameter #1:
+    Missing nullability on parameter `item` in method `set`
+MissingNullability: androidx.leanback.widget.SpeechOrbView#SpeechOrbView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `SpeechOrbView`
+MissingNullability: androidx.leanback.widget.SpeechOrbView#SpeechOrbView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `SpeechOrbView`
+MissingNullability: androidx.leanback.widget.SpeechOrbView#SpeechOrbView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `SpeechOrbView`
+MissingNullability: androidx.leanback.widget.SpeechOrbView#SpeechOrbView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `SpeechOrbView`
+MissingNullability: androidx.leanback.widget.SpeechOrbView#SpeechOrbView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `SpeechOrbView`
+MissingNullability: androidx.leanback.widget.SpeechOrbView#setListeningOrbColors(androidx.leanback.widget.SearchOrbView.Colors) parameter #0:
+    Missing nullability on parameter `colors` in method `setListeningOrbColors`
+MissingNullability: androidx.leanback.widget.SpeechOrbView#setNotListeningOrbColors(androidx.leanback.widget.SearchOrbView.Colors) parameter #0:
+    Missing nullability on parameter `colors` in method `setNotListeningOrbColors`
+MissingNullability: androidx.leanback.widget.TitleHelper#TitleHelper(android.view.ViewGroup, android.view.View) parameter #0:
+    Missing nullability on parameter `sceneRoot` in method `TitleHelper`
+MissingNullability: androidx.leanback.widget.TitleHelper#TitleHelper(android.view.ViewGroup, android.view.View) parameter #1:
+    Missing nullability on parameter `titleView` in method `TitleHelper`
+MissingNullability: androidx.leanback.widget.TitleHelper#getOnFocusSearchListener():
+    Missing nullability on method `getOnFocusSearchListener` return
+MissingNullability: androidx.leanback.widget.TitleHelper#getSceneRoot():
+    Missing nullability on method `getSceneRoot` return
+MissingNullability: androidx.leanback.widget.TitleHelper#getTitleView():
+    Missing nullability on method `getTitleView` return
+MissingNullability: androidx.leanback.widget.TitleView#TitleView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `TitleView`
+MissingNullability: androidx.leanback.widget.TitleView#TitleView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `TitleView`
+MissingNullability: androidx.leanback.widget.TitleView#TitleView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `TitleView`
+MissingNullability: androidx.leanback.widget.TitleView#TitleView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `TitleView`
+MissingNullability: androidx.leanback.widget.TitleView#TitleView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `TitleView`
+MissingNullability: androidx.leanback.widget.TitleView#getBadgeDrawable():
+    Missing nullability on method `getBadgeDrawable` return
+MissingNullability: androidx.leanback.widget.TitleView#getSearchAffordanceColors():
+    Missing nullability on method `getSearchAffordanceColors` return
+MissingNullability: androidx.leanback.widget.TitleView#getSearchAffordanceView():
+    Missing nullability on method `getSearchAffordanceView` return
+MissingNullability: androidx.leanback.widget.TitleView#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.leanback.widget.TitleView#getTitleViewAdapter():
+    Missing nullability on method `getTitleViewAdapter` return
+MissingNullability: androidx.leanback.widget.TitleView#setBadgeDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setBadgeDrawable`
+MissingNullability: androidx.leanback.widget.TitleView#setOnSearchClickedListener(android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnSearchClickedListener`
+MissingNullability: androidx.leanback.widget.TitleView#setSearchAffordanceColors(androidx.leanback.widget.SearchOrbView.Colors) parameter #0:
+    Missing nullability on parameter `colors` in method `setSearchAffordanceColors`
+MissingNullability: androidx.leanback.widget.TitleView#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `titleText` in method `setTitle`
+MissingNullability: androidx.leanback.widget.TitleViewAdapter#getBadgeDrawable():
+    Missing nullability on method `getBadgeDrawable` return
+MissingNullability: androidx.leanback.widget.TitleViewAdapter#getSearchAffordanceColors():
+    Missing nullability on method `getSearchAffordanceColors` return
+MissingNullability: androidx.leanback.widget.TitleViewAdapter#getSearchAffordanceView():
+    Missing nullability on method `getSearchAffordanceView` return
+MissingNullability: androidx.leanback.widget.TitleViewAdapter#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.leanback.widget.TitleViewAdapter#setBadgeDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setBadgeDrawable`
+MissingNullability: androidx.leanback.widget.TitleViewAdapter#setOnSearchClickedListener(android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnSearchClickedListener`
+MissingNullability: androidx.leanback.widget.TitleViewAdapter#setSearchAffordanceColors(androidx.leanback.widget.SearchOrbView.Colors) parameter #0:
+    Missing nullability on parameter `colors` in method `setSearchAffordanceColors`
+MissingNullability: androidx.leanback.widget.TitleViewAdapter#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `titleText` in method `setTitle`
+MissingNullability: androidx.leanback.widget.TitleViewAdapter.Provider#getTitleViewAdapter():
+    Missing nullability on method `getTitleViewAdapter` return
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter#createGridViewHolder(android.view.ViewGroup):
+    Missing nullability on method `createGridViewHolder` return
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter#createGridViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `createGridViewHolder`
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter#createShadowOverlayOptions():
+    Missing nullability on method `createShadowOverlayOptions` return
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter#getOnItemViewClickedListener():
+    Missing nullability on method `getOnItemViewClickedListener` return
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter#getOnItemViewSelectedListener():
+    Missing nullability on method `getOnItemViewSelectedListener` return
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter#initializeGridViewHolder(androidx.leanback.widget.VerticalGridPresenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `vh` in method `initializeGridViewHolder`
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter#isUsingZOrder(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `isUsingZOrder`
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter#onBindViewHolder(androidx.leanback.widget.Presenter.ViewHolder, Object) parameter #1:
+    Missing nullability on parameter `item` in method `onBindViewHolder`
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter#onCreateViewHolder(android.view.ViewGroup):
+    Missing nullability on method `onCreateViewHolder` return
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter#onCreateViewHolder(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `parent` in method `onCreateViewHolder`
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter#onUnbindViewHolder(androidx.leanback.widget.Presenter.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `onUnbindViewHolder`
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter#setEntranceTransitionState(androidx.leanback.widget.VerticalGridPresenter.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `holder` in method `setEntranceTransitionState`
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter#setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewClickedListener`
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter#setOnItemViewSelectedListener(androidx.leanback.widget.OnItemViewSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnItemViewSelectedListener`
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter.ViewHolder#ViewHolder(androidx.leanback.widget.VerticalGridView) parameter #0:
+    Missing nullability on parameter `view` in method `ViewHolder`
+MissingNullability: androidx.leanback.widget.VerticalGridPresenter.ViewHolder#getGridView():
+    Missing nullability on method `getGridView` return
+MissingNullability: androidx.leanback.widget.VerticalGridView#VerticalGridView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `VerticalGridView`
+MissingNullability: androidx.leanback.widget.VerticalGridView#VerticalGridView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `VerticalGridView`
+MissingNullability: androidx.leanback.widget.VerticalGridView#VerticalGridView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `VerticalGridView`
+MissingNullability: androidx.leanback.widget.VerticalGridView#VerticalGridView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `VerticalGridView`
+MissingNullability: androidx.leanback.widget.VerticalGridView#VerticalGridView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `VerticalGridView`
+MissingNullability: androidx.leanback.widget.VerticalGridView#initAttributes(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `initAttributes`
+MissingNullability: androidx.leanback.widget.VerticalGridView#initAttributes(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `initAttributes`
+MissingNullability: androidx.leanback.widget.ViewHolderTask#run(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `viewHolder` in method `run`
+MissingNullability: androidx.leanback.widget.picker.DatePicker#DatePicker(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `DatePicker`
+MissingNullability: androidx.leanback.widget.picker.DatePicker#DatePicker(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `DatePicker`
+MissingNullability: androidx.leanback.widget.picker.DatePicker#DatePicker(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `DatePicker`
+MissingNullability: androidx.leanback.widget.picker.DatePicker#DatePicker(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `DatePicker`
+MissingNullability: androidx.leanback.widget.picker.DatePicker#getDatePickerFormat():
+    Missing nullability on method `getDatePickerFormat` return
+MissingNullability: androidx.leanback.widget.picker.DatePicker#setDatePickerFormat(String) parameter #0:
+    Missing nullability on parameter `datePickerFormat` in method `setDatePickerFormat`
+MissingNullability: androidx.leanback.widget.picker.Picker#Picker(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `Picker`
+MissingNullability: androidx.leanback.widget.picker.Picker#Picker(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attributeSet` in method `Picker`
+MissingNullability: androidx.leanback.widget.picker.Picker#Picker(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `Picker`
+MissingNullability: androidx.leanback.widget.picker.Picker#Picker(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `Picker`
+MissingNullability: androidx.leanback.widget.picker.Picker#addOnValueChangedListener(androidx.leanback.widget.picker.Picker.PickerValueListener) parameter #0:
+    Missing nullability on parameter `listener` in method `addOnValueChangedListener`
+MissingNullability: androidx.leanback.widget.picker.Picker#dispatchKeyEvent(android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `event` in method `dispatchKeyEvent`
+MissingNullability: androidx.leanback.widget.picker.Picker#getColumnAt(int):
+    Missing nullability on method `getColumnAt` return
+MissingNullability: androidx.leanback.widget.picker.Picker#getSeparators():
+    Missing nullability on method `getSeparators` return
+MissingNullability: androidx.leanback.widget.picker.Picker#onRequestFocusInDescendants(int, android.graphics.Rect) parameter #1:
+    Missing nullability on parameter `previouslyFocusedRect` in method `onRequestFocusInDescendants`
+MissingNullability: androidx.leanback.widget.picker.Picker#removeOnValueChangedListener(androidx.leanback.widget.picker.Picker.PickerValueListener) parameter #0:
+    Missing nullability on parameter `listener` in method `removeOnValueChangedListener`
+MissingNullability: androidx.leanback.widget.picker.Picker#requestChildFocus(android.view.View, android.view.View) parameter #0:
+    Missing nullability on parameter `child` in method `requestChildFocus`
+MissingNullability: androidx.leanback.widget.picker.Picker#requestChildFocus(android.view.View, android.view.View) parameter #1:
+    Missing nullability on parameter `focused` in method `requestChildFocus`
+MissingNullability: androidx.leanback.widget.picker.Picker#setColumnAt(int, androidx.leanback.widget.picker.PickerColumn) parameter #1:
+    Missing nullability on parameter `column` in method `setColumnAt`
+MissingNullability: androidx.leanback.widget.picker.Picker#setColumns(java.util.List<androidx.leanback.widget.picker.PickerColumn>) parameter #0:
+    Missing nullability on parameter `columns` in method `setColumns`
+MissingNullability: androidx.leanback.widget.picker.Picker#setSeparator(CharSequence) parameter #0:
+    Missing nullability on parameter `separator` in method `setSeparator`
+MissingNullability: androidx.leanback.widget.picker.Picker#setSeparators(java.util.List<java.lang.CharSequence>) parameter #0:
+    Missing nullability on parameter `separators` in method `setSeparators`
+MissingNullability: androidx.leanback.widget.picker.Picker.PickerValueListener#onValueChanged(androidx.leanback.widget.picker.Picker, int) parameter #0:
+    Missing nullability on parameter `picker` in method `onValueChanged`
+MissingNullability: androidx.leanback.widget.picker.PickerColumn#getLabelFor(int):
+    Missing nullability on method `getLabelFor` return
+MissingNullability: androidx.leanback.widget.picker.PickerColumn#getLabelFormat():
+    Missing nullability on method `getLabelFormat` return
+MissingNullability: androidx.leanback.widget.picker.PickerColumn#getStaticLabels():
+    Missing nullability on method `getStaticLabels` return
+MissingNullability: androidx.leanback.widget.picker.PickerColumn#setLabelFormat(String) parameter #0:
+    Missing nullability on parameter `labelFormat` in method `setLabelFormat`
+MissingNullability: androidx.leanback.widget.picker.PickerColumn#setStaticLabels(CharSequence[]) parameter #0:
+    Missing nullability on parameter `labels` in method `setStaticLabels`
+MissingNullability: androidx.leanback.widget.picker.PinPicker#PinPicker(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `PinPicker`
+MissingNullability: androidx.leanback.widget.picker.PinPicker#PinPicker(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `PinPicker`
+MissingNullability: androidx.leanback.widget.picker.PinPicker#PinPicker(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `PinPicker`
+MissingNullability: androidx.leanback.widget.picker.PinPicker#PinPicker(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `PinPicker`
+MissingNullability: androidx.leanback.widget.picker.PinPicker#dispatchKeyEvent(android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `event` in method `dispatchKeyEvent`
+MissingNullability: androidx.leanback.widget.picker.PinPicker#getPin():
+    Missing nullability on method `getPin` return
+MissingNullability: androidx.leanback.widget.picker.TimePicker#TimePicker(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `TimePicker`
+MissingNullability: androidx.leanback.widget.picker.TimePicker#TimePicker(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `TimePicker`
+MissingNullability: androidx.leanback.widget.picker.TimePicker#TimePicker(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `TimePicker`
+MissingNullability: androidx.leanback.widget.picker.TimePicker#TimePicker(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `TimePicker`
+
+
 RegistrationName: androidx.leanback.media.PlaybackGlue#addPlayerCallback(androidx.leanback.media.PlaybackGlue.PlayerCallback):
     Callback methods should be named register/unregister; was addPlayerCallback
 RegistrationName: androidx.leanback.media.PlaybackGlue#removePlayerCallback(androidx.leanback.media.PlaybackGlue.PlayerCallback):
diff --git a/leanback/src/main/res/values-as/strings.xml b/leanback/src/main/res/values-as/strings.xml
index 05b84d6..7284e2d 100644
--- a/leanback/src/main/res/values-as/strings.xml
+++ b/leanback/src/main/res/values-as/strings.xml
@@ -40,7 +40,7 @@
     <string name="lb_playback_controls_thumb_down_outline" msgid="2847309435442474470">"থাম্ব ডাউন বাছনি কৰক"</string>
     <string name="lb_playback_controls_repeat_none" msgid="5812341701962930499">"একো পুনৰাই প্লে নকৰিব"</string>
     <string name="lb_playback_controls_repeat_all" msgid="5164826436271322261">"সকলো পুনৰাই প্লে কৰক"</string>
-    <string name="lb_playback_controls_repeat_one" msgid="7675097479246139440">"এটা পুনৰাই প্লে কৰক"</string>
+    <string name="lb_playback_controls_repeat_one" msgid="7675097479246139440">"এটা পুনৰাই প্লে’ কৰক"</string>
     <string name="lb_playback_controls_shuffle_enable" msgid="7809089255981448519">"সান-মিহলি সক্ষম কৰক"</string>
     <string name="lb_playback_controls_shuffle_disable" msgid="8182435535948303910">"সান-মিহলি অক্ষম কৰক"</string>
     <string name="lb_playback_controls_high_quality_enable" msgid="1862669142355962638">"উচ্চ মানৰ প্লেবেক সক্ষম কৰক"</string>
diff --git a/leanback/src/main/res/values-be/strings.xml b/leanback/src/main/res/values-be/strings.xml
index a4038d6..ad86128 100644
--- a/leanback/src/main/res/values-be/strings.xml
+++ b/leanback/src/main/res/values-be/strings.xml
@@ -47,7 +47,7 @@
     <string name="lb_playback_controls_high_quality_disable" msgid="3000046054608531995">"Адключыць высокую якасць"</string>
     <string name="lb_playback_controls_closed_captioning_enable" msgid="3934392140182327163">"Уключыць схаваныя цітры"</string>
     <string name="lb_playback_controls_closed_captioning_disable" msgid="5508271941331836786">"Адключыць схаваныя цітры"</string>
-    <string name="lb_playback_controls_picture_in_picture" msgid="8800305194045609275">"Увайсці ў рэжым \"Відарыс у відарысе\""</string>
+    <string name="lb_playback_controls_picture_in_picture" msgid="8800305194045609275">"Перайсці ў рэжым \"Відарыс у відарысе\""</string>
     <string name="lb_playback_time_separator" msgid="6549544638083578695">"/"</string>
     <string name="lb_playback_controls_shown" msgid="7794717158616536936">"Элементы кіравання мультымедыя паказаны"</string>
     <string name="lb_playback_controls_hidden" msgid="619396299825306757">"Элементы кіравання мультымедыя схаваны. Каб паказаць іх, націсніце d-pad"</string>
diff --git a/legacy/core-utils/api/api_lint.ignore b/legacy/core-utils/api/api_lint.ignore
new file mode 100644
index 0000000..cb08390
--- /dev/null
+++ b/legacy/core-utils/api/api_lint.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+MissingNullability: androidx.legacy.content.WakefulBroadcastReceiver#completeWakefulIntent(android.content.Intent) parameter #0:
+    Missing nullability on parameter `intent` in method `completeWakefulIntent`
+MissingNullability: androidx.legacy.content.WakefulBroadcastReceiver#startWakefulService(android.content.Context, android.content.Intent):
+    Missing nullability on method `startWakefulService` return
+MissingNullability: androidx.legacy.content.WakefulBroadcastReceiver#startWakefulService(android.content.Context, android.content.Intent) parameter #0:
+    Missing nullability on parameter `context` in method `startWakefulService`
+MissingNullability: androidx.legacy.content.WakefulBroadcastReceiver#startWakefulService(android.content.Context, android.content.Intent) parameter #1:
+    Missing nullability on parameter `intent` in method `startWakefulService`
diff --git a/lifecycle/lifecycle-common-java8/api/2.2.0-alpha04.txt b/lifecycle/lifecycle-common-java8/api/2.2.0-alpha04.txt
new file mode 100644
index 0000000..498d3a9
--- /dev/null
+++ b/lifecycle/lifecycle-common-java8/api/2.2.0-alpha04.txt
@@ -0,0 +1,14 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public interface DefaultLifecycleObserver extends androidx.lifecycle.LifecycleObserver androidx.lifecycle.LifecycleObserver {
+    method public default void onCreate(androidx.lifecycle.LifecycleOwner);
+    method public default void onDestroy(androidx.lifecycle.LifecycleOwner);
+    method public default void onPause(androidx.lifecycle.LifecycleOwner);
+    method public default void onResume(androidx.lifecycle.LifecycleOwner);
+    method public default void onStart(androidx.lifecycle.LifecycleOwner);
+    method public default void onStop(androidx.lifecycle.LifecycleOwner);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-common-java8/api/restricted_2.2.0-alpha04.txt b/lifecycle/lifecycle-common-java8/api/restricted_2.2.0-alpha04.txt
new file mode 100644
index 0000000..498d3a9
--- /dev/null
+++ b/lifecycle/lifecycle-common-java8/api/restricted_2.2.0-alpha04.txt
@@ -0,0 +1,14 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public interface DefaultLifecycleObserver extends androidx.lifecycle.LifecycleObserver androidx.lifecycle.LifecycleObserver {
+    method public default void onCreate(androidx.lifecycle.LifecycleOwner);
+    method public default void onDestroy(androidx.lifecycle.LifecycleOwner);
+    method public default void onPause(androidx.lifecycle.LifecycleOwner);
+    method public default void onResume(androidx.lifecycle.LifecycleOwner);
+    method public default void onStart(androidx.lifecycle.LifecycleOwner);
+    method public default void onStop(androidx.lifecycle.LifecycleOwner);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-common/api/2.2.0-alpha04.txt b/lifecycle/lifecycle-common/api/2.2.0-alpha04.txt
new file mode 100644
index 0000000..3f2e1d7
--- /dev/null
+++ b/lifecycle/lifecycle-common/api/2.2.0-alpha04.txt
@@ -0,0 +1,46 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public abstract class Lifecycle {
+    ctor public Lifecycle();
+    method @MainThread public abstract void addObserver(androidx.lifecycle.LifecycleObserver);
+    method @MainThread public abstract androidx.lifecycle.Lifecycle.State getCurrentState();
+    method @MainThread public abstract void removeObserver(androidx.lifecycle.LifecycleObserver);
+  }
+
+  public enum Lifecycle.Event {
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_ANY;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_CREATE;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_DESTROY;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_PAUSE;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_RESUME;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_START;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_STOP;
+  }
+
+  public enum Lifecycle.State {
+    method public boolean isAtLeast(androidx.lifecycle.Lifecycle.State);
+    enum_constant public static final androidx.lifecycle.Lifecycle.State CREATED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State DESTROYED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State INITIALIZED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State RESUMED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State STARTED;
+  }
+
+  public interface LifecycleEventObserver extends androidx.lifecycle.LifecycleObserver {
+    method public void onStateChanged(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.Event);
+  }
+
+  public interface LifecycleObserver {
+  }
+
+  public interface LifecycleOwner {
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface OnLifecycleEvent {
+    method public abstract androidx.lifecycle.Lifecycle.Event! value();
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-common/api/api_lint.ignore b/lifecycle/lifecycle-common/api/api_lint.ignore
index 09c14c4..676e161 100644
--- a/lifecycle/lifecycle-common/api/api_lint.ignore
+++ b/lifecycle/lifecycle-common/api/api_lint.ignore
@@ -3,3 +3,7 @@
     Class should be named LifecycleEventCallback
 CallbackName: androidx.lifecycle.LifecycleObserver:
     Class should be named LifecycleCallback
+
+
+MissingNullability: androidx.lifecycle.OnLifecycleEvent#value():
+    Missing nullability on method `value` return
diff --git a/lifecycle/lifecycle-common/api/restricted_2.2.0-alpha04.ignore b/lifecycle/lifecycle-common/api/restricted_2.2.0-alpha04.ignore
new file mode 100644
index 0000000..f8a81b8
--- /dev/null
+++ b/lifecycle/lifecycle-common/api/restricted_2.2.0-alpha04.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+AddedAbstractMethod: androidx.lifecycle.LifecycleEventObserver#onStateChanged(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.Event):
+    Added method androidx.lifecycle.LifecycleEventObserver.onStateChanged(androidx.lifecycle.LifecycleOwner,androidx.lifecycle.Lifecycle.Event)
diff --git a/lifecycle/lifecycle-common/api/restricted_2.2.0-alpha04.txt b/lifecycle/lifecycle-common/api/restricted_2.2.0-alpha04.txt
new file mode 100644
index 0000000..0a6849f
--- /dev/null
+++ b/lifecycle/lifecycle-common/api/restricted_2.2.0-alpha04.txt
@@ -0,0 +1,62 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface GeneratedAdapter {
+    method public void callMethods(androidx.lifecycle.LifecycleOwner!, androidx.lifecycle.Lifecycle.Event!, boolean, androidx.lifecycle.MethodCallsLogger!);
+  }
+
+  @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface GenericLifecycleObserver extends androidx.lifecycle.LifecycleEventObserver {
+  }
+
+  public abstract class Lifecycle {
+    ctor public Lifecycle();
+    method @MainThread public abstract void addObserver(androidx.lifecycle.LifecycleObserver);
+    method @MainThread public abstract androidx.lifecycle.Lifecycle.State getCurrentState();
+    method @MainThread public abstract void removeObserver(androidx.lifecycle.LifecycleObserver);
+  }
+
+  public enum Lifecycle.Event {
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_ANY;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_CREATE;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_DESTROY;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_PAUSE;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_RESUME;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_START;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_STOP;
+  }
+
+  public enum Lifecycle.State {
+    method public boolean isAtLeast(androidx.lifecycle.Lifecycle.State);
+    enum_constant public static final androidx.lifecycle.Lifecycle.State CREATED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State DESTROYED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State INITIALIZED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State RESUMED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State STARTED;
+  }
+
+  public interface LifecycleEventObserver extends androidx.lifecycle.LifecycleObserver {
+    method public void onStateChanged(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.Event);
+  }
+
+  public interface LifecycleObserver {
+  }
+
+  public interface LifecycleOwner {
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class Lifecycling {
+    method public static String! getAdapterName(String!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class MethodCallsLogger {
+    ctor public MethodCallsLogger();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean approveCall(String!, int);
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface OnLifecycleEvent {
+    method public abstract androidx.lifecycle.Lifecycle.Event! value();
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-extensions/api/2.2.0-alpha04.txt b/lifecycle/lifecycle-extensions/api/2.2.0-alpha04.txt
new file mode 100644
index 0000000..273ffbf
--- /dev/null
+++ b/lifecycle/lifecycle-extensions/api/2.2.0-alpha04.txt
@@ -0,0 +1,22 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  @Deprecated public class ViewModelProviders {
+    ctor @Deprecated public ViewModelProviders();
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.Fragment);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.FragmentActivity);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.Fragment, androidx.lifecycle.ViewModelProvider.Factory?);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.FragmentActivity, androidx.lifecycle.ViewModelProvider.Factory?);
+  }
+
+  @Deprecated public static class ViewModelProviders.DefaultFactory extends androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory {
+    ctor @Deprecated public ViewModelProviders.DefaultFactory(android.app.Application);
+  }
+
+  @Deprecated public class ViewModelStores {
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelStore of(androidx.fragment.app.FragmentActivity);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelStore of(androidx.fragment.app.Fragment);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/lifecycle/lifecycle-extensions/api/res-2.2.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to lifecycle/lifecycle-extensions/api/res-2.2.0-alpha04.txt
diff --git a/lifecycle/lifecycle-extensions/api/restricted_2.2.0-alpha04.txt b/lifecycle/lifecycle-extensions/api/restricted_2.2.0-alpha04.txt
new file mode 100644
index 0000000..273ffbf
--- /dev/null
+++ b/lifecycle/lifecycle-extensions/api/restricted_2.2.0-alpha04.txt
@@ -0,0 +1,22 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  @Deprecated public class ViewModelProviders {
+    ctor @Deprecated public ViewModelProviders();
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.Fragment);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.FragmentActivity);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.Fragment, androidx.lifecycle.ViewModelProvider.Factory?);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.FragmentActivity, androidx.lifecycle.ViewModelProvider.Factory?);
+  }
+
+  @Deprecated public static class ViewModelProviders.DefaultFactory extends androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory {
+    ctor @Deprecated public ViewModelProviders.DefaultFactory(android.app.Application);
+  }
+
+  @Deprecated public class ViewModelStores {
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelStore of(androidx.fragment.app.FragmentActivity);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelStore of(androidx.fragment.app.Fragment);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-livedata-core-ktx/api/2.2.0-alpha04.txt b/lifecycle/lifecycle-livedata-core-ktx/api/2.2.0-alpha04.txt
new file mode 100644
index 0000000..861a341
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-core-ktx/api/2.2.0-alpha04.txt
@@ -0,0 +1,10 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public final class LiveDataKt {
+    ctor public LiveDataKt();
+    method @MainThread public static inline <T> androidx.lifecycle.Observer<T> observe(androidx.lifecycle.LiveData<T>, androidx.lifecycle.LifecycleOwner owner, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> onChanged);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/lifecycle/lifecycle-livedata-core-ktx/api/res-2.2.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to lifecycle/lifecycle-livedata-core-ktx/api/res-2.2.0-alpha04.txt
diff --git a/lifecycle/lifecycle-livedata-core-ktx/api/restricted_2.2.0-alpha04.txt b/lifecycle/lifecycle-livedata-core-ktx/api/restricted_2.2.0-alpha04.txt
new file mode 100644
index 0000000..861a341
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-core-ktx/api/restricted_2.2.0-alpha04.txt
@@ -0,0 +1,10 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public final class LiveDataKt {
+    ctor public LiveDataKt();
+    method @MainThread public static inline <T> androidx.lifecycle.Observer<T> observe(androidx.lifecycle.LiveData<T>, androidx.lifecycle.LifecycleOwner owner, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> onChanged);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-livedata-core/api/2.2.0-alpha04.txt b/lifecycle/lifecycle-livedata-core/api/2.2.0-alpha04.txt
new file mode 100644
index 0000000..f0db7db
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-core/api/2.2.0-alpha04.txt
@@ -0,0 +1,32 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public abstract class LiveData<T> {
+    ctor public LiveData(T!);
+    ctor public LiveData();
+    method public T? getValue();
+    method public boolean hasActiveObservers();
+    method public boolean hasObservers();
+    method @MainThread public void observe(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Observer<? super T>);
+    method @MainThread public void observeForever(androidx.lifecycle.Observer<? super T>);
+    method protected void onActive();
+    method protected void onInactive();
+    method protected void postValue(T!);
+    method @MainThread public void removeObserver(androidx.lifecycle.Observer<? super T>);
+    method @MainThread public void removeObservers(androidx.lifecycle.LifecycleOwner);
+    method @MainThread protected void setValue(T!);
+  }
+
+  public class MutableLiveData<T> extends androidx.lifecycle.LiveData<T> {
+    ctor public MutableLiveData(T!);
+    ctor public MutableLiveData();
+    method public void postValue(T!);
+    method public void setValue(T!);
+  }
+
+  public interface Observer<T> {
+    method public void onChanged(T!);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/lifecycle/lifecycle-livedata-core/api/res-2.2.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to lifecycle/lifecycle-livedata-core/api/res-2.2.0-alpha04.txt
diff --git a/lifecycle/lifecycle-livedata-core/api/restricted_2.2.0-alpha04.txt b/lifecycle/lifecycle-livedata-core/api/restricted_2.2.0-alpha04.txt
new file mode 100644
index 0000000..f0db7db
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-core/api/restricted_2.2.0-alpha04.txt
@@ -0,0 +1,32 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public abstract class LiveData<T> {
+    ctor public LiveData(T!);
+    ctor public LiveData();
+    method public T? getValue();
+    method public boolean hasActiveObservers();
+    method public boolean hasObservers();
+    method @MainThread public void observe(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Observer<? super T>);
+    method @MainThread public void observeForever(androidx.lifecycle.Observer<? super T>);
+    method protected void onActive();
+    method protected void onInactive();
+    method protected void postValue(T!);
+    method @MainThread public void removeObserver(androidx.lifecycle.Observer<? super T>);
+    method @MainThread public void removeObservers(androidx.lifecycle.LifecycleOwner);
+    method @MainThread protected void setValue(T!);
+  }
+
+  public class MutableLiveData<T> extends androidx.lifecycle.LiveData<T> {
+    ctor public MutableLiveData(T!);
+    ctor public MutableLiveData();
+    method public void postValue(T!);
+    method public void setValue(T!);
+  }
+
+  public interface Observer<T> {
+    method public void onChanged(T!);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-livedata-ktx/api/2.2.0-alpha03.txt b/lifecycle/lifecycle-livedata-ktx/api/2.2.0-alpha03.txt
index 9dc2bee..26f3e49 100644
--- a/lifecycle/lifecycle-livedata-ktx/api/2.2.0-alpha03.txt
+++ b/lifecycle/lifecycle-livedata-ktx/api/2.2.0-alpha03.txt
@@ -11,6 +11,17 @@
     method public static <T> androidx.lifecycle.LiveData<T> liveData(kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
   }
 
+  public final class FlowLiveDataApi26Kt {
+    ctor public FlowLiveDataApi26Kt();
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, java.time.Duration timeout);
+  }
+
+  public final class FlowLiveDataKt {
+    ctor public FlowLiveDataKt();
+    method public static <T> kotlinx.coroutines.flow.Flow<T> asFlow(androidx.lifecycle.LiveData<T>);
+    method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L);
+  }
+
   public interface LiveDataScope<T> {
     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);
diff --git a/lifecycle/lifecycle-livedata-ktx/api/2.2.0-alpha04.txt b/lifecycle/lifecycle-livedata-ktx/api/2.2.0-alpha04.txt
new file mode 100644
index 0000000..26f3e49
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/api/2.2.0-alpha04.txt
@@ -0,0 +1,40 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public final class CoroutineLiveDataApi26Kt {
+    ctor public CoroutineLiveDataApi26Kt();
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> liveData(kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, java.time.Duration timeout, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+  }
+
+  public final class CoroutineLiveDataKt {
+    ctor public CoroutineLiveDataKt();
+    method public static <T> androidx.lifecycle.LiveData<T> liveData(kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+  }
+
+  public final class FlowLiveDataApi26Kt {
+    ctor public FlowLiveDataApi26Kt();
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, java.time.Duration timeout);
+  }
+
+  public final class FlowLiveDataKt {
+    ctor public FlowLiveDataKt();
+    method public static <T> kotlinx.coroutines.flow.Flow<T> asFlow(androidx.lifecycle.LiveData<T>);
+    method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L);
+  }
+
+  public interface LiveDataScope<T> {
+    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;
+  }
+
+  public final class TransformationsKt {
+    ctor public TransformationsKt();
+    method public static inline <X> androidx.lifecycle.LiveData<X> distinctUntilChanged(androidx.lifecycle.LiveData<X>);
+    method public static inline <X, Y> androidx.lifecycle.LiveData<Y> map(androidx.lifecycle.LiveData<X>, kotlin.jvm.functions.Function1<? super X,? extends Y> transform);
+    method public static inline <X, Y> androidx.lifecycle.LiveData<Y> switchMap(androidx.lifecycle.LiveData<X>, kotlin.jvm.functions.Function1<? super X,? extends androidx.lifecycle.LiveData<Y>> transform);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-livedata-ktx/api/api_lint.ignore b/lifecycle/lifecycle-livedata-ktx/api/api_lint.ignore
new file mode 100644
index 0000000..9763738
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/api/api_lint.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+MissingNullability: androidx.lifecycle.LiveDataScope#emit(T, kotlin.coroutines.Continuation<? super kotlin.Unit>):
+    Missing nullability on method `emit` return
diff --git a/lifecycle/lifecycle-livedata-ktx/api/current.txt b/lifecycle/lifecycle-livedata-ktx/api/current.txt
index 9dc2bee..26f3e49 100644
--- a/lifecycle/lifecycle-livedata-ktx/api/current.txt
+++ b/lifecycle/lifecycle-livedata-ktx/api/current.txt
@@ -11,6 +11,17 @@
     method public static <T> androidx.lifecycle.LiveData<T> liveData(kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
   }
 
+  public final class FlowLiveDataApi26Kt {
+    ctor public FlowLiveDataApi26Kt();
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, java.time.Duration timeout);
+  }
+
+  public final class FlowLiveDataKt {
+    ctor public FlowLiveDataKt();
+    method public static <T> kotlinx.coroutines.flow.Flow<T> asFlow(androidx.lifecycle.LiveData<T>);
+    method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L);
+  }
+
   public interface LiveDataScope<T> {
     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);
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/lifecycle/lifecycle-livedata-ktx/api/res-2.2.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to lifecycle/lifecycle-livedata-ktx/api/res-2.2.0-alpha04.txt
diff --git a/lifecycle/lifecycle-livedata-ktx/api/restricted_2.2.0-alpha03.txt b/lifecycle/lifecycle-livedata-ktx/api/restricted_2.2.0-alpha03.txt
index 9dc2bee..26f3e49 100644
--- a/lifecycle/lifecycle-livedata-ktx/api/restricted_2.2.0-alpha03.txt
+++ b/lifecycle/lifecycle-livedata-ktx/api/restricted_2.2.0-alpha03.txt
@@ -11,6 +11,17 @@
     method public static <T> androidx.lifecycle.LiveData<T> liveData(kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
   }
 
+  public final class FlowLiveDataApi26Kt {
+    ctor public FlowLiveDataApi26Kt();
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, java.time.Duration timeout);
+  }
+
+  public final class FlowLiveDataKt {
+    ctor public FlowLiveDataKt();
+    method public static <T> kotlinx.coroutines.flow.Flow<T> asFlow(androidx.lifecycle.LiveData<T>);
+    method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L);
+  }
+
   public interface LiveDataScope<T> {
     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);
diff --git a/lifecycle/lifecycle-livedata-ktx/api/restricted_2.2.0-alpha04.txt b/lifecycle/lifecycle-livedata-ktx/api/restricted_2.2.0-alpha04.txt
new file mode 100644
index 0000000..26f3e49
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/api/restricted_2.2.0-alpha04.txt
@@ -0,0 +1,40 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public final class CoroutineLiveDataApi26Kt {
+    ctor public CoroutineLiveDataApi26Kt();
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> liveData(kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, java.time.Duration timeout, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+  }
+
+  public final class CoroutineLiveDataKt {
+    ctor public CoroutineLiveDataKt();
+    method public static <T> androidx.lifecycle.LiveData<T> liveData(kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+  }
+
+  public final class FlowLiveDataApi26Kt {
+    ctor public FlowLiveDataApi26Kt();
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, java.time.Duration timeout);
+  }
+
+  public final class FlowLiveDataKt {
+    ctor public FlowLiveDataKt();
+    method public static <T> kotlinx.coroutines.flow.Flow<T> asFlow(androidx.lifecycle.LiveData<T>);
+    method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L);
+  }
+
+  public interface LiveDataScope<T> {
+    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;
+  }
+
+  public final class TransformationsKt {
+    ctor public TransformationsKt();
+    method public static inline <X> androidx.lifecycle.LiveData<X> distinctUntilChanged(androidx.lifecycle.LiveData<X>);
+    method public static inline <X, Y> androidx.lifecycle.LiveData<Y> map(androidx.lifecycle.LiveData<X>, kotlin.jvm.functions.Function1<? super X,? extends Y> transform);
+    method public static inline <X, Y> androidx.lifecycle.LiveData<Y> switchMap(androidx.lifecycle.LiveData<X>, kotlin.jvm.functions.Function1<? super X,? extends androidx.lifecycle.LiveData<Y>> transform);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt b/lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt
index 9dc2bee..26f3e49 100644
--- a/lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt
+++ b/lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt
@@ -11,6 +11,17 @@
     method public static <T> androidx.lifecycle.LiveData<T> liveData(kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
   }
 
+  public final class FlowLiveDataApi26Kt {
+    ctor public FlowLiveDataApi26Kt();
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, java.time.Duration timeout);
+  }
+
+  public final class FlowLiveDataKt {
+    ctor public FlowLiveDataKt();
+    method public static <T> kotlinx.coroutines.flow.Flow<T> asFlow(androidx.lifecycle.LiveData<T>);
+    method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L);
+  }
+
   public interface LiveDataScope<T> {
     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);
diff --git a/lifecycle/lifecycle-livedata-ktx/build.gradle b/lifecycle/lifecycle-livedata-ktx/build.gradle
index 6294159..cf0517c 100644
--- a/lifecycle/lifecycle-livedata-ktx/build.gradle
+++ b/lifecycle/lifecycle-livedata-ktx/build.gradle
@@ -41,12 +41,12 @@
     api(project(":lifecycle:lifecycle-livedata"))
     api(project(":lifecycle:lifecycle-livedata-core-ktx"))
     api(KOTLIN_STDLIB)
-    api(KOTLIN_COROUTINES_CORE)
+    api(KOTLIN_COROUTINES_CORE_PREVIEW)
     testImplementation(project(":lifecycle:lifecycle-runtime"))
     testImplementation("androidx.arch.core:core-testing:2.1.0-rc01")
     testImplementation(JUNIT)
     testImplementation(TRUTH)
-    testImplementation(KOTLIN_COROUTINES_TEST)
+    testImplementation(KOTLIN_COROUTINES_TEST_PREVIEW)
 }
 
 androidx {
diff --git a/lifecycle/lifecycle-livedata-ktx/src/main/java/androidx/lifecycle/FlowLiveData.kt b/lifecycle/lifecycle-livedata-ktx/src/main/java/androidx/lifecycle/FlowLiveData.kt
new file mode 100644
index 0000000..3b2c2f25
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/src/main/java/androidx/lifecycle/FlowLiveData.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.lifecycle
+
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.flow.flow
+import kotlin.coroutines.CoroutineContext
+import kotlin.coroutines.EmptyCoroutineContext
+
+/**
+ * Creates a LiveData that has values collected from the origin [Flow].
+ *
+ * The upstream flow collection starts when the returned [LiveData] becomes active
+ * ([LiveData.onActive]).
+ * If the [LiveData] becomes inactive ([LiveData.onInactive]) while the flow has not completed,
+ * the flow collection will be cancelled after [timeoutInMs] milliseconds unless the [LiveData]
+ * becomes active again before that timeout (to gracefully handle cases like Activity rotation).
+ *
+ * After a cancellation, if the [LiveData] becomes active again, the upstream flow collection will
+ * be re-executed.
+ *
+ * If the upstream flow completes successfully *or* is cancelled due to reasons other than
+ * [LiveData] becoming inactive, it *will not* be re-collected even after [LiveData] goes through
+ * active inactive cycle.
+ *
+ * If flow completes with an exception, then exception will be delivered to the
+ * [CoroutineExceptionHandler][kotlinx.coroutines.CoroutineExceptionHandler] of provided [context].
+ * By default [EmptyCoroutineContext] is used to so an exception will be delivered to main's
+ * thread [UncaughtExceptionHandler][Thread.UncaughtExceptionHandler]. If your flow upstream is
+ * expected to throw, you can use [catch operator][kotlinx.coroutines.flow.catch] on upstream flow
+ * to emit a helpful error object.
+ *
+ * @param context The CoroutineContext to collect the upstream flow in. Defaults to
+ * [EmptyCoroutineContext] combined with [Dispatchers.Main]
+ * @param timeoutInMs The timeout in ms before cancelling the block if there are no active observers
+ * ([LiveData.hasActiveObservers]. Defaults to [DEFAULT_TIMEOUT].
+ */
+fun <T> Flow<T>.asLiveData(
+    context: CoroutineContext = EmptyCoroutineContext,
+    timeoutInMs: Long = DEFAULT_TIMEOUT
+): LiveData<T> = liveData(context, timeoutInMs) {
+    collect {
+        emit(it)
+    }
+}
+
+/**
+ * Creates a [Flow] containing values dispatched by originating [LiveData]: at the start
+ * a flow collector receives the latest value held by LiveData and then observes LiveData updates.
+ *
+ * When a collection of the returned flow starts the originating [LiveData] becomes
+ * [active][LiveData.onActive]. Similarly, when a collection completes [LiveData] becomes
+ * [inactive][LiveData.onInactive].
+ *
+ * BackPressure: the returned flow is conflated. There is no mechanism to suspend an emission by
+ * LiveData due to a slow collector, so collector always gets the most recent value emitted.
+ */
+fun <T> LiveData<T>.asFlow(): Flow<T> = flow {
+    val channel = Channel<T>(Channel.CONFLATED)
+    val observer = Observer<T> {
+        channel.offer(it)
+    }
+    withContext(Dispatchers.Main) {
+        observeForever(observer)
+    }
+    try {
+        for (value in channel) {
+            emit(value)
+        }
+    } finally {
+        GlobalScope.launch(Dispatchers.Main) {
+            removeObserver(observer)
+        }
+    }
+}
\ No newline at end of file
diff --git a/lifecycle/lifecycle-livedata-ktx/src/main/java/androidx/lifecycle/FlowLiveDataApi26.kt b/lifecycle/lifecycle-livedata-ktx/src/main/java/androidx/lifecycle/FlowLiveDataApi26.kt
new file mode 100644
index 0000000..ac2643d
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/src/main/java/androidx/lifecycle/FlowLiveDataApi26.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.lifecycle
+
+import android.os.Build
+import androidx.annotation.RequiresApi
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.Flow
+import java.time.Duration
+import kotlin.coroutines.CoroutineContext
+import kotlin.coroutines.EmptyCoroutineContext
+
+/**
+ * Creates a LiveData that has values collected from the origin [Flow].
+ *
+ * The upstream flow collection starts when the returned [LiveData] becomes active
+ * ([LiveData.onActive]).
+ * If the [LiveData] becomes inactive ([LiveData.onInactive]) while the flow has not completed,
+ * the flow collection will be cancelled after [timeout] unless the [LiveData]
+ * becomes active again before that timeout (to gracefully handle cases like Activity rotation).
+ *
+ * After a cancellation, if the [LiveData] becomes active again, the upstream flow collection will
+ * be re-executed.
+ *
+ * If the upstream flow completes successfully *or* is cancelled due to reasons other than
+ * [LiveData] becoming inactive, it *will not* be re-collected even after [LiveData] goes through
+ * active inactive cycle.
+ *
+ * If flow completes with an exception, then exception will be delivered to the
+ * [CoroutineExceptionHandler][kotlinx.coroutines.CoroutineExceptionHandler] of provided [context].
+ * By default [EmptyCoroutineContext] is used to so an exception will be delivered to main's
+ * thread [UncaughtExceptionHandler][Thread.UncaughtExceptionHandler]. If your flow upstream is
+ * expected to throw, you can use [catch operator][kotlinx.coroutines.flow.catch] on upstream flow
+ * to emit a helpful error object.
+ *
+ * @param context The CoroutineContext to collect the upstream flow in. Defaults to
+ * [EmptyCoroutineContext] combined with [Dispatchers.Main]
+ * @param timeout The timeout in ms before cancelling the block if there are no active observers
+ * ([LiveData.hasActiveObservers]. Defaults to [DEFAULT_TIMEOUT].
+ */
+@RequiresApi(Build.VERSION_CODES.O)
+fun <T> Flow<T>.asLiveData(
+    context: CoroutineContext = EmptyCoroutineContext,
+    timeout: Duration
+): LiveData<T> = asLiveData(context, timeout.toMillis())
\ No newline at end of file
diff --git a/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/BuildLiveDataTest.kt b/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/BuildLiveDataTest.kt
index 2f53b3b..9e55611 100644
--- a/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/BuildLiveDataTest.kt
+++ b/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/BuildLiveDataTest.kt
@@ -16,95 +16,38 @@
 
 package androidx.lifecycle
 
-import androidx.arch.core.executor.ArchTaskExecutor
-import androidx.arch.core.executor.TaskExecutor
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CompletableDeferred
-import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineExceptionHandler
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.ObsoleteCoroutinesApi
-import kotlinx.coroutines.async
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
-import kotlinx.coroutines.test.TestCoroutineContext
-import kotlinx.coroutines.test.resetMain
-import kotlinx.coroutines.test.setMain
-import org.junit.After
-import org.junit.Before
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
 import java.time.Duration
 import java.util.concurrent.atomic.AtomicBoolean
 import java.util.concurrent.atomic.AtomicReference
-import kotlin.coroutines.ContinuationInterceptor
 import kotlin.coroutines.coroutineContext
 
-@ObsoleteCoroutinesApi
+@ExperimentalCoroutinesApi
 @RunWith(JUnit4::class)
 class BuildLiveDataTest {
-    @ObsoleteCoroutinesApi
-    private val mainContext = TestCoroutineContext("test-main-context")
-    private val mainScope = CoroutineScope(mainContext)
-    @ObsoleteCoroutinesApi
-    private val testContext = TestCoroutineContext("test-other-context")
-
-    @ExperimentalCoroutinesApi
-    @Before
-    fun initMain() {
-        lateinit var mainThread: Thread
-        runBlocking(mainContext) {
-            mainThread = Thread.currentThread()
-        }
-        Dispatchers.setMain(
-            mainContext[ContinuationInterceptor.Key] as CoroutineDispatcher
-        )
-        ArchTaskExecutor.getInstance().setDelegate(
-            object : TaskExecutor() {
-                override fun executeOnDiskIO(runnable: Runnable) {
-                    error("unsupported")
-                }
-
-                override fun postToMainThread(runnable: Runnable) {
-                    mainScope.launch {
-                        runnable.run()
-                    }
-                }
-
-                override fun isMainThread(): Boolean {
-                    return mainThread == Thread.currentThread()
-                }
-            }
-        )
-    }
-
-    @ExperimentalCoroutinesApi
-    @After
-    fun clear() {
-        advanceTimeBy(100000)
-        mainContext.assertExceptions("shouldn't have any exceptions") {
-            it.isEmpty()
-        }
-        testContext.assertExceptions("shouldn't have any exceptions") {
-            it.isEmpty()
-        }
-        ArchTaskExecutor.getInstance().setDelegate(null)
-        Dispatchers.resetMain()
-    }
+    @get:Rule
+    val scopes = ScopesRule()
+    private val mainScope = scopes.mainScope
+    private val testScope = scopes.testScope
 
     @Test
     fun oneShot() {
         val liveData = liveData {
             emit(3)
         }
-        triggerAllActions()
+        scopes.triggerAllActions()
         assertThat(liveData.value).isNull()
         liveData.addObserver().assertItems(3)
     }
@@ -122,12 +65,12 @@
             unsubscribe()
         }
         // trigger cancellation
-        mainContext.advanceTimeBy(100)
+        mainScope.advanceTimeBy(100)
         assertThat(ld.hasActiveObservers()).isFalse()
         ld.addObserver().apply {
-            triggerAllActions()
+            scopes.triggerAllActions()
             assertItems(2, 1, 2)
-            mainContext.advanceTimeBy(1001)
+            mainScope.advanceTimeBy(1001)
             assertItems(2, 1, 2, 3)
         }
     }
@@ -145,13 +88,13 @@
             unsubscribe()
         }
         // advance some but not enough to cover the delay
-        mainContext.advanceTimeBy(500)
+        mainScope.advanceTimeBy(500)
         assertThat(ld.hasActiveObservers()).isFalse()
         assertThat(ld.value).isEqualTo(2)
         ld.addObserver().apply {
             assertItems(2)
             // advance enough to cover the rest of the delay
-            mainContext.advanceTimeBy(501)
+            mainScope.advanceTimeBy(501)
             assertItems(2, 3)
         }
     }
@@ -173,12 +116,12 @@
             unsubscribe()
         }
         // advance some but not enough to cover the delay
-        mainContext.advanceTimeBy(4_000)
+        mainScope.advanceTimeBy(4_000)
         assertThat(running.isActive).isTrue()
         assertThat(ld.hasActiveObservers()).isFalse()
         assertThat(ld.value).isEqualTo(1)
         // advance time to finish
-        mainContext.advanceTimeBy(1_000)
+        mainScope.advanceTimeBy(1_000)
         // ensure it is not running anymore
         assertThat(running.isActive).isFalse()
         assertThat(ld.value).isEqualTo(1)
@@ -187,26 +130,26 @@
     @Test
     fun ignoreCancelledYields() {
         val cancelMutex = Mutex(true)
-        val ld = liveData(timeoutInMs = 0, context = testContext) {
+        val ld = liveData(timeoutInMs = 0, context = testScope.coroutineContext) {
             emit(1)
             cancelMutex.withLock {
                 emit(2)
             }
         }
         ld.addObserver().apply {
-            triggerAllActions()
+            scopes.triggerAllActions()
             assertItems(1)
             unsubscribe()
             cancelMutex.unlock()
         }
         // let cancellation take place
-        triggerAllActions()
+        scopes.triggerAllActions()
         // emit should immediately trigger cancellation to happen
         assertThat(ld.value).isEqualTo(1)
         assertThat(ld.hasActiveObservers()).isFalse()
         // now because it was cancelled, re-observing should dispatch 1,1,2
         ld.addObserver().apply {
-            triggerAllActions()
+            scopes.triggerAllActions()
             assertItems(1, 1, 2)
         }
     }
@@ -214,33 +157,33 @@
     @Test
     fun readLatestValue() {
         val latest = AtomicReference<Int?>()
-        val ld = liveData<Int>(testContext) {
+        val ld = liveData<Int>(testScope.coroutineContext) {
             latest.set(latestValue)
         }
-        runOnMain {
+        scopes.runOnMain {
             ld.value = 3
         }
         ld.addObserver()
-        triggerAllActions()
+        scopes.triggerAllActions()
         assertThat(latest.get()).isEqualTo(3)
     }
 
     @Test
     fun readLatestValue_readWithinBlock() {
         val latest = AtomicReference<Int?>()
-        val ld = liveData<Int>(testContext) {
+        val ld = liveData<Int>(testScope.coroutineContext) {
             emit(5)
             latest.set(latestValue)
         }
         ld.addObserver()
-        triggerAllActions()
+        scopes.triggerAllActions()
         assertThat(latest.get()).isEqualTo(5)
     }
 
     @Test
     fun readLatestValue_keepYieldedFromBefore() {
         val latest = AtomicReference<Int?>()
-        val ld = liveData<Int>(testContext, 10) {
+        val ld = liveData<Int>(testScope.coroutineContext, 10) {
             if (latestValue == null) {
                 emit(5)
                 delay(500000) // wait for cancellation
@@ -249,16 +192,16 @@
             latest.set(latestValue)
         }
         ld.addObserver().apply {
-            triggerAllActions()
+            scopes.triggerAllActions()
             assertItems(5)
             unsubscribe()
         }
-        triggerAllActions()
+        scopes.triggerAllActions()
         // wait for it to be cancelled
-        advanceTimeBy(10)
+        scopes.advanceTimeBy(10)
         assertThat(latest.get()).isNull()
         ld.addObserver()
-        triggerAllActions()
+        scopes.triggerAllActions()
         assertThat(latest.get()).isEqualTo(5)
     }
 
@@ -293,13 +236,13 @@
                 emit(it)
             }
         }
-        val ld = liveData(testContext) {
+        val ld = liveData(testScope.coroutineContext) {
             emitSource(odds)
             doneOddsYield.lock()
             emitSource(evens)
         }
         ld.addObserver().apply {
-            triggerAllActions()
+            scopes.triggerAllActions()
             assertItems(1, 3, 5, 7, 9, 2, 4, 6, 8, 10)
         }
     }
@@ -315,14 +258,14 @@
             delay(1)
             emit(-1)
         }
-        val ld = liveData(testContext) {
+        val ld = liveData(testScope.coroutineContext) {
             emitSource(odds)
             doneOddsYield.lock()
             emit(10)
         }
         ld.addObserver().apply {
-            triggerAllActions()
-            advanceTimeBy(100)
+            scopes.triggerAllActions()
+            scopes.advanceTimeBy(100)
             assertItems(1, 3, 5, 7, 9, 10)
         }
     }
@@ -339,10 +282,10 @@
         }
         val ld = liveData {
             val disposable = emitSource(odds)
-            triggerAllActions()
+            scopes.triggerAllActions()
             assertThat(odds.hasActiveObservers()).isEqualTo(true)
             disposable.dispose()
-            triggerAllActions()
+            scopes.triggerAllActions()
             assertThat(odds.hasActiveObservers()).isEqualTo(false)
             doneOddsYield.unlock()
         }
@@ -360,16 +303,16 @@
         }
         val ld = liveData {
             val disposable = emitSource(odds)
-            triggerAllActions()
+            scopes.triggerAllActions()
             disposable.dispose()
-            triggerAllActions()
+            scopes.triggerAllActions()
             assertThat(odds.hasActiveObservers()).isEqualTo(false)
             // add observer via side channel.
             (this as LiveDataScopeImpl<Int>).target.addSource(odds) {}
-            triggerAllActions()
+            scopes.triggerAllActions()
             // redispose previous one should not impact
             disposable.dispose()
-            triggerAllActions()
+            scopes.triggerAllActions()
             // still has the observer we added from the side channel
             assertThat(odds.hasActiveObservers()).isEqualTo(true)
         }
@@ -388,7 +331,7 @@
         val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
             exception.complete(throwable)
         }
-        val ld = liveData(testContext + exceptionHandler, 10) {
+        val ld = liveData(testScope.coroutineContext + exceptionHandler, 10) {
             if (exception.isActive) {
                 throw IllegalArgumentException("i like to fail")
             } else {
@@ -396,16 +339,16 @@
             }
         }
         ld.addObserver().apply {
-            triggerAllActions()
+            scopes.triggerAllActions()
             assertItems()
             runBlocking {
                 assertThat(exception.await()).hasMessageThat().contains("i like to fail")
             }
             unsubscribe()
         }
-        triggerAllActions()
+        scopes.triggerAllActions()
         ld.addObserver().apply {
-            triggerAllActions()
+            scopes.triggerAllActions()
             assertItems()
         }
     }
@@ -415,7 +358,7 @@
         val didCancel = AtomicBoolean(false)
         val unexpected = AtomicBoolean(false)
 
-        val ld = liveData<Int>(testContext, 10) {
+        val ld = liveData<Int>(testScope.coroutineContext, 10) {
             if (didCancel.compareAndSet(false, true)) {
                 coroutineContext.cancel()
             } else {
@@ -423,14 +366,14 @@
             }
         }
         ld.addObserver().apply {
-            triggerAllActions()
+            scopes.triggerAllActions()
             assertItems()
             unsubscribe()
         }
         assertThat(didCancel.get()).isTrue()
         ld.addObserver()
         // trigger cancelation
-        advanceTimeBy(11)
+        scopes.advanceTimeBy(11)
         assertThat(unexpected.get()).isFalse()
     }
 
@@ -442,7 +385,7 @@
         }
         val src = MutableLiveData<Int>()
         val ld = src.switchMap {
-            liveData(testContext + exceptionHandler) {
+            liveData(testScope.coroutineContext + exceptionHandler) {
                 if (exception.isActive) {
                     throw IllegalArgumentException("i like to fail")
                 } else {
@@ -452,69 +395,21 @@
         }
         ld.addObserver().apply {
             assertItems()
-            runOnMain {
+            scopes.runOnMain {
                 src.value = 1
             }
-            triggerAllActions()
+            scopes.triggerAllActions()
             runBlocking {
                 assertThat(exception.await()).hasMessageThat().contains("i like to fail")
             }
-            runOnMain {
+            scopes.runOnMain {
                 src.value = 2
             }
-            triggerAllActions()
+            scopes.triggerAllActions()
             assertItems(3)
         }
     }
 
-    private fun triggerAllActions() {
-        do {
-            mainContext.triggerActions()
-            testContext.triggerActions()
-            val allIdle = listOf(mainContext, testContext).all {
-                it.isIdle()
-            }
-        } while (!allIdle)
-    }
-
-    private fun advanceTimeBy(time: Long) {
-        mainContext.advanceTimeBy(time)
-        testContext.advanceTimeBy(time)
-        triggerAllActions()
-    }
-
-    private fun TestCoroutineContext.isIdle(): Boolean {
-        val queueField = this::class.java
-            .getDeclaredField("queue")
-        queueField.isAccessible = true
-        val queue = queueField.get(this)
-        val peekMethod = queue::class.java
-            .getDeclaredMethod("peek")
-        val nextTask = peekMethod.invoke(queue) ?: return true
-        val timeField = nextTask::class.java.getDeclaredField("time")
-        timeField.isAccessible = true
-        val time = timeField.getLong(nextTask)
-        return time > now()
-    }
-
-    private fun <T> runOnMain(block: () -> T): T {
-        return runBlocking {
-            val async = mainScope.async {
-                block()
-            }
-            mainContext.triggerActions()
-            async.await()
-        }
-    }
-
-    private fun <T> LiveData<T>.addObserver(): CollectingObserver<T> {
-        return runOnMain {
-            val observer = CollectingObserver(this)
-            observeForever(observer)
-            observer
-        }
-    }
-
     @Test
     fun multipleValuesAndObservers() {
         val ld = liveData {
@@ -526,20 +421,5 @@
         ld.addObserver().assertItems(4)
     }
 
-    inner class CollectingObserver<T>(
-        private val liveData: LiveData<T>
-    ) : Observer<T> {
-        private var items = mutableListOf<T>()
-        override fun onChanged(t: T) {
-            items.add(t)
-        }
-
-        fun assertItems(vararg expected: T) {
-            assertThat(items).containsExactly(*expected)
-        }
-
-        fun unsubscribe() = runOnMain {
-            liveData.removeObserver(this)
-        }
-    }
+    private fun <T> LiveData<T>.addObserver() = this.addObserver(scopes)
 }
\ No newline at end of file
diff --git a/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/FlowAsLiveDataTest.kt b/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/FlowAsLiveDataTest.kt
new file mode 100644
index 0000000..d12c446
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/FlowAsLiveDataTest.kt
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.lifecycle
+
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.CoroutineExceptionHandler
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import java.time.Duration
+import java.util.concurrent.atomic.AtomicBoolean
+import kotlin.coroutines.coroutineContext
+
+@ExperimentalCoroutinesApi
+@RunWith(JUnit4::class)
+class FlowAsLiveDataTest {
+    @get:Rule
+    val scopes = ScopesRule()
+    private val mainScope = scopes.mainScope
+    private val testScope = scopes.testScope
+
+    private fun <T> LiveData<T>.addObserver() = this.addObserver(scopes)
+
+    @Test
+    fun oneShot() {
+        val liveData = flowOf(3).asLiveData()
+        scopes.triggerAllActions()
+        assertThat(liveData.value).isNull()
+        liveData.addObserver().assertItems(3)
+    }
+
+    @Test
+    fun removeObserverInBetween() {
+        val ld = flow {
+                emit(1)
+                emit(2)
+                delay(1000)
+                emit(3)
+        }.asLiveData(timeoutInMs = 10)
+
+        ld.addObserver().apply {
+            assertItems(1, 2)
+            unsubscribe()
+        }
+        // trigger cancellation
+        mainScope.advanceTimeBy(100)
+        assertThat(ld.hasActiveObservers()).isFalse()
+        ld.addObserver().apply {
+            scopes.triggerAllActions()
+            assertItems(2, 1, 2)
+            mainScope.advanceTimeBy(1001)
+            assertItems(2, 1, 2, 3)
+        }
+    }
+
+    @Test
+    fun callbackFlow_cancelled() {
+        var closeCalled = false
+        val ld = callbackFlow {
+            testScope.launch {
+                offer(1)
+                offer(2)
+                delay(1000)
+                offer(3)
+            }
+            awaitClose {
+                closeCalled = true
+            }
+        }.asLiveData(timeoutInMs = 10)
+
+        ld.addObserver().apply {
+            scopes.triggerAllActions()
+            assertItems(1, 2)
+            unsubscribe()
+        }
+        assertThat(closeCalled).isFalse()
+        // trigger cancellation
+        mainScope.advanceTimeBy(100)
+        assertThat(ld.hasActiveObservers()).isFalse()
+        assertThat(closeCalled).isTrue()
+        ld.addObserver().apply {
+            scopes.triggerAllActions()
+            assertItems(2, 1, 2)
+            scopes.advanceTimeBy(1001)
+            assertItems(2, 1, 2, 3)
+        }
+    }
+
+    @Test
+    fun removeObserverInBetween_largeTimeout() {
+        val ld = flow {
+            emit(1)
+            emit(2)
+            delay(1000)
+            emit(3)
+        }.asLiveData(timeoutInMs = 10000)
+
+        ld.addObserver().apply {
+            assertItems(1, 2)
+            unsubscribe()
+        }
+        // advance some but not enough to cover the delay
+        mainScope.advanceTimeBy(500)
+        assertThat(ld.hasActiveObservers()).isFalse()
+        assertThat(ld.value).isEqualTo(2)
+        ld.addObserver().apply {
+            assertItems(2)
+            // advance enough to cover the rest of the delay
+            mainScope.advanceTimeBy(501)
+            assertItems(2, 3)
+        }
+    }
+
+    @Test
+    fun timeoutViaDuration() {
+        val running = CompletableDeferred<Unit>()
+        val ld = flow {
+            try {
+                emit(1)
+                delay(5_001)
+                emit(2)
+            } finally {
+                running.complete(Unit)
+            }
+        }.asLiveData(timeout = Duration.ofSeconds(5))
+
+        ld.addObserver().apply {
+            assertItems(1)
+            unsubscribe()
+        }
+        // advance some but not enough to cover the delay
+        mainScope.advanceTimeBy(4_000)
+        assertThat(running.isActive).isTrue()
+        assertThat(ld.hasActiveObservers()).isFalse()
+        assertThat(ld.value).isEqualTo(1)
+        // advance time to finish
+        mainScope.advanceTimeBy(1_000)
+        // ensure it is not running anymore
+        assertThat(running.isActive).isFalse()
+        assertThat(ld.value).isEqualTo(1)
+    }
+
+    @Test
+    fun flowThrows() {
+        // use an exception handler instead of the test context exception handler to ensure that
+        // we do not re-run the block if its exception is gracefully caught
+        // TODO should we consider doing that ? But if we do, what is the rule? do we retry when
+        // it becomes active again or do we retry ourselves? better no do anything to be consistent.
+        val exception = CompletableDeferred<Throwable>()
+        val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
+            exception.complete(throwable)
+        }
+        val ld = flow {
+            if (exception.isActive) {
+                throw IllegalArgumentException("i like to fail")
+            } else {
+                emit(3)
+            }
+        }.asLiveData(testScope.coroutineContext + exceptionHandler, 10)
+        ld.addObserver().apply {
+            scopes.triggerAllActions()
+            assertItems()
+            runBlocking {
+                assertThat(exception.await()).hasMessageThat().contains("i like to fail")
+            }
+            unsubscribe()
+        }
+        scopes.triggerAllActions()
+        ld.addObserver().apply {
+            scopes.triggerAllActions()
+            assertItems()
+        }
+    }
+
+    @Test
+    fun flowCancelsItself() {
+        val didCancel = AtomicBoolean(false)
+        val unexpected = AtomicBoolean(false)
+
+        val ld = flow<Int> {
+            if (didCancel.compareAndSet(false, true)) {
+                coroutineContext.cancel()
+            } else {
+                unexpected.set(true)
+            }
+        }.asLiveData(testScope.coroutineContext, 10)
+        ld.addObserver().apply {
+            scopes.triggerAllActions()
+            assertItems()
+            unsubscribe()
+        }
+        assertThat(didCancel.get()).isTrue()
+        ld.addObserver()
+        // trigger cancelation
+        scopes.advanceTimeBy(11)
+        assertThat(unexpected.get()).isFalse()
+    }
+
+    @Test
+    fun multipleValuesAndObservers() {
+        val ld = flowOf(3, 4).asLiveData()
+        ld.addObserver().assertItems(3, 4)
+        // re-observe, get latest value only
+        ld.addObserver().assertItems(4)
+    }
+}
\ No newline at end of file
diff --git a/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/LiveDataAsFlowTest.kt b/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/LiveDataAsFlowTest.kt
new file mode 100644
index 0000000..bd7bc0e
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/LiveDataAsFlowTest.kt
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.lifecycle
+
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.take
+import kotlinx.coroutines.flow.toList
+import kotlinx.coroutines.launch
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@ExperimentalCoroutinesApi
+@RunWith(JUnit4::class)
+class LiveDataAsFlowTest {
+    @get:Rule
+    val scopes = ScopesRule()
+    private val mainScope = scopes.mainScope
+    private val testScope = scopes.testScope
+
+    @Test
+    fun checkCancellation() {
+        val ld = MutableLiveData<Int>()
+        val flow = ld.asFlow()
+        scopes.triggerAllActions()
+        // check that flow creation didn't make livedata active
+        assertThat(ld.hasActiveObservers()).isFalse()
+        val job = testScope.launch { flow.collect { } }
+        scopes.triggerAllActions()
+        // collection started there should be an active observer
+        assertThat(ld.hasActiveObservers()).isTrue()
+        job.cancel()
+        scopes.triggerAllActions()
+        // job with collection was cancelled, so no active observers again
+        assertThat(ld.hasActiveObservers()).isFalse()
+    }
+
+    @Test
+    fun dispatchMultiple() {
+        val ld = MutableLiveData<Int>()
+        val collected = mutableListOf<Int>()
+        val job = testScope.launch {
+            ld.asFlow().collect {
+                delay(100)
+                collected.add(it)
+            }
+        }
+        mainScope.launch {
+            ld.value = 1
+            delay(1000)
+            ld.value = 2
+            ld.value = 3
+            ld.value = 4
+        }
+        scopes.triggerAllActions()
+        scopes.advanceTimeBy(200)
+        assertThat(collected).isEqualTo(listOf(1))
+        scopes.advanceTimeBy(800)
+        assertThat(collected).isEqualTo(listOf(1, 2, 4))
+        job.cancel()
+        scopes.triggerAllActions()
+        assertThat(ld.hasActiveObservers()).isFalse()
+    }
+
+    @Test
+    fun reusingFlow() {
+        val ld = MutableLiveData<Int>()
+        val flow = ld.asFlow()
+        mainScope.launch { ld.value = 1 }
+        val firstCollection = testScope.launch {
+            assertThat(flow.first()).isEqualTo(1)
+        }
+        scopes.triggerAllActions()
+        // check that we're done with previous collection
+        assertThat(ld.hasActiveObservers()).isFalse()
+        assertThat(firstCollection.isCompleted).isTrue()
+
+        val secondCollection = testScope.launch {
+            assertThat(flow.take(2).toList()).isEqualTo(listOf(1, 2))
+        }
+        scopes.triggerAllActions()
+        assertThat(ld.hasActiveObservers()).isTrue()
+        mainScope.launch { ld.value = 2 }
+        scopes.triggerAllActions()
+        assertThat(secondCollection.isCompleted).isTrue()
+        assertThat(ld.hasActiveObservers()).isFalse()
+    }
+
+    @Test
+    fun twoFlowsInParallel() {
+        val ld = MutableLiveData<Int>()
+        val flowA = ld.asFlow()
+        val flowB = ld.asFlow()
+        assertThat(ld.hasActiveObservers()).isFalse()
+        val jobA = testScope.launch {
+            assertThat(flowA.first()).isEqualTo(1)
+        }
+        val jobB = testScope.launch {
+            assertThat(flowB.take(2).toList()).isEqualTo(listOf(1, 2))
+        }
+        scopes.triggerAllActions()
+        assertThat(ld.hasActiveObservers())
+
+        mainScope.launch { ld.value = 1 }
+        scopes.triggerAllActions()
+        assertThat(ld.hasActiveObservers()).isTrue()
+        assertThat(jobA.isCompleted).isTrue()
+        assertThat(jobB.isCompleted).isFalse()
+        mainScope.launch { ld.value = 2 }
+        scopes.triggerAllActions()
+        assertThat(ld.hasActiveObservers()).isFalse()
+        assertThat(jobB.isCompleted).isTrue()
+    }
+}
\ No newline at end of file
diff --git a/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/ScopesRule.kt b/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/ScopesRule.kt
new file mode 100644
index 0000000..9d96fb7
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/ScopesRule.kt
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.lifecycle
+
+import androidx.arch.core.executor.ArchTaskExecutor
+import androidx.arch.core.executor.TaskExecutor
+import com.google.common.truth.Truth
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.async
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.TestCoroutineDispatcher
+import kotlinx.coroutines.test.TestCoroutineScope
+import kotlinx.coroutines.test.resetMain
+import kotlinx.coroutines.test.setMain
+import org.junit.rules.TestWatcher
+import org.junit.runner.Description
+
+@ExperimentalCoroutinesApi
+class ScopesRule : TestWatcher() {
+    private val mainDispatcher = TestCoroutineDispatcher()
+    val mainScope = TestCoroutineScope(mainDispatcher)
+
+    private val testDispatcher = TestCoroutineDispatcher()
+    val testScope = TestCoroutineScope(testDispatcher)
+
+    override fun starting(description: Description?) {
+        Dispatchers.setMain(mainDispatcher)
+        ArchTaskExecutor.getInstance().setDelegate(
+            object : TaskExecutor() {
+                override fun executeOnDiskIO(runnable: Runnable) {
+                    error("unsupported")
+                }
+
+                override fun postToMainThread(runnable: Runnable) {
+                    mainScope.launch {
+                        runnable.run()
+                    }
+                }
+
+                override fun isMainThread(): Boolean {
+                    // we have only one thread in this test.
+                    return true
+                }
+            }
+        )
+        // manually roll the time
+        mainScope.pauseDispatcher()
+        testScope.pauseDispatcher()
+    }
+
+    override fun finished(description: Description?) {
+        advanceTimeBy(100000)
+        mainScope.cleanupTestCoroutines()
+        testScope.cleanupTestCoroutines()
+        ArchTaskExecutor.getInstance().setDelegate(null)
+        Dispatchers.resetMain()
+    }
+
+    fun advanceTimeBy(time: Long) {
+        mainScope.advanceTimeBy(time)
+        testScope.advanceTimeBy(time)
+        triggerAllActions()
+    }
+
+    fun triggerAllActions() {
+        do {
+            mainScope.runCurrent()
+            testScope.runCurrent()
+            val allIdle = listOf(mainDispatcher, testDispatcher).all {
+                it.isIdle()
+            }
+        } while (!allIdle)
+    }
+
+    fun <T> runOnMain(block: () -> T): T {
+        return runBlocking {
+            val async = mainScope.async {
+                block()
+            }
+            mainScope.runCurrent()
+            async.await()
+        }
+    }
+
+    private fun TestCoroutineDispatcher.isIdle(): Boolean {
+        val queueField = this::class.java
+            .getDeclaredField("queue")
+        queueField.isAccessible = true
+        val queue = queueField.get(this)
+        val peekMethod = queue::class.java
+            .getDeclaredMethod("peek")
+        val nextTask = peekMethod.invoke(queue) ?: return true
+        val timeField = nextTask::class.java.getDeclaredField("time")
+        timeField.isAccessible = true
+        val time = timeField.getLong(nextTask)
+        return time > testDispatcher.currentTime
+    }
+}
+
+@ExperimentalCoroutinesApi
+fun <T> LiveData<T>.addObserver(scopes: ScopesRule): CollectingObserver<T> {
+    return scopes.runOnMain {
+        val observer = CollectingObserver(this, scopes)
+        observeForever(observer)
+        observer
+    }
+}
+
+@ExperimentalCoroutinesApi
+class CollectingObserver<T>(
+    private val liveData: LiveData<T>,
+    private val scopes: ScopesRule
+) : Observer<T> {
+    private var items = mutableListOf<T>()
+    override fun onChanged(t: T) {
+        items.add(t)
+    }
+
+    fun assertItems(vararg expected: T) {
+        Truth.assertThat(items).containsExactly(*expected)
+    }
+
+    fun unsubscribe() = scopes.runOnMain {
+        liveData.removeObserver(this)
+    }
+}
\ No newline at end of file
diff --git a/lifecycle/lifecycle-livedata/api/2.2.0-alpha04.txt b/lifecycle/lifecycle-livedata/api/2.2.0-alpha04.txt
new file mode 100644
index 0000000..b9a2837
--- /dev/null
+++ b/lifecycle/lifecycle-livedata/api/2.2.0-alpha04.txt
@@ -0,0 +1,17 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public class MediatorLiveData<T> extends androidx.lifecycle.MutableLiveData<T> {
+    ctor public MediatorLiveData();
+    method @MainThread public <S> void addSource(androidx.lifecycle.LiveData<S!>, androidx.lifecycle.Observer<? super S>);
+    method @MainThread public <S> void removeSource(androidx.lifecycle.LiveData<S!>);
+  }
+
+  public class Transformations {
+    method @MainThread public static <X> androidx.lifecycle.LiveData<X!> distinctUntilChanged(androidx.lifecycle.LiveData<X!>);
+    method @MainThread public static <X, Y> androidx.lifecycle.LiveData<Y!> map(androidx.lifecycle.LiveData<X!>, androidx.arch.core.util.Function<X!,Y!>);
+    method @MainThread public static <X, Y> androidx.lifecycle.LiveData<Y!> switchMap(androidx.lifecycle.LiveData<X!>, androidx.arch.core.util.Function<X!,androidx.lifecycle.LiveData<Y!>!>);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/lifecycle/lifecycle-livedata/api/res-2.2.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to lifecycle/lifecycle-livedata/api/res-2.2.0-alpha04.txt
diff --git a/lifecycle/lifecycle-livedata/api/restricted_2.2.0-alpha04.txt b/lifecycle/lifecycle-livedata/api/restricted_2.2.0-alpha04.txt
new file mode 100644
index 0000000..5d2ddfa
--- /dev/null
+++ b/lifecycle/lifecycle-livedata/api/restricted_2.2.0-alpha04.txt
@@ -0,0 +1,25 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class ComputableLiveData<T> {
+    ctor public ComputableLiveData();
+    ctor public ComputableLiveData(java.util.concurrent.Executor);
+    method @WorkerThread protected abstract T! compute();
+    method public androidx.lifecycle.LiveData<T!> getLiveData();
+    method public void invalidate();
+  }
+
+  public class MediatorLiveData<T> extends androidx.lifecycle.MutableLiveData<T> {
+    ctor public MediatorLiveData();
+    method @MainThread public <S> void addSource(androidx.lifecycle.LiveData<S!>, androidx.lifecycle.Observer<? super S>);
+    method @MainThread public <S> void removeSource(androidx.lifecycle.LiveData<S!>);
+  }
+
+  public class Transformations {
+    method @MainThread public static <X> androidx.lifecycle.LiveData<X!> distinctUntilChanged(androidx.lifecycle.LiveData<X!>);
+    method @MainThread public static <X, Y> androidx.lifecycle.LiveData<Y!> map(androidx.lifecycle.LiveData<X!>, androidx.arch.core.util.Function<X!,Y!>);
+    method @MainThread public static <X, Y> androidx.lifecycle.LiveData<Y!> switchMap(androidx.lifecycle.LiveData<X!>, androidx.arch.core.util.Function<X!,androidx.lifecycle.LiveData<Y!>!>);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-process/api/2.2.0-alpha04.txt b/lifecycle/lifecycle-process/api/2.2.0-alpha04.txt
new file mode 100644
index 0000000..beea619
--- /dev/null
+++ b/lifecycle/lifecycle-process/api/2.2.0-alpha04.txt
@@ -0,0 +1,10 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public class ProcessLifecycleOwner implements androidx.lifecycle.LifecycleOwner {
+    method public static androidx.lifecycle.LifecycleOwner get();
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/lifecycle/lifecycle-process/api/res-2.2.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to lifecycle/lifecycle-process/api/res-2.2.0-alpha04.txt
diff --git a/lifecycle/lifecycle-process/api/restricted_2.2.0-alpha04.txt b/lifecycle/lifecycle-process/api/restricted_2.2.0-alpha04.txt
new file mode 100644
index 0000000..ba282a3
--- /dev/null
+++ b/lifecycle/lifecycle-process/api/restricted_2.2.0-alpha04.txt
@@ -0,0 +1,20 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public class ProcessLifecycleOwner implements androidx.lifecycle.LifecycleOwner {
+    method public static androidx.lifecycle.LifecycleOwner get();
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ProcessLifecycleOwnerInitializer extends android.content.ContentProvider {
+    ctor public ProcessLifecycleOwnerInitializer();
+    method public int delete(android.net.Uri, String!, String![]!);
+    method public String? getType(android.net.Uri);
+    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![]!);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-reactivestreams-ktx/api/2.2.0-alpha04.txt b/lifecycle/lifecycle-reactivestreams-ktx/api/2.2.0-alpha04.txt
new file mode 100644
index 0000000..659d07d
--- /dev/null
+++ b/lifecycle/lifecycle-reactivestreams-ktx/api/2.2.0-alpha04.txt
@@ -0,0 +1,11 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public final class LiveDataReactiveSteamsKt {
+    ctor public LiveDataReactiveSteamsKt();
+    method public static inline <T> androidx.lifecycle.LiveData<T> toLiveData(org.reactivestreams.Publisher<T>);
+    method public static inline <T> org.reactivestreams.Publisher<T> toPublisher(androidx.lifecycle.LiveData<T>, androidx.lifecycle.LifecycleOwner lifecycle);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/lifecycle/lifecycle-reactivestreams-ktx/api/res-2.2.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to lifecycle/lifecycle-reactivestreams-ktx/api/res-2.2.0-alpha04.txt
diff --git a/lifecycle/lifecycle-reactivestreams-ktx/api/restricted_2.2.0-alpha04.txt b/lifecycle/lifecycle-reactivestreams-ktx/api/restricted_2.2.0-alpha04.txt
new file mode 100644
index 0000000..659d07d
--- /dev/null
+++ b/lifecycle/lifecycle-reactivestreams-ktx/api/restricted_2.2.0-alpha04.txt
@@ -0,0 +1,11 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public final class LiveDataReactiveSteamsKt {
+    ctor public LiveDataReactiveSteamsKt();
+    method public static inline <T> androidx.lifecycle.LiveData<T> toLiveData(org.reactivestreams.Publisher<T>);
+    method public static inline <T> org.reactivestreams.Publisher<T> toPublisher(androidx.lifecycle.LiveData<T>, androidx.lifecycle.LifecycleOwner lifecycle);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-reactivestreams/api/2.2.0-alpha04.txt b/lifecycle/lifecycle-reactivestreams/api/2.2.0-alpha04.txt
new file mode 100644
index 0000000..518fc95
--- /dev/null
+++ b/lifecycle/lifecycle-reactivestreams/api/2.2.0-alpha04.txt
@@ -0,0 +1,10 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public final class LiveDataReactiveStreams {
+    method public static <T> androidx.lifecycle.LiveData<T!> fromPublisher(org.reactivestreams.Publisher<T!>);
+    method public static <T> org.reactivestreams.Publisher<T!> toPublisher(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.LiveData<T!>);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/lifecycle/lifecycle-reactivestreams/api/res-2.2.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to lifecycle/lifecycle-reactivestreams/api/res-2.2.0-alpha04.txt
diff --git a/lifecycle/lifecycle-reactivestreams/api/restricted_2.2.0-alpha04.txt b/lifecycle/lifecycle-reactivestreams/api/restricted_2.2.0-alpha04.txt
new file mode 100644
index 0000000..518fc95
--- /dev/null
+++ b/lifecycle/lifecycle-reactivestreams/api/restricted_2.2.0-alpha04.txt
@@ -0,0 +1,10 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public final class LiveDataReactiveStreams {
+    method public static <T> androidx.lifecycle.LiveData<T!> fromPublisher(org.reactivestreams.Publisher<T!>);
+    method public static <T> org.reactivestreams.Publisher<T!> toPublisher(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.LiveData<T!>);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-runtime-ktx/api/2.2.0-alpha04.txt b/lifecycle/lifecycle-runtime-ktx/api/2.2.0-alpha04.txt
new file mode 100644
index 0000000..8156596
--- /dev/null
+++ b/lifecycle/lifecycle-runtime-ktx/api/2.2.0-alpha04.txt
@@ -0,0 +1,32 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public abstract class LifecycleCoroutineScope implements kotlinx.coroutines.CoroutineScope {
+    method public final kotlinx.coroutines.Job launchWhenCreated(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method public final kotlinx.coroutines.Job launchWhenResumed(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method public final kotlinx.coroutines.Job launchWhenStarted(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+  }
+
+  public final class LifecycleKt {
+    ctor public LifecycleKt();
+    method public static androidx.lifecycle.LifecycleCoroutineScope getCoroutineScope(androidx.lifecycle.Lifecycle);
+  }
+
+  public final class LifecycleOwnerKt {
+    ctor public LifecycleOwnerKt();
+    method public static androidx.lifecycle.LifecycleCoroutineScope getLifecycleScope(androidx.lifecycle.LifecycleOwner);
+  }
+
+  public final class PausingDispatcherKt {
+    ctor public 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> 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);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-runtime-ktx/api/api_lint.ignore b/lifecycle/lifecycle-runtime-ktx/api/api_lint.ignore
new file mode 100644
index 0000000..51b3d63
--- /dev/null
+++ b/lifecycle/lifecycle-runtime-ktx/api/api_lint.ignore
@@ -0,0 +1,15 @@
+// Baseline format: 1.0
+MissingNullability: androidx.lifecycle.PausingDispatcherKt#whenCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?>, kotlin.coroutines.Continuation<? super T>):
+    Missing nullability on method `whenCreated` return
+MissingNullability: androidx.lifecycle.PausingDispatcherKt#whenCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?>, kotlin.coroutines.Continuation<? super T>):
+    Missing nullability on method `whenCreated` return
+MissingNullability: androidx.lifecycle.PausingDispatcherKt#whenResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?>, kotlin.coroutines.Continuation<? super T>):
+    Missing nullability on method `whenResumed` return
+MissingNullability: androidx.lifecycle.PausingDispatcherKt#whenResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?>, kotlin.coroutines.Continuation<? super T>):
+    Missing nullability on method `whenResumed` return
+MissingNullability: androidx.lifecycle.PausingDispatcherKt#whenStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?>, kotlin.coroutines.Continuation<? super T>):
+    Missing nullability on method `whenStarted` return
+MissingNullability: androidx.lifecycle.PausingDispatcherKt#whenStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?>, kotlin.coroutines.Continuation<? super T>):
+    Missing nullability on method `whenStarted` return
+MissingNullability: androidx.lifecycle.PausingDispatcherKt#whenStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?>, kotlin.coroutines.Continuation<? super T>):
+    Missing nullability on method `whenStateAtLeast` return
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/lifecycle/lifecycle-runtime-ktx/api/res-2.2.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to lifecycle/lifecycle-runtime-ktx/api/res-2.2.0-alpha04.txt
diff --git a/lifecycle/lifecycle-runtime-ktx/api/restricted_2.2.0-alpha04.txt b/lifecycle/lifecycle-runtime-ktx/api/restricted_2.2.0-alpha04.txt
new file mode 100644
index 0000000..8156596
--- /dev/null
+++ b/lifecycle/lifecycle-runtime-ktx/api/restricted_2.2.0-alpha04.txt
@@ -0,0 +1,32 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public abstract class LifecycleCoroutineScope implements kotlinx.coroutines.CoroutineScope {
+    method public final kotlinx.coroutines.Job launchWhenCreated(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method public final kotlinx.coroutines.Job launchWhenResumed(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method public final kotlinx.coroutines.Job launchWhenStarted(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+  }
+
+  public final class LifecycleKt {
+    ctor public LifecycleKt();
+    method public static androidx.lifecycle.LifecycleCoroutineScope getCoroutineScope(androidx.lifecycle.Lifecycle);
+  }
+
+  public final class LifecycleOwnerKt {
+    ctor public LifecycleOwnerKt();
+    method public static androidx.lifecycle.LifecycleCoroutineScope getLifecycleScope(androidx.lifecycle.LifecycleOwner);
+  }
+
+  public final class PausingDispatcherKt {
+    ctor public 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> 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);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-runtime/api/2.2.0-alpha04.txt b/lifecycle/lifecycle-runtime/api/2.2.0-alpha04.txt
new file mode 100644
index 0000000..0a652c0
--- /dev/null
+++ b/lifecycle/lifecycle-runtime/api/2.2.0-alpha04.txt
@@ -0,0 +1,20 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public class LifecycleRegistry extends androidx.lifecycle.Lifecycle {
+    ctor public LifecycleRegistry(androidx.lifecycle.LifecycleOwner);
+    method public void addObserver(androidx.lifecycle.LifecycleObserver);
+    method public androidx.lifecycle.Lifecycle.State getCurrentState();
+    method public int getObserverCount();
+    method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event);
+    method @Deprecated @MainThread public void markState(androidx.lifecycle.Lifecycle.State);
+    method public void removeObserver(androidx.lifecycle.LifecycleObserver);
+    method @MainThread public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+  }
+
+  @Deprecated public interface LifecycleRegistryOwner extends androidx.lifecycle.LifecycleOwner {
+    method @Deprecated public androidx.lifecycle.LifecycleRegistry getLifecycle();
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/lifecycle/lifecycle-runtime/api/res-2.2.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to lifecycle/lifecycle-runtime/api/res-2.2.0-alpha04.txt
diff --git a/lifecycle/lifecycle-runtime/api/restricted_2.2.0-alpha04.txt b/lifecycle/lifecycle-runtime/api/restricted_2.2.0-alpha04.txt
new file mode 100644
index 0000000..7d16ff4
--- /dev/null
+++ b/lifecycle/lifecycle-runtime/api/restricted_2.2.0-alpha04.txt
@@ -0,0 +1,31 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public class LifecycleRegistry extends androidx.lifecycle.Lifecycle {
+    ctor public LifecycleRegistry(androidx.lifecycle.LifecycleOwner);
+    method public void addObserver(androidx.lifecycle.LifecycleObserver);
+    method public androidx.lifecycle.Lifecycle.State getCurrentState();
+    method public int getObserverCount();
+    method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event);
+    method @Deprecated @MainThread public void markState(androidx.lifecycle.Lifecycle.State);
+    method public void removeObserver(androidx.lifecycle.LifecycleObserver);
+    method @MainThread public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+  }
+
+  @Deprecated public interface LifecycleRegistryOwner extends androidx.lifecycle.LifecycleOwner {
+    method @Deprecated public androidx.lifecycle.LifecycleRegistry getLifecycle();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ReportFragment extends android.app.Fragment {
+    ctor public ReportFragment();
+    method public static void injectIfNeededIn(android.app.Activity!);
+    method public void onActivityCreated(android.os.Bundle!);
+    method public void onDestroy();
+    method public void onPause();
+    method public void onResume();
+    method public void onStart();
+    method public void onStop();
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-service/api/2.2.0-alpha04.txt b/lifecycle/lifecycle-service/api/2.2.0-alpha04.txt
new file mode 100644
index 0000000..e3c2893
--- /dev/null
+++ b/lifecycle/lifecycle-service/api/2.2.0-alpha04.txt
@@ -0,0 +1,21 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public class LifecycleService extends android.app.Service implements androidx.lifecycle.LifecycleOwner {
+    ctor public LifecycleService();
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method @CallSuper public android.os.IBinder? onBind(android.content.Intent);
+    method @CallSuper public void onStart(android.content.Intent?, int);
+  }
+
+  public class ServiceLifecycleDispatcher {
+    ctor public ServiceLifecycleDispatcher(androidx.lifecycle.LifecycleOwner);
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method public void onServicePreSuperOnBind();
+    method public void onServicePreSuperOnCreate();
+    method public void onServicePreSuperOnDestroy();
+    method public void onServicePreSuperOnStart();
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/lifecycle/lifecycle-service/api/res-2.2.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to lifecycle/lifecycle-service/api/res-2.2.0-alpha04.txt
diff --git a/lifecycle/lifecycle-service/api/restricted_2.2.0-alpha04.txt b/lifecycle/lifecycle-service/api/restricted_2.2.0-alpha04.txt
new file mode 100644
index 0000000..e3c2893
--- /dev/null
+++ b/lifecycle/lifecycle-service/api/restricted_2.2.0-alpha04.txt
@@ -0,0 +1,21 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public class LifecycleService extends android.app.Service implements androidx.lifecycle.LifecycleOwner {
+    ctor public LifecycleService();
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method @CallSuper public android.os.IBinder? onBind(android.content.Intent);
+    method @CallSuper public void onStart(android.content.Intent?, int);
+  }
+
+  public class ServiceLifecycleDispatcher {
+    ctor public ServiceLifecycleDispatcher(androidx.lifecycle.LifecycleOwner);
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method public void onServicePreSuperOnBind();
+    method public void onServicePreSuperOnCreate();
+    method public void onServicePreSuperOnDestroy();
+    method public void onServicePreSuperOnStart();
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-viewmodel-ktx/api/2.2.0-alpha04.txt b/lifecycle/lifecycle-viewmodel-ktx/api/2.2.0-alpha04.txt
new file mode 100644
index 0000000..2386744
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-ktx/api/2.2.0-alpha04.txt
@@ -0,0 +1,22 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public final class ViewModelKt {
+    ctor public ViewModelKt();
+    method public static kotlinx.coroutines.CoroutineScope getViewModelScope(androidx.lifecycle.ViewModel);
+  }
+
+  public final class ViewModelLazy<VM extends androidx.lifecycle.ViewModel> implements kotlin.Lazy<VM> {
+    ctor public ViewModelLazy(kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory> factoryProducer);
+    method public VM getValue();
+    method public boolean isInitialized();
+    property public VM value;
+  }
+
+  public final class ViewModelProviderKt {
+    ctor public ViewModelProviderKt();
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> VM get(androidx.lifecycle.ViewModelProvider);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/lifecycle/lifecycle-viewmodel-ktx/api/res-2.2.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to lifecycle/lifecycle-viewmodel-ktx/api/res-2.2.0-alpha04.txt
diff --git a/lifecycle/lifecycle-viewmodel-ktx/api/restricted_2.2.0-alpha04.txt b/lifecycle/lifecycle-viewmodel-ktx/api/restricted_2.2.0-alpha04.txt
new file mode 100644
index 0000000..2386744
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-ktx/api/restricted_2.2.0-alpha04.txt
@@ -0,0 +1,22 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public final class ViewModelKt {
+    ctor public ViewModelKt();
+    method public static kotlinx.coroutines.CoroutineScope getViewModelScope(androidx.lifecycle.ViewModel);
+  }
+
+  public final class ViewModelLazy<VM extends androidx.lifecycle.ViewModel> implements kotlin.Lazy<VM> {
+    ctor public ViewModelLazy(kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory> factoryProducer);
+    method public VM getValue();
+    method public boolean isInitialized();
+    property public VM value;
+  }
+
+  public final class ViewModelProviderKt {
+    ctor public ViewModelProviderKt();
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> VM get(androidx.lifecycle.ViewModelProvider);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/api/1.0.0-alpha04.txt b/lifecycle/lifecycle-viewmodel-savedstate/api/1.0.0-alpha04.txt
new file mode 100644
index 0000000..8bd77f2
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-savedstate/api/1.0.0-alpha04.txt
@@ -0,0 +1,29 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public abstract class AbstractSavedStateViewModelFactory implements androidx.lifecycle.ViewModelProvider.Factory {
+    ctor public AbstractSavedStateViewModelFactory(androidx.savedstate.SavedStateRegistryOwner, android.os.Bundle?);
+    method public final <T extends androidx.lifecycle.ViewModel> T create(Class<T!>);
+    method protected abstract <T extends androidx.lifecycle.ViewModel> T create(String, Class<T!>, androidx.lifecycle.SavedStateHandle);
+  }
+
+  public final class SavedStateHandle {
+    ctor public SavedStateHandle(java.util.Map<java.lang.String!,java.lang.Object!>);
+    ctor public SavedStateHandle();
+    method @MainThread public boolean contains(String);
+    method @MainThread public <T> T? get(String);
+    method @MainThread public <T> androidx.lifecycle.MutableLiveData<T!> getLiveData(String);
+    method @MainThread public <T> androidx.lifecycle.MutableLiveData<T!> getLiveData(String, T!);
+    method @MainThread public java.util.Set<java.lang.String!> keys();
+    method @MainThread public <T> T? remove(String);
+    method @MainThread public <T> void set(String, T?);
+  }
+
+  public final class SavedStateViewModelFactory extends androidx.lifecycle.AbstractSavedStateViewModelFactory implements androidx.lifecycle.ViewModelProvider.Factory {
+    ctor public SavedStateViewModelFactory(android.app.Application, androidx.savedstate.SavedStateRegistryOwner);
+    ctor public SavedStateViewModelFactory(android.app.Application, androidx.savedstate.SavedStateRegistryOwner, android.os.Bundle?);
+    method protected <T extends androidx.lifecycle.ViewModel> T create(String, Class<T!>, androidx.lifecycle.SavedStateHandle);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/lifecycle/lifecycle-viewmodel-savedstate/api/res-1.0.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to lifecycle/lifecycle-viewmodel-savedstate/api/res-1.0.0-alpha04.txt
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_1.0.0-alpha04.txt b/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_1.0.0-alpha04.txt
new file mode 100644
index 0000000..efd5ff3
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_1.0.0-alpha04.txt
@@ -0,0 +1,30 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public abstract class AbstractSavedStateViewModelFactory implements androidx.lifecycle.ViewModelProvider.Factory {
+    ctor public AbstractSavedStateViewModelFactory(androidx.savedstate.SavedStateRegistryOwner, android.os.Bundle?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final <T extends androidx.lifecycle.ViewModel> T create(String, Class<T!>);
+    method public final <T extends androidx.lifecycle.ViewModel> T create(Class<T!>);
+    method protected abstract <T extends androidx.lifecycle.ViewModel> T create(String, Class<T!>, androidx.lifecycle.SavedStateHandle);
+  }
+
+  public final class SavedStateHandle {
+    ctor public SavedStateHandle(java.util.Map<java.lang.String!,java.lang.Object!>);
+    ctor public SavedStateHandle();
+    method @MainThread public boolean contains(String);
+    method @MainThread public <T> T? get(String);
+    method @MainThread public <T> androidx.lifecycle.MutableLiveData<T!> getLiveData(String);
+    method @MainThread public <T> androidx.lifecycle.MutableLiveData<T!> getLiveData(String, T!);
+    method @MainThread public java.util.Set<java.lang.String!> keys();
+    method @MainThread public <T> T? remove(String);
+    method @MainThread public <T> void set(String, T?);
+  }
+
+  public final class SavedStateViewModelFactory extends androidx.lifecycle.AbstractSavedStateViewModelFactory implements androidx.lifecycle.ViewModelProvider.Factory {
+    ctor public SavedStateViewModelFactory(android.app.Application, androidx.savedstate.SavedStateRegistryOwner);
+    ctor public SavedStateViewModelFactory(android.app.Application, androidx.savedstate.SavedStateRegistryOwner, android.os.Bundle?);
+    method protected <T extends androidx.lifecycle.ViewModel> T create(String, Class<T!>, androidx.lifecycle.SavedStateHandle);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-viewmodel/api/2.2.0-alpha04.txt b/lifecycle/lifecycle-viewmodel/api/2.2.0-alpha04.txt
new file mode 100644
index 0000000..07a8cb5
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel/api/2.2.0-alpha04.txt
@@ -0,0 +1,50 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public class AndroidViewModel extends androidx.lifecycle.ViewModel {
+    ctor public AndroidViewModel(android.app.Application);
+    method public <T extends android.app.Application> T getApplication();
+  }
+
+  public interface HasDefaultViewModelProviderFactory {
+    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+  }
+
+  public abstract class ViewModel {
+    ctor public ViewModel();
+    method protected void onCleared();
+  }
+
+  public class ViewModelProvider {
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStoreOwner);
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStoreOwner, androidx.lifecycle.ViewModelProvider.Factory);
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStore, androidx.lifecycle.ViewModelProvider.Factory);
+    method @MainThread public <T extends androidx.lifecycle.ViewModel> T get(Class<T!>);
+    method @MainThread public <T extends androidx.lifecycle.ViewModel> T get(String, Class<T!>);
+  }
+
+  public static class ViewModelProvider.AndroidViewModelFactory extends androidx.lifecycle.ViewModelProvider.NewInstanceFactory {
+    ctor public ViewModelProvider.AndroidViewModelFactory(android.app.Application);
+    method public static androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory getInstance(android.app.Application);
+  }
+
+  public static interface ViewModelProvider.Factory {
+    method public <T extends androidx.lifecycle.ViewModel> T create(Class<T!>);
+  }
+
+  public static class ViewModelProvider.NewInstanceFactory implements androidx.lifecycle.ViewModelProvider.Factory {
+    ctor public ViewModelProvider.NewInstanceFactory();
+    method public <T extends androidx.lifecycle.ViewModel> T create(Class<T!>);
+  }
+
+  public class ViewModelStore {
+    ctor public ViewModelStore();
+    method public final void clear();
+  }
+
+  public interface ViewModelStoreOwner {
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/lifecycle/lifecycle-viewmodel/api/res-2.2.0-alpha04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to lifecycle/lifecycle-viewmodel/api/res-2.2.0-alpha04.txt
diff --git a/lifecycle/lifecycle-viewmodel/api/restricted_2.2.0-alpha04.txt b/lifecycle/lifecycle-viewmodel/api/restricted_2.2.0-alpha04.txt
new file mode 100644
index 0000000..07a8cb5
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel/api/restricted_2.2.0-alpha04.txt
@@ -0,0 +1,50 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+  public class AndroidViewModel extends androidx.lifecycle.ViewModel {
+    ctor public AndroidViewModel(android.app.Application);
+    method public <T extends android.app.Application> T getApplication();
+  }
+
+  public interface HasDefaultViewModelProviderFactory {
+    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+  }
+
+  public abstract class ViewModel {
+    ctor public ViewModel();
+    method protected void onCleared();
+  }
+
+  public class ViewModelProvider {
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStoreOwner);
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStoreOwner, androidx.lifecycle.ViewModelProvider.Factory);
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStore, androidx.lifecycle.ViewModelProvider.Factory);
+    method @MainThread public <T extends androidx.lifecycle.ViewModel> T get(Class<T!>);
+    method @MainThread public <T extends androidx.lifecycle.ViewModel> T get(String, Class<T!>);
+  }
+
+  public static class ViewModelProvider.AndroidViewModelFactory extends androidx.lifecycle.ViewModelProvider.NewInstanceFactory {
+    ctor public ViewModelProvider.AndroidViewModelFactory(android.app.Application);
+    method public static androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory getInstance(android.app.Application);
+  }
+
+  public static interface ViewModelProvider.Factory {
+    method public <T extends androidx.lifecycle.ViewModel> T create(Class<T!>);
+  }
+
+  public static class ViewModelProvider.NewInstanceFactory implements androidx.lifecycle.ViewModelProvider.Factory {
+    ctor public ViewModelProvider.NewInstanceFactory();
+    method public <T extends androidx.lifecycle.ViewModel> T create(Class<T!>);
+  }
+
+  public class ViewModelStore {
+    ctor public ViewModelStore();
+    method public final void clear();
+  }
+
+  public interface ViewModelStoreOwner {
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+  }
+
+}
+
diff --git a/loader/loader/api/api_lint.ignore b/loader/loader/api/api_lint.ignore
index cb37084..61ab4c6 100644
--- a/loader/loader/api/api_lint.ignore
+++ b/loader/loader/api/api_lint.ignore
@@ -3,6 +3,46 @@
     Class should be named ForceLoadContentCallback
 
 
+MissingNullability: androidx.loader.app.LoaderManager#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
+    Missing nullability on parameter `prefix` in method `dump`
+MissingNullability: androidx.loader.app.LoaderManager#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
+    Missing nullability on parameter `fd` in method `dump`
+MissingNullability: androidx.loader.app.LoaderManager#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2:
+    Missing nullability on parameter `writer` in method `dump`
+MissingNullability: androidx.loader.app.LoaderManager#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #3:
+    Missing nullability on parameter `args` in method `dump`
+MissingNullability: androidx.loader.content.AsyncTaskLoader#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
+    Missing nullability on parameter `prefix` in method `dump`
+MissingNullability: androidx.loader.content.AsyncTaskLoader#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
+    Missing nullability on parameter `fd` in method `dump`
+MissingNullability: androidx.loader.content.AsyncTaskLoader#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2:
+    Missing nullability on parameter `writer` in method `dump`
+MissingNullability: androidx.loader.content.AsyncTaskLoader#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #3:
+    Missing nullability on parameter `args` in method `dump`
+MissingNullability: androidx.loader.content.CursorLoader#deliverResult(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `cursor` in method `deliverResult`
+MissingNullability: androidx.loader.content.CursorLoader#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
+    Missing nullability on parameter `prefix` in method `dump`
+MissingNullability: androidx.loader.content.CursorLoader#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
+    Missing nullability on parameter `fd` in method `dump`
+MissingNullability: androidx.loader.content.CursorLoader#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2:
+    Missing nullability on parameter `writer` in method `dump`
+MissingNullability: androidx.loader.content.CursorLoader#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #3:
+    Missing nullability on parameter `args` in method `dump`
+MissingNullability: androidx.loader.content.CursorLoader#loadInBackground():
+    Missing nullability on method `loadInBackground` return
+MissingNullability: androidx.loader.content.CursorLoader#onCanceled(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `cursor` in method `onCanceled`
+MissingNullability: androidx.loader.content.Loader#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
+    Missing nullability on parameter `prefix` in method `dump`
+MissingNullability: androidx.loader.content.Loader#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
+    Missing nullability on parameter `fd` in method `dump`
+MissingNullability: androidx.loader.content.Loader#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2:
+    Missing nullability on parameter `writer` in method `dump`
+MissingNullability: androidx.loader.content.Loader#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #3:
+    Missing nullability on parameter `args` in method `dump`
+
+
 NoClone: androidx.loader.app.LoaderManager#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
     Must use ParcelFileDescriptor instead of FileDescriptor in parameter fd in androidx.loader.app.LoaderManager.dump(String prefix, java.io.FileDescriptor fd, java.io.PrintWriter writer, String[] args)
 NoClone: androidx.loader.content.AsyncTaskLoader#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
diff --git a/media/api/api_lint.ignore b/media/api/api_lint.ignore
index 6e2dfd0..1fa7b87 100644
--- a/media/api/api_lint.ignore
+++ b/media/api/api_lint.ignore
@@ -39,6 +39,572 @@
     Inconsistent interface constant; expected 'MediaBrowserServiceCompat'`
 
 
+MissingNullability: android.support.v4.media.MediaBrowserCompat#MediaBrowserCompat(android.content.Context, android.content.ComponentName, android.support.v4.media.MediaBrowserCompat.ConnectionCallback, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `context` in method `MediaBrowserCompat`
+MissingNullability: android.support.v4.media.MediaBrowserCompat#MediaBrowserCompat(android.content.Context, android.content.ComponentName, android.support.v4.media.MediaBrowserCompat.ConnectionCallback, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `serviceComponent` in method `MediaBrowserCompat`
+MissingNullability: android.support.v4.media.MediaBrowserCompat#MediaBrowserCompat(android.content.Context, android.content.ComponentName, android.support.v4.media.MediaBrowserCompat.ConnectionCallback, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `callback` in method `MediaBrowserCompat`
+MissingNullability: android.support.v4.media.MediaBrowserCompat#MediaBrowserCompat(android.content.Context, android.content.ComponentName, android.support.v4.media.MediaBrowserCompat.ConnectionCallback, android.os.Bundle) parameter #3:
+    Missing nullability on parameter `rootHints` in method `MediaBrowserCompat`
+MissingNullability: android.support.v4.media.MediaBrowserCompat#search(String, android.os.Bundle, android.support.v4.media.MediaBrowserCompat.SearchCallback) parameter #1:
+    Missing nullability on parameter `extras` in method `search`
+MissingNullability: android.support.v4.media.MediaBrowserCompat#sendCustomAction(String, android.os.Bundle, android.support.v4.media.MediaBrowserCompat.CustomActionCallback) parameter #1:
+    Missing nullability on parameter `extras` in method `sendCustomAction`
+MissingNullability: android.support.v4.media.MediaBrowserCompat.CustomActionCallback#onError(String, android.os.Bundle, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `action` in method `onError`
+MissingNullability: android.support.v4.media.MediaBrowserCompat.CustomActionCallback#onError(String, android.os.Bundle, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `onError`
+MissingNullability: android.support.v4.media.MediaBrowserCompat.CustomActionCallback#onError(String, android.os.Bundle, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `data` in method `onError`
+MissingNullability: android.support.v4.media.MediaBrowserCompat.CustomActionCallback#onProgressUpdate(String, android.os.Bundle, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `action` in method `onProgressUpdate`
+MissingNullability: android.support.v4.media.MediaBrowserCompat.CustomActionCallback#onProgressUpdate(String, android.os.Bundle, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `onProgressUpdate`
+MissingNullability: android.support.v4.media.MediaBrowserCompat.CustomActionCallback#onProgressUpdate(String, android.os.Bundle, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `data` in method `onProgressUpdate`
+MissingNullability: android.support.v4.media.MediaBrowserCompat.CustomActionCallback#onResult(String, android.os.Bundle, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `action` in method `onResult`
+MissingNullability: android.support.v4.media.MediaBrowserCompat.CustomActionCallback#onResult(String, android.os.Bundle, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `onResult`
+MissingNullability: android.support.v4.media.MediaBrowserCompat.CustomActionCallback#onResult(String, android.os.Bundle, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `resultData` in method `onResult`
+MissingNullability: android.support.v4.media.MediaBrowserCompat.ItemCallback#onItemLoaded(android.support.v4.media.MediaBrowserCompat.MediaItem) parameter #0:
+    Missing nullability on parameter `item` in method `onItemLoaded`
+MissingNullability: android.support.v4.media.MediaBrowserCompat.MediaItem#CREATOR:
+    Missing nullability on field `CREATOR` in class `class android.support.v4.media.MediaBrowserCompat.MediaItem`
+MissingNullability: android.support.v4.media.MediaBrowserCompat.MediaItem#fromMediaItem(Object):
+    Missing nullability on method `fromMediaItem` return
+MissingNullability: android.support.v4.media.MediaBrowserCompat.MediaItem#fromMediaItem(Object) parameter #0:
+    Missing nullability on parameter `itemObj` in method `fromMediaItem`
+MissingNullability: android.support.v4.media.MediaBrowserCompat.MediaItem#fromMediaItemList(java.util.List<?>):
+    Missing nullability on method `fromMediaItemList` return
+MissingNullability: android.support.v4.media.MediaBrowserCompat.MediaItem#fromMediaItemList(java.util.List<?>) parameter #0:
+    Missing nullability on parameter `itemList` in method `fromMediaItemList`
+MissingNullability: android.support.v4.media.MediaBrowserCompat.MediaItem#writeToParcel(android.os.Parcel, int) parameter #0:
+    Missing nullability on parameter `out` in method `writeToParcel`
+MissingNullability: android.support.v4.media.MediaBrowserCompat.SearchCallback#onError(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `onError`
+MissingNullability: android.support.v4.media.MediaBrowserCompat.SearchCallback#onSearchResult(String, android.os.Bundle, java.util.List<android.support.v4.media.MediaBrowserCompat.MediaItem>) parameter #1:
+    Missing nullability on parameter `extras` in method `onSearchResult`
+MissingNullability: android.support.v4.media.MediaDescriptionCompat#CREATOR:
+    Missing nullability on field `CREATOR` in class `class android.support.v4.media.MediaDescriptionCompat`
+MissingNullability: android.support.v4.media.MediaDescriptionCompat#fromMediaDescription(Object):
+    Missing nullability on method `fromMediaDescription` return
+MissingNullability: android.support.v4.media.MediaDescriptionCompat#fromMediaDescription(Object) parameter #0:
+    Missing nullability on parameter `descriptionObj` in method `fromMediaDescription`
+MissingNullability: android.support.v4.media.MediaDescriptionCompat#getMediaDescription():
+    Missing nullability on method `getMediaDescription` return
+MissingNullability: android.support.v4.media.MediaDescriptionCompat#toString():
+    Missing nullability on method `toString` return
+MissingNullability: android.support.v4.media.MediaDescriptionCompat#writeToParcel(android.os.Parcel, int) parameter #0:
+    Missing nullability on parameter `dest` in method `writeToParcel`
+MissingNullability: android.support.v4.media.MediaDescriptionCompat.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: android.support.v4.media.MediaDescriptionCompat.Builder#setDescription(CharSequence):
+    Missing nullability on method `setDescription` return
+MissingNullability: android.support.v4.media.MediaDescriptionCompat.Builder#setExtras(android.os.Bundle):
+    Missing nullability on method `setExtras` return
+MissingNullability: android.support.v4.media.MediaDescriptionCompat.Builder#setIconBitmap(android.graphics.Bitmap):
+    Missing nullability on method `setIconBitmap` return
+MissingNullability: android.support.v4.media.MediaDescriptionCompat.Builder#setIconUri(android.net.Uri):
+    Missing nullability on method `setIconUri` return
+MissingNullability: android.support.v4.media.MediaDescriptionCompat.Builder#setMediaId(String):
+    Missing nullability on method `setMediaId` return
+MissingNullability: android.support.v4.media.MediaDescriptionCompat.Builder#setMediaUri(android.net.Uri):
+    Missing nullability on method `setMediaUri` return
+MissingNullability: android.support.v4.media.MediaDescriptionCompat.Builder#setSubtitle(CharSequence):
+    Missing nullability on method `setSubtitle` return
+MissingNullability: android.support.v4.media.MediaDescriptionCompat.Builder#setTitle(CharSequence):
+    Missing nullability on method `setTitle` return
+MissingNullability: android.support.v4.media.MediaMetadataCompat#CREATOR:
+    Missing nullability on field `CREATOR` in class `class android.support.v4.media.MediaMetadataCompat`
+MissingNullability: android.support.v4.media.MediaMetadataCompat#containsKey(String) parameter #0:
+    Missing nullability on parameter `key` in method `containsKey`
+MissingNullability: android.support.v4.media.MediaMetadataCompat#fromMediaMetadata(Object):
+    Missing nullability on method `fromMediaMetadata` return
+MissingNullability: android.support.v4.media.MediaMetadataCompat#fromMediaMetadata(Object) parameter #0:
+    Missing nullability on parameter `metadataObj` in method `fromMediaMetadata`
+MissingNullability: android.support.v4.media.MediaMetadataCompat#getBitmap(String):
+    Missing nullability on method `getBitmap` return
+MissingNullability: android.support.v4.media.MediaMetadataCompat#getBitmap(String) parameter #0:
+    Missing nullability on parameter `key` in method `getBitmap`
+MissingNullability: android.support.v4.media.MediaMetadataCompat#getBundle():
+    Missing nullability on method `getBundle` return
+MissingNullability: android.support.v4.media.MediaMetadataCompat#getDescription():
+    Missing nullability on method `getDescription` return
+MissingNullability: android.support.v4.media.MediaMetadataCompat#getLong(String) parameter #0:
+    Missing nullability on parameter `key` in method `getLong`
+MissingNullability: android.support.v4.media.MediaMetadataCompat#getMediaMetadata():
+    Missing nullability on method `getMediaMetadata` return
+MissingNullability: android.support.v4.media.MediaMetadataCompat#getRating(String):
+    Missing nullability on method `getRating` return
+MissingNullability: android.support.v4.media.MediaMetadataCompat#getRating(String) parameter #0:
+    Missing nullability on parameter `key` in method `getRating`
+MissingNullability: android.support.v4.media.MediaMetadataCompat#getString(String):
+    Missing nullability on method `getString` return
+MissingNullability: android.support.v4.media.MediaMetadataCompat#getString(String) parameter #0:
+    Missing nullability on parameter `key` in method `getString`
+MissingNullability: android.support.v4.media.MediaMetadataCompat#getText(String):
+    Missing nullability on method `getText` return
+MissingNullability: android.support.v4.media.MediaMetadataCompat#getText(String) parameter #0:
+    Missing nullability on parameter `key` in method `getText`
+MissingNullability: android.support.v4.media.MediaMetadataCompat#keySet():
+    Missing nullability on method `keySet` return
+MissingNullability: android.support.v4.media.MediaMetadataCompat#writeToParcel(android.os.Parcel, int) parameter #0:
+    Missing nullability on parameter `dest` in method `writeToParcel`
+MissingNullability: android.support.v4.media.MediaMetadataCompat.Builder#Builder(android.support.v4.media.MediaMetadataCompat) parameter #0:
+    Missing nullability on parameter `source` in method `Builder`
+MissingNullability: android.support.v4.media.MediaMetadataCompat.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: android.support.v4.media.MediaMetadataCompat.Builder#putBitmap(String, android.graphics.Bitmap):
+    Missing nullability on method `putBitmap` return
+MissingNullability: android.support.v4.media.MediaMetadataCompat.Builder#putBitmap(String, android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `key` in method `putBitmap`
+MissingNullability: android.support.v4.media.MediaMetadataCompat.Builder#putBitmap(String, android.graphics.Bitmap) parameter #1:
+    Missing nullability on parameter `value` in method `putBitmap`
+MissingNullability: android.support.v4.media.MediaMetadataCompat.Builder#putLong(String, long):
+    Missing nullability on method `putLong` return
+MissingNullability: android.support.v4.media.MediaMetadataCompat.Builder#putLong(String, long) parameter #0:
+    Missing nullability on parameter `key` in method `putLong`
+MissingNullability: android.support.v4.media.MediaMetadataCompat.Builder#putRating(String, android.support.v4.media.RatingCompat):
+    Missing nullability on method `putRating` return
+MissingNullability: android.support.v4.media.MediaMetadataCompat.Builder#putRating(String, android.support.v4.media.RatingCompat) parameter #0:
+    Missing nullability on parameter `key` in method `putRating`
+MissingNullability: android.support.v4.media.MediaMetadataCompat.Builder#putRating(String, android.support.v4.media.RatingCompat) parameter #1:
+    Missing nullability on parameter `value` in method `putRating`
+MissingNullability: android.support.v4.media.MediaMetadataCompat.Builder#putString(String, String):
+    Missing nullability on method `putString` return
+MissingNullability: android.support.v4.media.MediaMetadataCompat.Builder#putString(String, String) parameter #0:
+    Missing nullability on parameter `key` in method `putString`
+MissingNullability: android.support.v4.media.MediaMetadataCompat.Builder#putString(String, String) parameter #1:
+    Missing nullability on parameter `value` in method `putString`
+MissingNullability: android.support.v4.media.MediaMetadataCompat.Builder#putText(String, CharSequence):
+    Missing nullability on method `putText` return
+MissingNullability: android.support.v4.media.MediaMetadataCompat.Builder#putText(String, CharSequence) parameter #0:
+    Missing nullability on parameter `key` in method `putText`
+MissingNullability: android.support.v4.media.MediaMetadataCompat.Builder#putText(String, CharSequence) parameter #1:
+    Missing nullability on parameter `value` in method `putText`
+MissingNullability: android.support.v4.media.RatingCompat#CREATOR:
+    Missing nullability on field `CREATOR` in class `class android.support.v4.media.RatingCompat`
+MissingNullability: android.support.v4.media.RatingCompat#fromRating(Object):
+    Missing nullability on method `fromRating` return
+MissingNullability: android.support.v4.media.RatingCompat#fromRating(Object) parameter #0:
+    Missing nullability on parameter `ratingObj` in method `fromRating`
+MissingNullability: android.support.v4.media.RatingCompat#getRating():
+    Missing nullability on method `getRating` return
+MissingNullability: android.support.v4.media.RatingCompat#newHeartRating(boolean):
+    Missing nullability on method `newHeartRating` return
+MissingNullability: android.support.v4.media.RatingCompat#newPercentageRating(float):
+    Missing nullability on method `newPercentageRating` return
+MissingNullability: android.support.v4.media.RatingCompat#newStarRating(int, float):
+    Missing nullability on method `newStarRating` return
+MissingNullability: android.support.v4.media.RatingCompat#newThumbRating(boolean):
+    Missing nullability on method `newThumbRating` return
+MissingNullability: android.support.v4.media.RatingCompat#newUnratedRating(int):
+    Missing nullability on method `newUnratedRating` return
+MissingNullability: android.support.v4.media.RatingCompat#toString():
+    Missing nullability on method `toString` return
+MissingNullability: android.support.v4.media.RatingCompat#writeToParcel(android.os.Parcel, int) parameter #0:
+    Missing nullability on parameter `dest` in method `writeToParcel`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#MediaControllerCompat(android.content.Context, android.support.v4.media.session.MediaSessionCompat) parameter #0:
+    Missing nullability on parameter `context` in method `MediaControllerCompat`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#MediaControllerCompat(android.content.Context, android.support.v4.media.session.MediaSessionCompat.Token) parameter #0:
+    Missing nullability on parameter `context` in method `MediaControllerCompat`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#addQueueItem(android.support.v4.media.MediaDescriptionCompat) parameter #0:
+    Missing nullability on parameter `description` in method `addQueueItem`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#addQueueItem(android.support.v4.media.MediaDescriptionCompat, int) parameter #0:
+    Missing nullability on parameter `description` in method `addQueueItem`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#dispatchMediaButtonEvent(android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `keyEvent` in method `dispatchMediaButtonEvent`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#getExtras():
+    Missing nullability on method `getExtras` return
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#getMediaController():
+    Missing nullability on method `getMediaController` return
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#getMediaController(android.app.Activity):
+    Missing nullability on method `getMediaController` return
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#getMetadata():
+    Missing nullability on method `getMetadata` return
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#getPackageName():
+    Missing nullability on method `getPackageName` return
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#getPlaybackInfo():
+    Missing nullability on method `getPlaybackInfo` return
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#getPlaybackState():
+    Missing nullability on method `getPlaybackState` return
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#getQueue():
+    Missing nullability on method `getQueue` return
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#getQueueTitle():
+    Missing nullability on method `getQueueTitle` return
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#getSessionActivity():
+    Missing nullability on method `getSessionActivity` return
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#getSessionToken():
+    Missing nullability on method `getSessionToken` return
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#getTransportControls():
+    Missing nullability on method `getTransportControls` return
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#registerCallback(android.support.v4.media.session.MediaControllerCompat.Callback, android.os.Handler) parameter #1:
+    Missing nullability on parameter `handler` in method `registerCallback`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#removeQueueItem(android.support.v4.media.MediaDescriptionCompat) parameter #0:
+    Missing nullability on parameter `description` in method `removeQueueItem`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat#setMediaController(android.app.Activity, android.support.v4.media.session.MediaControllerCompat) parameter #1:
+    Missing nullability on parameter `mediaController` in method `setMediaController`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.Callback#onAudioInfoChanged(android.support.v4.media.session.MediaControllerCompat.PlaybackInfo) parameter #0:
+    Missing nullability on parameter `info` in method `onAudioInfoChanged`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.Callback#onExtrasChanged(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `extras` in method `onExtrasChanged`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.Callback#onMetadataChanged(android.support.v4.media.MediaMetadataCompat) parameter #0:
+    Missing nullability on parameter `metadata` in method `onMetadataChanged`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.Callback#onPlaybackStateChanged(android.support.v4.media.session.PlaybackStateCompat) parameter #0:
+    Missing nullability on parameter `state` in method `onPlaybackStateChanged`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.Callback#onQueueChanged(java.util.List<android.support.v4.media.session.MediaSessionCompat.QueueItem>) parameter #0:
+    Missing nullability on parameter `queue` in method `onQueueChanged`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.Callback#onQueueTitleChanged(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `onQueueTitleChanged`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.Callback#onSessionEvent(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `event` in method `onSessionEvent`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.Callback#onSessionEvent(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `onSessionEvent`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#playFromMediaId(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `mediaId` in method `playFromMediaId`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#playFromMediaId(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `playFromMediaId`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#playFromSearch(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `query` in method `playFromSearch`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#playFromSearch(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `playFromSearch`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#playFromUri(android.net.Uri, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `uri` in method `playFromUri`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#playFromUri(android.net.Uri, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `playFromUri`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#prepareFromMediaId(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `mediaId` in method `prepareFromMediaId`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#prepareFromMediaId(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `prepareFromMediaId`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#prepareFromSearch(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `query` in method `prepareFromSearch`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#prepareFromSearch(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `prepareFromSearch`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#prepareFromUri(android.net.Uri, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `uri` in method `prepareFromUri`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#prepareFromUri(android.net.Uri, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `prepareFromUri`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#sendCustomAction(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `action` in method `sendCustomAction`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#sendCustomAction(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `args` in method `sendCustomAction`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#sendCustomAction(android.support.v4.media.session.PlaybackStateCompat.CustomAction, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `customAction` in method `sendCustomAction`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#sendCustomAction(android.support.v4.media.session.PlaybackStateCompat.CustomAction, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `args` in method `sendCustomAction`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#setRating(android.support.v4.media.RatingCompat) parameter #0:
+    Missing nullability on parameter `rating` in method `setRating`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#setRating(android.support.v4.media.RatingCompat, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `rating` in method `setRating`
+MissingNullability: android.support.v4.media.session.MediaControllerCompat.TransportControls#setRating(android.support.v4.media.RatingCompat, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `setRating`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#addOnActiveChangeListener(android.support.v4.media.session.MediaSessionCompat.OnActiveChangeListener) parameter #0:
+    Missing nullability on parameter `listener` in method `addOnActiveChangeListener`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#fromMediaSession(android.content.Context, Object):
+    Missing nullability on method `fromMediaSession` return
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#fromMediaSession(android.content.Context, Object) parameter #0:
+    Missing nullability on parameter `context` in method `fromMediaSession`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#fromMediaSession(android.content.Context, Object) parameter #1:
+    Missing nullability on parameter `mediaSession` in method `fromMediaSession`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#getController():
+    Missing nullability on method `getController` return
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#getMediaSession():
+    Missing nullability on method `getMediaSession` return
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#getRemoteControlClient():
+    Missing nullability on method `getRemoteControlClient` return
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#getSessionToken():
+    Missing nullability on method `getSessionToken` return
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#removeOnActiveChangeListener(android.support.v4.media.session.MediaSessionCompat.OnActiveChangeListener) parameter #0:
+    Missing nullability on parameter `listener` in method `removeOnActiveChangeListener`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#sendSessionEvent(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `event` in method `sendSessionEvent`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#sendSessionEvent(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `sendSessionEvent`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#setCallback(android.support.v4.media.session.MediaSessionCompat.Callback) parameter #0:
+    Missing nullability on parameter `callback` in method `setCallback`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#setCallback(android.support.v4.media.session.MediaSessionCompat.Callback, android.os.Handler) parameter #0:
+    Missing nullability on parameter `callback` in method `setCallback`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#setCallback(android.support.v4.media.session.MediaSessionCompat.Callback, android.os.Handler) parameter #1:
+    Missing nullability on parameter `handler` in method `setCallback`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#setExtras(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `extras` in method `setExtras`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#setMediaButtonReceiver(android.app.PendingIntent) parameter #0:
+    Missing nullability on parameter `mbr` in method `setMediaButtonReceiver`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#setMetadata(android.support.v4.media.MediaMetadataCompat) parameter #0:
+    Missing nullability on parameter `metadata` in method `setMetadata`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#setPlaybackState(android.support.v4.media.session.PlaybackStateCompat) parameter #0:
+    Missing nullability on parameter `state` in method `setPlaybackState`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#setPlaybackToRemote(androidx.media.VolumeProviderCompat) parameter #0:
+    Missing nullability on parameter `volumeProvider` in method `setPlaybackToRemote`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#setQueue(java.util.List<android.support.v4.media.session.MediaSessionCompat.QueueItem>) parameter #0:
+    Missing nullability on parameter `queue` in method `setQueue`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#setQueueTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setQueueTitle`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat#setSessionActivity(android.app.PendingIntent) parameter #0:
+    Missing nullability on parameter `pi` in method `setSessionActivity`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onAddQueueItem(android.support.v4.media.MediaDescriptionCompat) parameter #0:
+    Missing nullability on parameter `description` in method `onAddQueueItem`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onAddQueueItem(android.support.v4.media.MediaDescriptionCompat, int) parameter #0:
+    Missing nullability on parameter `description` in method `onAddQueueItem`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onCommand(String, android.os.Bundle, android.os.ResultReceiver) parameter #0:
+    Missing nullability on parameter `command` in method `onCommand`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onCommand(String, android.os.Bundle, android.os.ResultReceiver) parameter #1:
+    Missing nullability on parameter `extras` in method `onCommand`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onCommand(String, android.os.Bundle, android.os.ResultReceiver) parameter #2:
+    Missing nullability on parameter `cb` in method `onCommand`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onCustomAction(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `action` in method `onCustomAction`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onCustomAction(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `onCustomAction`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onMediaButtonEvent(android.content.Intent) parameter #0:
+    Missing nullability on parameter `mediaButtonEvent` in method `onMediaButtonEvent`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onPlayFromMediaId(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `mediaId` in method `onPlayFromMediaId`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onPlayFromMediaId(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `onPlayFromMediaId`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onPlayFromSearch(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `query` in method `onPlayFromSearch`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onPlayFromSearch(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `onPlayFromSearch`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onPlayFromUri(android.net.Uri, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `uri` in method `onPlayFromUri`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onPlayFromUri(android.net.Uri, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `onPlayFromUri`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onPrepareFromMediaId(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `mediaId` in method `onPrepareFromMediaId`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onPrepareFromMediaId(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `onPrepareFromMediaId`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onPrepareFromSearch(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `query` in method `onPrepareFromSearch`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onPrepareFromSearch(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `onPrepareFromSearch`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onPrepareFromUri(android.net.Uri, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `uri` in method `onPrepareFromUri`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onPrepareFromUri(android.net.Uri, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `onPrepareFromUri`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onRemoveQueueItem(android.support.v4.media.MediaDescriptionCompat) parameter #0:
+    Missing nullability on parameter `description` in method `onRemoveQueueItem`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onSetRating(android.support.v4.media.RatingCompat) parameter #0:
+    Missing nullability on parameter `rating` in method `onSetRating`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onSetRating(android.support.v4.media.RatingCompat, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `rating` in method `onSetRating`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Callback#onSetRating(android.support.v4.media.RatingCompat, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `extras` in method `onSetRating`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.QueueItem#CREATOR:
+    Missing nullability on field `CREATOR` in class `class android.support.v4.media.session.MediaSessionCompat.QueueItem`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.QueueItem#QueueItem(android.support.v4.media.MediaDescriptionCompat, long) parameter #0:
+    Missing nullability on parameter `description` in method `QueueItem`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.QueueItem#fromQueueItem(Object):
+    Missing nullability on method `fromQueueItem` return
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.QueueItem#fromQueueItem(Object) parameter #0:
+    Missing nullability on parameter `queueItem` in method `fromQueueItem`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.QueueItem#fromQueueItemList(java.util.List<?>):
+    Missing nullability on method `fromQueueItemList` return
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.QueueItem#fromQueueItemList(java.util.List<?>) parameter #0:
+    Missing nullability on parameter `itemList` in method `fromQueueItemList`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.QueueItem#getDescription():
+    Missing nullability on method `getDescription` return
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.QueueItem#getQueueItem():
+    Missing nullability on method `getQueueItem` return
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.QueueItem#toString():
+    Missing nullability on method `toString` return
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.QueueItem#writeToParcel(android.os.Parcel, int) parameter #0:
+    Missing nullability on parameter `dest` in method `writeToParcel`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Token#CREATOR:
+    Missing nullability on field `CREATOR` in class `class android.support.v4.media.session.MediaSessionCompat.Token`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Token#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Token#fromToken(Object):
+    Missing nullability on method `fromToken` return
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Token#fromToken(Object) parameter #0:
+    Missing nullability on parameter `token` in method `fromToken`
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Token#getToken():
+    Missing nullability on method `getToken` return
+MissingNullability: android.support.v4.media.session.MediaSessionCompat.Token#writeToParcel(android.os.Parcel, int) parameter #0:
+    Missing nullability on parameter `dest` in method `writeToParcel`
+MissingNullability: android.support.v4.media.session.ParcelableVolumeInfo#CREATOR:
+    Missing nullability on field `CREATOR` in class `class android.support.v4.media.session.ParcelableVolumeInfo`
+MissingNullability: android.support.v4.media.session.ParcelableVolumeInfo#ParcelableVolumeInfo(android.os.Parcel) parameter #0:
+    Missing nullability on parameter `from` in method `ParcelableVolumeInfo`
+MissingNullability: android.support.v4.media.session.ParcelableVolumeInfo#writeToParcel(android.os.Parcel, int) parameter #0:
+    Missing nullability on parameter `dest` in method `writeToParcel`
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat#CREATOR:
+    Missing nullability on field `CREATOR` in class `class android.support.v4.media.session.PlaybackStateCompat`
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat#fromPlaybackState(Object):
+    Missing nullability on method `fromPlaybackState` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat#fromPlaybackState(Object) parameter #0:
+    Missing nullability on parameter `stateObj` in method `fromPlaybackState`
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat#getCustomActions():
+    Missing nullability on method `getCustomActions` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat#getErrorMessage():
+    Missing nullability on method `getErrorMessage` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat#getPlaybackState():
+    Missing nullability on method `getPlaybackState` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat#toString():
+    Missing nullability on method `toString` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat#writeToParcel(android.os.Parcel, int) parameter #0:
+    Missing nullability on parameter `dest` in method `writeToParcel`
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#Builder(android.support.v4.media.session.PlaybackStateCompat) parameter #0:
+    Missing nullability on parameter `source` in method `Builder`
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#addCustomAction(String, String, int):
+    Missing nullability on method `addCustomAction` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#addCustomAction(String, String, int) parameter #0:
+    Missing nullability on parameter `action` in method `addCustomAction`
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#addCustomAction(String, String, int) parameter #1:
+    Missing nullability on parameter `name` in method `addCustomAction`
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#addCustomAction(android.support.v4.media.session.PlaybackStateCompat.CustomAction):
+    Missing nullability on method `addCustomAction` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#addCustomAction(android.support.v4.media.session.PlaybackStateCompat.CustomAction) parameter #0:
+    Missing nullability on parameter `customAction` in method `addCustomAction`
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#setActions(long):
+    Missing nullability on method `setActions` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#setActiveQueueItemId(long):
+    Missing nullability on method `setActiveQueueItemId` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#setBufferedPosition(long):
+    Missing nullability on method `setBufferedPosition` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#setErrorMessage(CharSequence) parameter #0:
+    Missing nullability on parameter `errorMessage` in method `setErrorMessage`
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#setErrorMessage(int, CharSequence):
+    Missing nullability on method `setErrorMessage` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#setErrorMessage(int, CharSequence) parameter #1:
+    Missing nullability on parameter `errorMessage` in method `setErrorMessage`
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#setExtras(android.os.Bundle):
+    Missing nullability on method `setExtras` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#setExtras(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `extras` in method `setExtras`
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#setState(int, long, float):
+    Missing nullability on method `setState` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.Builder#setState(int, long, float, long):
+    Missing nullability on method `setState` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.CustomAction#CREATOR:
+    Missing nullability on field `CREATOR` in class `class android.support.v4.media.session.PlaybackStateCompat.CustomAction`
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.CustomAction#fromCustomAction(Object):
+    Missing nullability on method `fromCustomAction` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.CustomAction#fromCustomAction(Object) parameter #0:
+    Missing nullability on parameter `customActionObj` in method `fromCustomAction`
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.CustomAction#getAction():
+    Missing nullability on method `getAction` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.CustomAction#getCustomAction():
+    Missing nullability on method `getCustomAction` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.CustomAction#getExtras():
+    Missing nullability on method `getExtras` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.CustomAction#getName():
+    Missing nullability on method `getName` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.CustomAction#toString():
+    Missing nullability on method `toString` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.CustomAction#writeToParcel(android.os.Parcel, int) parameter #0:
+    Missing nullability on parameter `dest` in method `writeToParcel`
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.CustomAction.Builder#Builder(String, CharSequence, int) parameter #0:
+    Missing nullability on parameter `action` in method `Builder`
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.CustomAction.Builder#Builder(String, CharSequence, int) parameter #1:
+    Missing nullability on parameter `name` in method `Builder`
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.CustomAction.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.CustomAction.Builder#setExtras(android.os.Bundle):
+    Missing nullability on method `setExtras` return
+MissingNullability: android.support.v4.media.session.PlaybackStateCompat.CustomAction.Builder#setExtras(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `extras` in method `setExtras`
+MissingNullability: androidx.media.AudioAttributesCompat#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.media.AudioAttributesCompat#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.media.AudioAttributesCompat.Builder#Builder(androidx.media.AudioAttributesCompat) parameter #0:
+    Missing nullability on parameter `aa` in method `Builder`
+MissingNullability: androidx.media.AudioAttributesCompat.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.media.AudioAttributesCompat.Builder#setContentType(int):
+    Missing nullability on method `setContentType` return
+MissingNullability: androidx.media.AudioAttributesCompat.Builder#setFlags(int):
+    Missing nullability on method `setFlags` return
+MissingNullability: androidx.media.AudioAttributesCompat.Builder#setLegacyStreamType(int):
+    Missing nullability on method `setLegacyStreamType` return
+MissingNullability: androidx.media.AudioAttributesCompat.Builder#setUsage(int):
+    Missing nullability on method `setUsage` return
+MissingNullability: androidx.media.AudioFocusRequestCompat#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.media.AudioFocusRequestCompat.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.media.MediaBrowserServiceCompat#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
+    Missing nullability on parameter `fd` in method `dump`
+MissingNullability: androidx.media.MediaBrowserServiceCompat#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
+    Missing nullability on parameter `writer` in method `dump`
+MissingNullability: androidx.media.MediaBrowserServiceCompat#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2:
+    Missing nullability on parameter `args` in method `dump`
+MissingNullability: androidx.media.MediaBrowserServiceCompat#getBrowserRootHints():
+    Missing nullability on method `getBrowserRootHints` return
+MissingNullability: androidx.media.MediaBrowserServiceCompat#onBind(android.content.Intent):
+    Missing nullability on method `onBind` return
+MissingNullability: androidx.media.MediaBrowserServiceCompat#onBind(android.content.Intent) parameter #0:
+    Missing nullability on parameter `intent` in method `onBind`
+MissingNullability: androidx.media.MediaBrowserServiceCompat#onCustomAction(String, android.os.Bundle, androidx.media.MediaBrowserServiceCompat.Result<android.os.Bundle>) parameter #1:
+    Missing nullability on parameter `extras` in method `onCustomAction`
+MissingNullability: androidx.media.MediaBrowserServiceCompat#onLoadItem(String, androidx.media.MediaBrowserServiceCompat.Result<android.support.v4.media.MediaBrowserCompat.MediaItem>) parameter #0:
+    Missing nullability on parameter `itemId` in method `onLoadItem`
+MissingNullability: androidx.media.MediaBrowserServiceCompat#onSearch(String, android.os.Bundle, androidx.media.MediaBrowserServiceCompat.Result<java.util.List<android.support.v4.media.MediaBrowserCompat.MediaItem>>) parameter #1:
+    Missing nullability on parameter `extras` in method `onSearch`
+MissingNullability: androidx.media.MediaBrowserServiceCompat#setSessionToken(android.support.v4.media.session.MediaSessionCompat.Token) parameter #0:
+    Missing nullability on parameter `token` in method `setSessionToken`
+MissingNullability: androidx.media.MediaBrowserServiceCompat.BrowserRoot#getExtras():
+    Missing nullability on method `getExtras` return
+MissingNullability: androidx.media.MediaBrowserServiceCompat.BrowserRoot#getRootId():
+    Missing nullability on method `getRootId` return
+MissingNullability: androidx.media.MediaBrowserServiceCompat.Result#sendError(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `extras` in method `sendError`
+MissingNullability: androidx.media.MediaBrowserServiceCompat.Result#sendProgressUpdate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `extras` in method `sendProgressUpdate`
+MissingNullability: androidx.media.VolumeProviderCompat#getVolumeProvider():
+    Missing nullability on method `getVolumeProvider` return
+MissingNullability: androidx.media.VolumeProviderCompat#setCallback(androidx.media.VolumeProviderCompat.Callback) parameter #0:
+    Missing nullability on parameter `callback` in method `setCallback`
+MissingNullability: androidx.media.VolumeProviderCompat.Callback#onVolumeChanged(androidx.media.VolumeProviderCompat) parameter #0:
+    Missing nullability on parameter `volumeProvider` in method `onVolumeChanged`
+MissingNullability: androidx.media.app.NotificationCompat.MediaStyle#MediaStyle(androidx.core.app.NotificationCompat.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `MediaStyle`
+MissingNullability: androidx.media.app.NotificationCompat.MediaStyle#getMediaSession(android.app.Notification):
+    Missing nullability on method `getMediaSession` return
+MissingNullability: androidx.media.app.NotificationCompat.MediaStyle#getMediaSession(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notification` in method `getMediaSession`
+MissingNullability: androidx.media.app.NotificationCompat.MediaStyle#setCancelButtonIntent(android.app.PendingIntent):
+    Missing nullability on method `setCancelButtonIntent` return
+MissingNullability: androidx.media.app.NotificationCompat.MediaStyle#setCancelButtonIntent(android.app.PendingIntent) parameter #0:
+    Missing nullability on parameter `pendingIntent` in method `setCancelButtonIntent`
+MissingNullability: androidx.media.app.NotificationCompat.MediaStyle#setMediaSession(android.support.v4.media.session.MediaSessionCompat.Token):
+    Missing nullability on method `setMediaSession` return
+MissingNullability: androidx.media.app.NotificationCompat.MediaStyle#setMediaSession(android.support.v4.media.session.MediaSessionCompat.Token) parameter #0:
+    Missing nullability on parameter `token` in method `setMediaSession`
+MissingNullability: androidx.media.app.NotificationCompat.MediaStyle#setShowActionsInCompactView(int...):
+    Missing nullability on method `setShowActionsInCompactView` return
+MissingNullability: androidx.media.app.NotificationCompat.MediaStyle#setShowActionsInCompactView(int...) parameter #0:
+    Missing nullability on parameter `actions` in method `setShowActionsInCompactView`
+MissingNullability: androidx.media.app.NotificationCompat.MediaStyle#setShowCancelButton(boolean):
+    Missing nullability on method `setShowCancelButton` return
+MissingNullability: androidx.media.session.MediaButtonReceiver#buildMediaButtonPendingIntent(android.content.Context, android.content.ComponentName, long):
+    Missing nullability on method `buildMediaButtonPendingIntent` return
+MissingNullability: androidx.media.session.MediaButtonReceiver#buildMediaButtonPendingIntent(android.content.Context, android.content.ComponentName, long) parameter #0:
+    Missing nullability on parameter `context` in method `buildMediaButtonPendingIntent`
+MissingNullability: androidx.media.session.MediaButtonReceiver#buildMediaButtonPendingIntent(android.content.Context, android.content.ComponentName, long) parameter #1:
+    Missing nullability on parameter `mbrComponent` in method `buildMediaButtonPendingIntent`
+MissingNullability: androidx.media.session.MediaButtonReceiver#buildMediaButtonPendingIntent(android.content.Context, long):
+    Missing nullability on method `buildMediaButtonPendingIntent` return
+MissingNullability: androidx.media.session.MediaButtonReceiver#buildMediaButtonPendingIntent(android.content.Context, long) parameter #0:
+    Missing nullability on parameter `context` in method `buildMediaButtonPendingIntent`
+MissingNullability: androidx.media.session.MediaButtonReceiver#handleIntent(android.support.v4.media.session.MediaSessionCompat, android.content.Intent):
+    Missing nullability on method `handleIntent` return
+MissingNullability: androidx.media.session.MediaButtonReceiver#handleIntent(android.support.v4.media.session.MediaSessionCompat, android.content.Intent) parameter #0:
+    Missing nullability on parameter `mediaSessionCompat` in method `handleIntent`
+MissingNullability: androidx.media.session.MediaButtonReceiver#handleIntent(android.support.v4.media.session.MediaSessionCompat, android.content.Intent) parameter #1:
+    Missing nullability on parameter `intent` in method `handleIntent`
+MissingNullability: androidx.media.session.MediaButtonReceiver#onReceive(android.content.Context, android.content.Intent) parameter #0:
+    Missing nullability on parameter `context` in method `onReceive`
+MissingNullability: androidx.media.session.MediaButtonReceiver#onReceive(android.content.Context, android.content.Intent) parameter #1:
+    Missing nullability on parameter `intent` in method `onReceive`
+
+
 NoClone: androidx.media.MediaBrowserServiceCompat#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
     Must use ParcelFileDescriptor instead of FileDescriptor in parameter fd in androidx.media.MediaBrowserServiceCompat.dump(java.io.FileDescriptor fd, java.io.PrintWriter writer, String[] args)
 
diff --git a/media/api/restricted_1.2.0-alpha01.ignore b/media/api/restricted_1.2.0-alpha01.ignore
new file mode 100644
index 0000000..de0edac
--- /dev/null
+++ b/media/api/restricted_1.2.0-alpha01.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+ChangedThrows: android.support.v4.media.session.MediaControllerCompat#MediaControllerCompat(android.content.Context, android.support.v4.media.session.MediaSessionCompat.Token):
+    Constructor android.support.v4.media.session.MediaControllerCompat no longer throws exception android.os.RemoteException
diff --git a/media/src/main/java/android/support/v4/media/MediaBrowserCompat.java b/media/src/main/java/android/support/v4/media/MediaBrowserCompat.java
index 4ec5200..f3f9fc1 100644
--- a/media/src/main/java/android/support/v4/media/MediaBrowserCompat.java
+++ b/media/src/main/java/android/support/v4/media/MediaBrowserCompat.java
@@ -2272,7 +2272,9 @@
 
         @Override
         protected void onReceiveResult(int resultCode, Bundle resultData) {
-            MediaSessionCompat.ensureClassLoader(resultData);
+            if (resultData != null) {
+                resultData = MediaSessionCompat.unparcelWithClassLoader(resultData);
+            }
             if (resultCode != MediaBrowserServiceCompat.RESULT_OK || resultData == null
                     || !resultData.containsKey(MediaBrowserServiceCompat.KEY_MEDIA_ITEM)) {
                 mCallback.onError(mMediaId);
@@ -2302,7 +2304,9 @@
 
         @Override
         protected void onReceiveResult(int resultCode, Bundle resultData) {
-            MediaSessionCompat.ensureClassLoader(resultData);
+            if (resultData != null) {
+                resultData = MediaSessionCompat.unparcelWithClassLoader(resultData);
+            }
             if (resultCode != MediaBrowserServiceCompat.RESULT_OK || resultData == null
                     || !resultData.containsKey(MediaBrowserServiceCompat.KEY_SEARCH_RESULTS)) {
                 mCallback.onError(mQuery, mExtras);
@@ -2310,14 +2314,15 @@
             }
             Parcelable[] items = resultData.getParcelableArray(
                     MediaBrowserServiceCompat.KEY_SEARCH_RESULTS);
-            List<MediaItem> results = null;
             if (items != null) {
-                results = new ArrayList<>();
+                List<MediaItem> results = new ArrayList<>();
                 for (Parcelable item : items) {
                     results.add((MediaItem) item);
                 }
+                mCallback.onSearchResult(mQuery, mExtras, results);
+            } else {
+                mCallback.onError(mQuery, mExtras);
             }
-            mCallback.onSearchResult(mQuery, mExtras, results);
         }
     }
 
diff --git a/media/src/main/java/android/support/v4/media/MediaDescriptionCompat.java b/media/src/main/java/android/support/v4/media/MediaDescriptionCompat.java
index a4734db..07b3dcc 100644
--- a/media/src/main/java/android/support/v4/media/MediaDescriptionCompat.java
+++ b/media/src/main/java/android/support/v4/media/MediaDescriptionCompat.java
@@ -38,6 +38,8 @@
  */
 @SuppressLint("BanParcelableUsage")
 public final class MediaDescriptionCompat implements Parcelable {
+    private static final String TAG = "MediaDescriptionCompat";
+
     /**
      * Used as a long extra field to indicate the bluetooth folder type of the media item as
      * specified in the section 6.10.2.2 of the Bluetooth AVRCP 1.5. This is valid only for
@@ -385,9 +387,11 @@
             bob.setIconBitmap(description.getIconBitmap());
             bob.setIconUri(description.getIconUri());
             Bundle extras = description.getExtras();
+            if (extras != null) {
+                extras = MediaSessionCompat.unparcelWithClassLoader(extras);
+            }
             Uri mediaUri = null;
             if (extras != null) {
-                MediaSessionCompat.ensureClassLoader(extras);
                 mediaUri = extras.getParcelable(DESCRIPTION_KEY_MEDIA_URI);
             }
             if (mediaUri != null) {
diff --git a/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java b/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
index bbf6980..9efb6d0 100644
--- a/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
+++ b/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
@@ -1055,7 +1055,7 @@
     }
 
     /**
-     * A helper method for setting the class loader to {@link Bundle} objects.
+     * A helper method for setting the application class loader to the given {@link Bundle}.
      *
      * @hide
      */
@@ -1066,6 +1066,30 @@
         }
     }
 
+    /**
+     * Tries to unparcel the given {@link Bundle} with the application class loader and
+     * returns {@code null} if a {@link BadParcelableException} is thrown while unparcelling,
+     * otherwise the given bundle in which the application class loader is set.
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY)
+    @Nullable
+    public static Bundle unparcelWithClassLoader(@Nullable Bundle bundle) {
+        if (bundle == null) {
+            return null;
+        }
+        ensureClassLoader(bundle);
+        try {
+            bundle.isEmpty(); // to call unparcel()
+            return bundle;
+        } catch (BadParcelableException e) {
+            // The exception details will be logged by Parcel class.
+            Log.e(TAG, "Could not unparcel the data.");
+            return null;
+        }
+    }
+
     @SuppressWarnings("WeakerAccess") /* synthetic access */
     static PlaybackStateCompat getStateWithUpdatedPosition(
             PlaybackStateCompat state, MediaMetadataCompat metadata) {
@@ -1663,40 +1687,53 @@
             public void onCustomAction(String action, Bundle extras) {
                 ensureClassLoader(extras);
                 setCurrentControllerInfo();
-                Bundle bundle = extras.getBundle(ACTION_ARGUMENT_EXTRAS);
-                ensureClassLoader(bundle);
 
-                if (action.equals(ACTION_PLAY_FROM_URI)) {
-                    Uri uri = extras.getParcelable(ACTION_ARGUMENT_URI);
-                    Callback.this.onPlayFromUri(uri, bundle);
-                } else if (action.equals(ACTION_PREPARE)) {
-                    Callback.this.onPrepare();
-                } else if (action.equals(ACTION_PREPARE_FROM_MEDIA_ID)) {
-                    String mediaId = extras.getString(ACTION_ARGUMENT_MEDIA_ID);
-                    Callback.this.onPrepareFromMediaId(mediaId, bundle);
-                } else if (action.equals(ACTION_PREPARE_FROM_SEARCH)) {
-                    String query = extras.getString(ACTION_ARGUMENT_QUERY);
-                    Callback.this.onPrepareFromSearch(query, bundle);
-                } else if (action.equals(ACTION_PREPARE_FROM_URI)) {
-                    Uri uri = extras.getParcelable(ACTION_ARGUMENT_URI);
-                    Callback.this.onPrepareFromUri(uri, bundle);
-                } else if (action.equals(ACTION_SET_CAPTIONING_ENABLED)) {
-                    boolean enabled = extras.getBoolean(ACTION_ARGUMENT_CAPTIONING_ENABLED);
-                    Callback.this.onSetCaptioningEnabled(enabled);
-                } else if (action.equals(ACTION_SET_REPEAT_MODE)) {
-                    int repeatMode = extras.getInt(ACTION_ARGUMENT_REPEAT_MODE);
-                    Callback.this.onSetRepeatMode(repeatMode);
-                } else if (action.equals(ACTION_SET_SHUFFLE_MODE)) {
-                    int shuffleMode = extras.getInt(ACTION_ARGUMENT_SHUFFLE_MODE);
-                    Callback.this.onSetShuffleMode(shuffleMode);
-                } else if (action.equals(ACTION_SET_RATING)) {
-                    RatingCompat rating = extras.getParcelable(ACTION_ARGUMENT_RATING);
-                    Callback.this.onSetRating(rating, bundle);
-                } else if (action.equals(ACTION_SET_PLAYBACK_SPEED)) {
-                    float speed = extras.getFloat(ACTION_ARGUMENT_PLAYBACK_SPEED, 1.0f);
-                    Callback.this.onSetPlaybackSpeed(speed);
-                } else {
-                    Callback.this.onCustomAction(action, extras);
+                try {
+                    if (action.equals(ACTION_PLAY_FROM_URI)) {
+                        Uri uri = extras.getParcelable(ACTION_ARGUMENT_URI);
+                        Bundle bundle = extras.getBundle(ACTION_ARGUMENT_EXTRAS);
+                        ensureClassLoader(bundle);
+                        Callback.this.onPlayFromUri(uri, bundle);
+                    } else if (action.equals(ACTION_PREPARE)) {
+                        Callback.this.onPrepare();
+                    } else if (action.equals(ACTION_PREPARE_FROM_MEDIA_ID)) {
+                        String mediaId = extras.getString(ACTION_ARGUMENT_MEDIA_ID);
+                        Bundle bundle = extras.getBundle(ACTION_ARGUMENT_EXTRAS);
+                        ensureClassLoader(bundle);
+                        Callback.this.onPrepareFromMediaId(mediaId, bundle);
+                    } else if (action.equals(ACTION_PREPARE_FROM_SEARCH)) {
+                        String query = extras.getString(ACTION_ARGUMENT_QUERY);
+                        Bundle bundle = extras.getBundle(ACTION_ARGUMENT_EXTRAS);
+                        ensureClassLoader(bundle);
+                        Callback.this.onPrepareFromSearch(query, bundle);
+                    } else if (action.equals(ACTION_PREPARE_FROM_URI)) {
+                        Uri uri = extras.getParcelable(ACTION_ARGUMENT_URI);
+                        Bundle bundle = extras.getBundle(ACTION_ARGUMENT_EXTRAS);
+                        ensureClassLoader(bundle);
+                        Callback.this.onPrepareFromUri(uri, bundle);
+                    } else if (action.equals(ACTION_SET_CAPTIONING_ENABLED)) {
+                        boolean enabled = extras.getBoolean(ACTION_ARGUMENT_CAPTIONING_ENABLED);
+                        Callback.this.onSetCaptioningEnabled(enabled);
+                    } else if (action.equals(ACTION_SET_REPEAT_MODE)) {
+                        int repeatMode = extras.getInt(ACTION_ARGUMENT_REPEAT_MODE);
+                        Callback.this.onSetRepeatMode(repeatMode);
+                    } else if (action.equals(ACTION_SET_SHUFFLE_MODE)) {
+                        int shuffleMode = extras.getInt(ACTION_ARGUMENT_SHUFFLE_MODE);
+                        Callback.this.onSetShuffleMode(shuffleMode);
+                    } else if (action.equals(ACTION_SET_RATING)) {
+                        RatingCompat rating = extras.getParcelable(ACTION_ARGUMENT_RATING);
+                        Bundle bundle = extras.getBundle(ACTION_ARGUMENT_EXTRAS);
+                        ensureClassLoader(bundle);
+                        Callback.this.onSetRating(rating, bundle);
+                    } else if (action.equals(ACTION_SET_PLAYBACK_SPEED)) {
+                        float speed = extras.getFloat(ACTION_ARGUMENT_PLAYBACK_SPEED, 1.0f);
+                        Callback.this.onSetPlaybackSpeed(speed);
+                    } else {
+                        Callback.this.onCustomAction(action, extras);
+                    }
+                } catch (BadParcelableException e) {
+                    // The exception details will be logged by Parcel class.
+                    Log.e(TAG, "Could not unparcel the data.");
                 }
                 clearCurrentControllerInfo();
             }
diff --git a/media/src/main/java/android/support/v4/media/session/PlaybackStateCompat.java b/media/src/main/java/android/support/v4/media/session/PlaybackStateCompat.java
index 164a459..c0fa895 100644
--- a/media/src/main/java/android/support/v4/media/session/PlaybackStateCompat.java
+++ b/media/src/main/java/android/support/v4/media/session/PlaybackStateCompat.java
@@ -808,6 +808,7 @@
             Bundle extras;
             if (Build.VERSION.SDK_INT >= 22) {
                 extras = stateFwk.getExtras();
+                MediaSessionCompat.ensureClassLoader(extras);
             } else {
                 extras = null;
             }
@@ -932,12 +933,14 @@
 
             PlaybackState.CustomAction customActionFwk =
                     (PlaybackState.CustomAction) customActionObj;
+            Bundle extras = customActionFwk.getExtras();
+            MediaSessionCompat.ensureClassLoader(extras);
             PlaybackStateCompat.CustomAction customActionCompat =
                     new PlaybackStateCompat.CustomAction(
                             customActionFwk.getAction(),
                             customActionFwk.getName(),
                             customActionFwk.getIcon(),
-                            customActionFwk.getExtras());
+                            extras);
             customActionCompat.mCustomActionFwk = customActionFwk;
             return customActionCompat;
         }
diff --git a/media/src/main/java/androidx/media/AudioAttributesCompat.java b/media/src/main/java/androidx/media/AudioAttributesCompat.java
index 7337f93..aaa848f0 100644
--- a/media/src/main/java/androidx/media/AudioAttributesCompat.java
+++ b/media/src/main/java/androidx/media/AudioAttributesCompat.java
@@ -234,8 +234,11 @@
 
     static final int INVALID_STREAM_TYPE = -1;  // AudioSystem.STREAM_DEFAULT
 
+    /** @hide */
+    // It should be public to allow Parcelizers which never be de/jetified can access the field.
+    @RestrictTo(LIBRARY)
     @ParcelField(1)
-    AudioAttributesImpl mImpl;
+    public AudioAttributesImpl mImpl;
 
     AudioAttributesCompat() {
     }
diff --git a/media/src/main/java/androidx/media/AudioAttributesImplApi21.java b/media/src/main/java/androidx/media/AudioAttributesImplApi21.java
index bddc8a6..a9eae82 100644
--- a/media/src/main/java/androidx/media/AudioAttributesImplApi21.java
+++ b/media/src/main/java/androidx/media/AudioAttributesImplApi21.java
@@ -34,11 +34,17 @@
 public class AudioAttributesImplApi21 implements AudioAttributesImpl {
     private static final String TAG = "AudioAttributesCompat21";
 
+    /** @hide */
+    // It should be public to allow Parcelizers which never be de/jetified can access the field.
+    @RestrictTo(LIBRARY)
     @ParcelField(1)
-    AudioAttributes mAudioAttributes;
+    public AudioAttributes mAudioAttributes;
 
+    /** @hide */
+    // It should be public to allow Parcelizers which never be de/jetified can access the field.
+    @RestrictTo(LIBRARY)
     @ParcelField(2)
-    int mLegacyStreamType = INVALID_STREAM_TYPE;
+    public int mLegacyStreamType = INVALID_STREAM_TYPE;
 
     /**
      * Used for VersionedParcelable
diff --git a/media/src/main/java/androidx/media/AudioAttributesImplBase.java b/media/src/main/java/androidx/media/AudioAttributesImplBase.java
index 6525ab6..2b4bfeb 100644
--- a/media/src/main/java/androidx/media/AudioAttributesImplBase.java
+++ b/media/src/main/java/androidx/media/AudioAttributesImplBase.java
@@ -52,14 +52,29 @@
 @VersionedParcelize(jetifyAs = "android.support.v4.media.AudioAttributesImplBase")
 @RestrictTo(LIBRARY)
 public class AudioAttributesImplBase implements AudioAttributesImpl {
+    /** @hide */
+    // It should be public to allow Parcelizers which never be de/jetified can access the field.
+    @RestrictTo(LIBRARY)
     @ParcelField(1)
-    int mUsage = USAGE_UNKNOWN;
+    public int mUsage = USAGE_UNKNOWN;
+
+    /** @hide */
+    // It should be public to allow Parcelizers which never be de/jetified can access the field.
+    @RestrictTo(LIBRARY)
     @ParcelField(2)
-    int mContentType = CONTENT_TYPE_UNKNOWN;
+    public int mContentType = CONTENT_TYPE_UNKNOWN;
+
+    /** @hide */
+    // It should be public to allow Parcelizers which never be de/jetified can access the field.
+    @RestrictTo(LIBRARY)
     @ParcelField(3)
-    int mFlags = 0x0;
+    public int mFlags = 0x0;
+
+    /** @hide */
+    // It should be public to allow Parcelizers which never be de/jetified can access the field.
+    @RestrictTo(LIBRARY)
     @ParcelField(4)
-    int mLegacyStream = INVALID_STREAM_TYPE;
+    public int mLegacyStream = INVALID_STREAM_TYPE;
 
     /**
      * Used for VersionedParcelable
diff --git a/media/version-compat-tests/runtest.sh b/media/version-compat-tests/runtest.sh
index 7084c42..72b919e 100755
--- a/media/version-compat-tests/runtest.sh
+++ b/media/version-compat-tests/runtest.sh
@@ -56,11 +56,11 @@
   ./gradlew $SERVICE_MODULE_NAME:assembleDebugAndroidTest || { echo "Build failed. Aborting."; exit 1; }
 
   echo "Installing the test apks"
-  adb $DEVICE_SERIAL install -r "../../out/dist/apks/$CLIENT_MODULE_NAME.apk" || { echo "Apk installation failed. Aborting."; exit 1; }
-  adb $DEVICE_SERIAL install -r "../../out/dist/apks/$SERVICE_MODULE_NAME.apk" || { echo "Apk installation failed. Aborting."; exit 1; }
+  $ADB $DEVICE_SERIAL install -r "../../out/dist/apks/$CLIENT_MODULE_NAME.apk" || { echo "Apk installation failed. Aborting."; exit 1; }
+  $ADB $DEVICE_SERIAL install -r "../../out/dist/apks/$SERVICE_MODULE_NAME.apk" || { echo "Apk installation failed. Aborting."; exit 1; }
 
   echo "Running the tests"
-  local test_command="adb $DEVICE_SERIAL shell am instrument -w -e debug false -e client_version $CLIENT_VERSION -e service_version $SERVICE_VERSION"
+  local test_command="$ADB $DEVICE_SERIAL shell am instrument -w -e debug false -e client_version $CLIENT_VERSION -e service_version $SERVICE_VERSION"
   local client_test_runner="android.support.mediacompat.client.test/androidx.test.runner.AndroidJUnitRunner"
   local service_test_runner="android.support.mediacompat.service.test/androidx.test.runner.AndroidJUnitRunner"
 
@@ -88,6 +88,18 @@
   exit 1;
 fi
 
+if [ "`uname`" == "Darwin" ]; then
+  PLATFORM="darwin"
+else
+  PLATFORM="linux"
+fi
+ADB="../../prebuilts/fullsdk-$PLATFORM/platform-tools/adb"
+if [ ! -f "$ADB" ]; then
+  echo "adb not found at $ADB, finding adb in \$PATH..." 1>&2
+  command -v adb > /dev/null 2>&1 || { echo "adb not found in \$PATH" 1>&2; exit 1; }
+  ADB="adb"
+fi
+
 case ${1} in
   1|2|3|4)
     VERSION_COMBINATION=${1}
diff --git a/media2/common/api/api_lint.ignore b/media2/common/api/api_lint.ignore
index 42cac4b..24d306d 100644
--- a/media2/common/api/api_lint.ignore
+++ b/media2/common/api/api_lint.ignore
@@ -5,3 +5,9 @@
 
 IntentName: androidx.media2.common.MediaMetadata#METADATA_KEY_EXTRAS:
     Intent extra constant name must be EXTRA_FOO: METADATA_KEY_EXTRAS
+
+
+MissingNullability: androidx.media2.common.MediaItem#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.media2.common.MediaMetadata#toString():
+    Missing nullability on method `toString` return
diff --git a/media2/common/src/main/java/androidx/media2/common/SessionPlayer.java b/media2/common/src/main/java/androidx/media2/common/SessionPlayer.java
index c67153a..848da58 100644
--- a/media2/common/src/main/java/androidx/media2/common/SessionPlayer.java
+++ b/media2/common/src/main/java/androidx/media2/common/SessionPlayer.java
@@ -343,6 +343,9 @@
     /**
      * Seeks to the specified position. Moves the playback head to the specified position.
      * <p>
+     * The position is the relative position based on the {@link MediaItem#getStartPosition()}. So
+     * calling {@link #seekTo(long)} with {@code 0} means the seek to the start position.
+     * <p>
      * On success, a {@link PlayerResult} should be returned with the current media item when the
      * command completed. If it's called in {@link #PLAYER_STATE_IDLE}, it is ignored and
      * a {@link PlayerResult} should be returned with
@@ -405,13 +408,18 @@
 
     /**
      * Gets the current playback head position.
+     * <p>
+     * The position is the relative position based on the {@link MediaItem#getStartPosition()}.
+     * So the position {@code 0} means the start position of the {@link MediaItem}.
      *
      * @return the current playback position in ms, or {@link #UNKNOWN_TIME} if unknown.
      */
     public abstract long getCurrentPosition();
 
     /**
-     * Gets the duration of the current media item, or {@link #UNKNOWN_TIME} if unknown.
+     * Gets the duration of the current media item, or {@link #UNKNOWN_TIME} if unknown. If the
+     * current {@link MediaItem} has either start or end position, then duration would be adjusted
+     * accordingly instead of returning the whole size of the {@link MediaItem}.
      *
      * @return the duration in ms, or {@link #UNKNOWN_TIME}.
      */
@@ -419,6 +427,9 @@
 
     /**
      * Gets the position for how much has been buffered, or {@link #UNKNOWN_TIME} if unknown.
+     * <p>
+     * The position is the relative position based on the {@link MediaItem#getStartPosition()}.
+     * So the position {@code 0} means the start position of the {@link MediaItem}.
      *
      * @return the buffered position in ms, or {@link #UNKNOWN_TIME}.
      */
diff --git a/media2/player/api/api_lint.ignore b/media2/player/api/api_lint.ignore
index 821e3a3..825649f 100644
--- a/media2/player/api/api_lint.ignore
+++ b/media2/player/api/api_lint.ignore
@@ -9,3 +9,19 @@
 
 GenericException: androidx.media2.player.MediaPlayer#close():
     Methods must not throw generic exceptions (`java.lang.Exception`)
+
+
+MissingNullability: androidx.media2.player.MediaPlayer.TrackInfo#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.media2.player.MediaPlayer.TrackInfo#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.media2.player.MediaTimestamp#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.media2.player.MediaTimestamp#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.media2.player.TimedMetaData#getMetaData():
+    Missing nullability on method `getMetaData` return
+MissingNullability: androidx.media2.player.VideoSize#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.media2.player.VideoSize#toString():
+    Missing nullability on method `toString` return
diff --git a/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayer2StateTest.java b/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayer2StateTest.java
index 8926f13..8aeb61f 100644
--- a/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayer2StateTest.java
+++ b/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayer2StateTest.java
@@ -1122,20 +1122,20 @@
         }
         setupPlayer();
 
-        final List<Pair<Integer, Integer>> callCompletes = new ArrayList();
+        final List<Pair<Integer, Integer>> callCompletes = new ArrayList<>();
         final Monitor callCompleteCalled = new Monitor();
         final Monitor commandLabelReachedCalled = new Monitor();
         MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onCallCompleted(
                     MediaPlayer2 mp, MediaItem item, int what, int status) {
-                callCompletes.add(new Pair<Integer, Integer>(what, status));
+                callCompletes.add(new Pair<>(what, status));
                 callCompleteCalled.signal();
             }
 
             @Override
             public void onCommandLabelReached(MediaPlayer2 mp, Object label) {
-                callCompletes.add(new Pair<Integer, Integer>(
+                callCompletes.add(new Pair<>(
                             CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED,
                             CALL_STATUS_NO_ERROR));
                 callCompleteCalled.signal();
diff --git a/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayer2Test.java b/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayer2Test.java
index b8fefc9..8587e0e 100644
--- a/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayer2Test.java
+++ b/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayer2Test.java
@@ -2641,7 +2641,7 @@
         final int resid2 = R.raw.testvideo;
         final long start2 = 3000;
         final long end2 = 5000;
-        final int expectedDuration2 = 11047;
+        final int expectedDuration2 = 2000;
         MediaItem item2;
         try (AssetFileDescriptor afd2 = mResources.openRawResourceFd(resid2)) {
             item2 = new FileMediaItem.Builder(
@@ -2656,9 +2656,6 @@
         mPlayer.setMediaItem(item1);
         mPlayer.setNextMediaItem(item2);
         mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
-
-        final Monitor seekDone = new Monitor();
-        final int[] seekResults = new int[1];
         MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, MediaItem item, int what, int extra) {
@@ -2675,9 +2672,6 @@
                 if (what == MediaPlayer2.CALL_COMPLETED_PLAY) {
                     assertTrue(status == MediaPlayer2.CALL_STATUS_NO_ERROR);
                     mOnPlayCalled.signal();
-                } else if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO) {
-                    seekResults[0] = status;
-                    seekDone.signal();
                 }
             }
         };
@@ -2693,25 +2687,13 @@
         mOnCompletionCalled.reset();
         mPlayer.play();
         mOnPlayCalled.waitForSignal();
-        assertTrue(mPlayer.getCurrentPosition() >= start1);
-
         mOnCompletionCalled.waitForSignal();
-        assertTrue(mPlayer.getCurrentPosition() >= start2);
         mPlayer.setPlaybackParams(new PlaybackParams.Builder().setSpeed(0.5f).build());
-
         mOnCompletionCalled.reset();
         mOnCompletionCalled.waitForSignal();
-        assertTrue(Math.abs(mPlayer.getCurrentPosition() - end2) < PLAYBACK_COMPLETE_TOLERANCE_MS);
-
-        seekDone.reset();
-        mPlayer.seekTo(start2 - 1000);
-        seekDone.waitForSignal();
-        assertEquals(MediaPlayer2.CALL_STATUS_BAD_VALUE, seekResults[0]);
-
-        mPlayer.seekTo(end2 + 1000);
-        seekDone.waitForSignal();
-        assertEquals(MediaPlayer2.CALL_STATUS_BAD_VALUE, seekResults[0]);
-
+        assertTrue(
+                Math.abs(mPlayer.getCurrentPosition() - expectedDuration2)
+                        < PLAYBACK_COMPLETE_TOLERANCE_MS);
         assertEquals(expectedDuration2, mPlayer.getDuration());
     }
 
@@ -2722,6 +2704,7 @@
         final int resid = R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz;
         final long start = 6000;
         final long end = 8000;
+        final long expectedDuration = 2000;
         MediaItem item;
         try (AssetFileDescriptor afd = mResources.openRawResourceFd(resid)) {
             item = new FileMediaItem.Builder(
@@ -2772,22 +2755,17 @@
         mPlayer.play();
         mOnPlayCalled.waitForSignal();
         assertEquals(MediaPlayer2.PLAYER_STATE_PLAYING, mPlayer.getState());
-        assertTrue(mPlayer.getCurrentPosition() >= start);
-
         onDataSourceRepeatCalled.waitForSignal();
         assertEquals(MediaPlayer2.PLAYER_STATE_PLAYING, mPlayer.getState());
-        assertTrue(mPlayer.getCurrentPosition() >= start);
-        onDataSourceRepeatCalled.waitForCountedSignals(2);
-        assertEquals(MediaPlayer2.PLAYER_STATE_PLAYING, mPlayer.getState());
-        assertTrue(mPlayer.getCurrentPosition() >= start);
-
         mOnCompletionCalled.reset();
         mPlayer.loopCurrent(false);
         mOnCompletionCalled.waitForSignal();
         assertEquals(MediaPlayer2.PLAYER_STATE_PAUSED, mPlayer.getState());
         long pos = mPlayer.getCurrentPosition();
-        assertTrue("current pos (" + pos + "us) does not match requested pos (" + end + "us).",
-                Math.abs(pos - end) < PLAYBACK_COMPLETE_TOLERANCE_MS);
+        assertTrue(
+                "current pos (" + pos + " ms) does not match requested pos ("
+                        + expectedDuration + " ms).",
+                Math.abs(pos - expectedDuration) < PLAYBACK_COMPLETE_TOLERANCE_MS);
     }
 
     @Test
diff --git a/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayerTest.java b/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayerTest.java
index 00e85db..2ac01a3 100644
--- a/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayerTest.java
+++ b/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayerTest.java
@@ -55,10 +55,9 @@
 import androidx.test.filters.MediumTest;
 import androidx.test.filters.SdkSuppress;
 
-import com.google.common.util.concurrent.ListenableFuture;
-
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -68,6 +67,7 @@
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.BlockingDeque;
+import java.util.concurrent.Future;
 import java.util.concurrent.LinkedBlockingDeque;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
@@ -77,7 +77,7 @@
     private static final String LOG_TAG = "MediaPlayerTest";
 
     private static final int SLEEP_TIME = 1000;
-    private static final int WAIT_TIME_MS = 300;
+    private static final long WAIT_TIME_MS = 300;
     private static final float FLOAT_TOLERANCE = .0001f;
     private static final int INVALID_SHUFFLE_MODE = -1000;
     private static final int INVALID_REPEAT_MODE = -1000;
@@ -109,12 +109,13 @@
     @Test
     @MediumTest
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
+    @Ignore("Test disabled due to flakiness, see b/138474897")
     public void testPlayAudioOnce() throws Exception {
         assertTrue(loadResource(R.raw.testmp3_2));
         AudioAttributesCompat attributes = new AudioAttributesCompat.Builder()
                 .setLegacyStreamType(AudioManager.STREAM_MUSIC)
                 .build();
-        mPlayer.setAudioAttributes(attributes);
+        Future<PlayerResult> setAttrFuture = mPlayer.setAudioAttributes(attributes);
 
         final TestUtils.Monitor playing = new TestUtils.Monitor();
         mPlayer.registerPlayerCallback(mExecutor, new SessionPlayer.PlayerCallback() {
@@ -124,10 +125,13 @@
             }
         });
 
-        mPlayer.prepare();
-        mPlayer.play();
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
+        Future<PlayerResult> playFuture = mPlayer.play();
 
         assertTrue(playing.waitForSignal(SLEEP_TIME));
+        assertFutureSuccess(setAttrFuture);
+        assertFutureSuccess(prepareFuture);
+        assertFutureSuccess(playFuture);
     }
 
     @Test
@@ -139,8 +143,9 @@
         final int tolerance = 100;
         final int seekDuration = 100;
 
+        Future<PlayerResult> setItemFuture;
         try (AssetFileDescriptor afd = mResources.openRawResourceFd(resid)) {
-            mPlayer.setMediaItem(new FileMediaItem.Builder(
+            setItemFuture = mPlayer.setMediaItem(new FileMediaItem.Builder(
                     ParcelFileDescriptor.dup(afd.getFileDescriptor()))
                     .setFileDescriptorOffset(afd.getStartOffset())
                     .setFileDescriptorLength(afd.getLength())
@@ -149,31 +154,28 @@
         AudioAttributesCompat attributes = new AudioAttributesCompat.Builder()
                 .setLegacyStreamType(AudioManager.STREAM_MUSIC)
                 .build();
-        mPlayer.setAudioAttributes(attributes);
+        Future<PlayerResult> setAttrFuture = mPlayer.setAudioAttributes(attributes);
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
+        assertFutureSuccess(setItemFuture);
+        assertFutureSuccess(setAttrFuture);
+        assertFutureSuccess(prepareFuture);
 
-        ListenableFuture<PlayerResult> future = mPlayer.prepare();
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
-
-        assertFalse(mPlayer.getPlayerState() == MediaPlayer.PLAYER_STATE_PLAYING);
-        future = mPlayer.play();
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
-        assertTrue(mPlayer.getPlayerState() == MediaPlayer.PLAYER_STATE_PLAYING);
+        assertNotEquals(MediaPlayer.PLAYER_STATE_PLAYING, mPlayer.getPlayerState());
+        assertFutureSuccess(mPlayer.play());
+        assertEquals(MediaPlayer.PLAYER_STATE_PLAYING, mPlayer.getPlayerState());
 
         assertEquals(mp3Duration, mPlayer.getDuration(), tolerance);
         long pos = mPlayer.getCurrentPosition();
         assertTrue(pos >= 0);
         assertTrue(pos < mp3Duration - seekDuration);
 
-        future = mPlayer.seekTo(pos + seekDuration, MediaPlayer.SEEK_PREVIOUS_SYNC);
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
+        assertFutureSuccess(mPlayer.seekTo(pos + seekDuration, MediaPlayer.SEEK_PREVIOUS_SYNC));
         assertEquals(pos + seekDuration, mPlayer.getCurrentPosition(), tolerance);
 
-        future = mPlayer.pause();
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
-        assertFalse(mPlayer.getPlayerState() == MediaPlayer.PLAYER_STATE_PLAYING);
-        future = mPlayer.play();
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
-        assertTrue(mPlayer.getPlayerState() == MediaPlayer.PLAYER_STATE_PLAYING);
+        assertFutureSuccess(mPlayer.pause());
+        assertNotEquals(MediaPlayer.PLAYER_STATE_PLAYING, mPlayer.getPlayerState());
+        assertFutureSuccess(mPlayer.play());
+        assertEquals(MediaPlayer.PLAYER_STATE_PLAYING, mPlayer.getPlayerState());
 
         // waiting to complete
         while (mPlayer.getPlayerState() == MediaPlayer.PLAYER_STATE_PLAYING) {
@@ -192,7 +194,8 @@
         final int height = 288;
         final float volume = 0.5f;
 
-        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
+        Future<PlayerResult> setSurfaceFuture = mPlayer.setSurface(
+                mActivity.getSurfaceHolder().getSurface());
 
         final TestUtils.Monitor onVideoSizeChangedCalled = new TestUtils.Monitor();
         final TestUtils.Monitor onVideoRenderingStartCalled = new TestUtils.Monitor();
@@ -233,13 +236,16 @@
         };
         mPlayer.registerPlayerCallback(mExecutor, callback);
 
-        mPlayer.prepare();
-        mPlayer.play();
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
+        Future<PlayerResult> playFuture = mPlayer.play();
 
         onVideoSizeChangedCalled.waitForCountedSignals(2);
         onVideoRenderingStartCalled.waitForSignal();
 
-        mPlayer.setPlayerVolume(volume);
+        assertFutureSuccess(setSurfaceFuture);
+        assertFutureSuccess(prepareFuture);
+        assertFutureSuccess(playFuture);
+        assertFutureSuccess(mPlayer.setPlayerVolume(volume));
 
         // waiting to complete
         while (mPlayer.getPlayerState() == MediaPlayer.PLAYER_STATE_PLAYING) {
@@ -302,7 +308,8 @@
         final int width = 352;
         final int height = 288;
 
-        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
+        Future<PlayerResult> setSurfaceFuture = mPlayer.setSurface(
+                mActivity.getSurfaceHolder().getSurface());
 
         final TestUtils.Monitor onVideoSizeChangedCalled = new TestUtils.Monitor();
         final TestUtils.Monitor onVideoRenderingStartCalled = new TestUtils.Monitor();
@@ -343,11 +350,15 @@
         };
         mPlayer.registerPlayerCallback(mExecutor, callback);
 
-        mPlayer.prepare();
-        mPlayer.play();
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
+        Future<PlayerResult> playFuture = mPlayer.play();
 
         onVideoSizeChangedCalled.waitForCountedSignals(2);
         onVideoRenderingStartCalled.waitForSignal();
+
+        assertFutureSuccess(setSurfaceFuture);
+        assertFutureSuccess(prepareFuture);
+        assertFutureSuccess(playFuture);
     }
 
     @Test
@@ -360,12 +371,14 @@
         final int expectedDuration = 11047;
         final int tolerance = 70;
 
-        mPlayer.setSurface(mActivity.getSurfaceHolder2().getSurface());
+        Future<PlayerResult> setSurfaceFuture = mPlayer.setSurface(
+                mActivity.getSurfaceHolder2().getSurface());
         assertEquals(MediaPlayer.PLAYER_STATE_IDLE, mPlayer.getPlayerState());
         assertEquals(MediaPlayer.UNKNOWN_TIME, mPlayer.getDuration());
 
-        ListenableFuture<PlayerResult> future = mPlayer.prepare();
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
+        assertFutureSuccess(setSurfaceFuture);
+        assertFutureSuccess(prepareFuture);
 
         assertEquals(MediaPlayer.PLAYER_STATE_PAUSED, mPlayer.getPlayerState());
         assertEquals(expectedDuration, mPlayer.getDuration(), tolerance);
@@ -408,32 +421,33 @@
             fail();
         }
 
-        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
-
-        ListenableFuture<PlayerResult> future = mPlayer.prepare();
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
+        Future<PlayerResult> setSurfaceFuture = mPlayer.setSurface(
+                mActivity.getSurfaceHolder().getSurface());
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
+        assertFutureSuccess(setSurfaceFuture);
+        assertFutureSuccess(prepareFuture);
 
         float[] rates = {0.25f, 0.5f, 1.0f, 2.0f};
         for (float playbackRate : rates) {
-            mPlayer.seekTo(0, MediaPlayer.SEEK_PREVIOUS_SYNC);
+            Future<PlayerResult> seekFuture = mPlayer.seekTo(0, MediaPlayer.SEEK_PREVIOUS_SYNC);
             Thread.sleep(1000);
             int playTime = 4000;  // The testing clip is about 10 second long.
             int privState = mPlayer.getPlayerState();
 
-            future = mPlayer.setPlaybackParams(
+            Future<PlayerResult> setParamsFuture = mPlayer.setPlaybackParams(
                     new PlaybackParams.Builder().setSpeed(playbackRate).build());
-            assertEquals(RESULT_SUCCESS, future.get().getResultCode());
-            assertTrue("setPlaybackParams() should not change player state. "
-                    + mPlayer.getPlayerState(), mPlayer.getPlayerState() == privState);
+            assertFutureSuccess(seekFuture);
+            assertFutureSuccess(setParamsFuture);
+            assertEquals("setPlaybackParams() should not change player state. "
+                    + mPlayer.getPlayerState(), privState, mPlayer.getPlayerState());
 
-            future = mPlayer.play();
-            assertEquals(RESULT_SUCCESS, future.get().getResultCode());
+            Future<PlayerResult> playFuture = mPlayer.play();
             Thread.sleep(playTime);
 
             PlaybackParams pbp = mPlayer.getPlaybackParams();
             assertEquals(playbackRate, pbp.getSpeed(), FLOAT_TOLERANCE);
-            assertTrue("The player should still be playing",
-                    mPlayer.getPlayerState() == MediaPlayer.PLAYER_STATE_PLAYING);
+            assertEquals("The player should still be playing",
+                    MediaPlayer.PLAYER_STATE_PLAYING, mPlayer.getPlayerState());
 
             long playedMediaDurationMs = mPlayer.getCurrentPosition();
             int diff = Math.abs((int) (playedMediaDurationMs / playbackRate) - playTime);
@@ -441,8 +455,8 @@
                 fail("Media player had error in playback rate " + playbackRate
                         + ", play time is " + playTime + " vs expected " + playedMediaDurationMs);
             }
-            future = mPlayer.pause();
-            assertEquals(RESULT_SUCCESS, future.get().getResultCode());
+            assertFutureSuccess(playFuture);
+            assertFutureSuccess(mPlayer.pause());
 
             pbp = mPlayer.getPlaybackParams();
             assertEquals("pause() should not change the playback rate property.",
@@ -461,12 +475,13 @@
             fail();
         }
 
-        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
-
-        ListenableFuture<PlayerResult> future = mPlayer.prepare();
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
-
-        mPlayer.play();
+        Future<PlayerResult> setSurfaceFuture = mPlayer.setSurface(
+                mActivity.getSurfaceHolder().getSurface());
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
+        Future<PlayerResult> playFuture = mPlayer.play();
+        assertFutureSuccess(setSurfaceFuture);
+        assertFutureSuccess(prepareFuture);
+        assertFutureSuccess(playFuture);
 
         final long seekPosMs = 3000;
         final long timeToleranceMs = 100;
@@ -505,8 +520,7 @@
         int timeRemainedMs = 10000;  // total time for testing
         final int timeToleranceMs = 100;
 
-        ListenableFuture<PlayerResult> future = mPlayer.seekTo(seekPosMs, seekMode);
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
+        assertFutureSuccess(mPlayer.seekTo(seekPosMs, seekMode));
 
         long cp = -seekPosMs;
         while (timeRemainedMs > 0) {
@@ -534,45 +548,49 @@
             fail();
         }
 
-        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
-
-        ListenableFuture<PlayerResult> future = mPlayer.prepare();
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
-
-        mPlayer.play();
-        mPlayer.setPlaybackParams(new PlaybackParams.Builder().setSpeed(playbackRate).build());
+        Future<PlayerResult> setSurfaceFuture = mPlayer.setSurface(
+                mActivity.getSurfaceHolder().getSurface());
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
+        Future<PlayerResult> playFuture = mPlayer.play();
+        Future<PlayerResult> setParamsFuture = mPlayer.setPlaybackParams(
+                new PlaybackParams.Builder().setSpeed(playbackRate).build());
         Thread.sleep(SLEEP_TIME);  // let player get into stable state.
         long nt1 = System.nanoTime();
         MediaTimestamp ts1 = mPlayer.getTimestamp();
         long nt2 = System.nanoTime();
-        assertTrue("Media player should return a valid time stamp", ts1 != null);
+        assertNotNull("Media player should return a valid time stamp", ts1);
         assertEquals("MediaPlayer had error in clockRate " + ts1.getMediaClockRate(),
-                playbackRate, ts1.getMediaClockRate(), 0.001f);
+                playbackRate, ts1.getMediaClockRate(), FLOAT_TOLERANCE);
         assertTrue("The nanoTime of Media timestamp should be taken when getTimestamp is called.",
                 nt1 <= ts1.getAnchorSystemNanoTime() && ts1.getAnchorSystemNanoTime() <= nt2);
+        assertFutureSuccess(setSurfaceFuture);
+        assertFutureSuccess(prepareFuture);
+        assertFutureSuccess(playFuture);
+        assertFutureSuccess(setParamsFuture);
 
-        future = mPlayer.pause();
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
+        assertFutureSuccess(mPlayer.pause());
 
         ts1 = mPlayer.getTimestamp();
-        assertTrue("Media player should return a valid time stamp", ts1 != null);
-        assertTrue("Media player should have play rate of 0.0f when paused",
-                ts1.getMediaClockRate() == 0.0f);
+        assertNotNull("Media player should return a valid time stamp", ts1);
+        assertEquals("Media player should have play rate of 0.0f when paused",
+                0.0f, ts1.getMediaClockRate(), FLOAT_TOLERANCE);
 
-        mPlayer.seekTo(0, MediaPlayer.SEEK_PREVIOUS_SYNC);
-        mPlayer.play();
+        Future<PlayerResult> seekFuture = mPlayer.seekTo(0, MediaPlayer.SEEK_PREVIOUS_SYNC);
+        playFuture = mPlayer.play();
         Thread.sleep(SLEEP_TIME);  // let player get into stable state.
         int playTime = 4000;  // The testing clip is about 10 second long.
         ts1 = mPlayer.getTimestamp();
-        assertTrue("Media player should return a valid time stamp", ts1 != null);
+        assertNotNull("Media player should return a valid time stamp", ts1);
         Thread.sleep(playTime);
         MediaTimestamp ts2 = mPlayer.getTimestamp();
-        assertTrue("Media player should return a valid time stamp", ts2 != null);
-        assertTrue("The clockRate should not be changed.",
-                ts1.getMediaClockRate() == ts2.getMediaClockRate());
+        assertNotNull("Media player should return a valid time stamp", ts2);
+        assertEquals("The clockRate should not be changed.",
+                ts1.getMediaClockRate(), ts2.getMediaClockRate(), FLOAT_TOLERANCE);
         assertEquals("MediaPlayer had error in timestamp.",
                 ts1.getAnchorMediaTimeUs() + (long) (playTime * ts1.getMediaClockRate() * 1000),
                 ts2.getAnchorMediaTimeUs(), toleranceUs);
+        assertFutureSuccess(seekFuture);
+        assertFutureSuccess(playFuture);
 
         mPlayer.reset();
     }
@@ -605,7 +623,7 @@
     private int selectSubtitleTrack(int index) throws Exception {
         assertTrue(index < mSubtitleTrackInfos.size());
         final TrackInfo track = mSubtitleTrackInfos.get(index);
-        ListenableFuture<PlayerResult> future = mPlayer.selectTrack(track);
+        Future<PlayerResult> future = mPlayer.selectTrack(track);
         int result = future.get().getResultCode();
         if (result == RESULT_SUCCESS) {
             mSelectedTrack = track;
@@ -616,7 +634,7 @@
     private int deselectSubtitleTrack(int index) throws Exception {
         assertTrue(index < mSubtitleTrackInfos.size());
         final TrackInfo track = mSubtitleTrackInfos.get(index);
-        ListenableFuture<PlayerResult> future = mPlayer.deselectTrack(track);
+        Future<PlayerResult> future = mPlayer.deselectTrack(track);
         int result = future.get().getResultCode();
         if (result == RESULT_SUCCESS) {
             mSelectedTrack = null;
@@ -655,9 +673,13 @@
             }
         };
         mPlayer.registerPlayerCallback(mExecutor, callback);
-        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
-        mPlayer.prepare();
-        mPlayer.play().get();
+        Future<PlayerResult> setSurfaceFuture = mPlayer.setSurface(
+                mActivity.getSurfaceHolder().getSurface());
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
+        Future<PlayerResult> playFuture = mPlayer.play();
+        assertFutureSuccess(setSurfaceFuture);
+        assertFutureSuccess(prepareFuture);
+        assertFutureSuccess(playFuture);
         assertEquals(MediaPlayer.PLAYER_STATE_PLAYING, mPlayer.getPlayerState());
 
         // Closed caption tracks are in-band.
@@ -712,9 +734,13 @@
             }
         };
         mPlayer.registerPlayerCallback(mExecutor, callback);
-        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
-        mPlayer.prepare();
-        mPlayer.play().get();
+        Future<PlayerResult> setSurfaceFuture = mPlayer.setSurface(
+                mActivity.getSurfaceHolder().getSurface());
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
+        Future<PlayerResult> playFuture = mPlayer.play();
+        assertFutureSuccess(setSurfaceFuture);
+        assertFutureSuccess(prepareFuture);
+        assertFutureSuccess(playFuture);
         assertEquals(MediaPlayer.PLAYER_STATE_PLAYING, mPlayer.getPlayerState());
 
         // Closed caption tracks are in-band.
@@ -758,9 +784,13 @@
             }
         };
         mPlayer.registerPlayerCallback(mExecutor, callback);
-        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
-        mPlayer.prepare();
-        mPlayer.play().get();
+        Future<PlayerResult> setSurfaceFuture = mPlayer.setSurface(
+                mActivity.getSurfaceHolder().getSurface());
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
+        Future<PlayerResult> playFuture = mPlayer.play();
+        assertFutureSuccess(setSurfaceFuture);
+        assertFutureSuccess(prepareFuture);
+        assertFutureSuccess(playFuture);
         assertEquals(MediaPlayer.PLAYER_STATE_PLAYING, mPlayer.getPlayerState());
 
         // The media metadata will be changed while playing since closed caption tracks are in-band
@@ -795,9 +825,10 @@
             }
         };
         mPlayer.registerPlayerCallback(mExecutor, callback);
-        mPlayer.prepare();
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
 
         mTracksFullyFound.waitForSignal(1500);
+        assertFutureSuccess(prepareFuture);
 
         readTracks();
 
@@ -836,26 +867,31 @@
             }
         };
         mPlayer.registerPlayerCallback(mExecutor, callback);
-        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
-        mPlayer.prepare();
+        Future<PlayerResult> setSurfaceFuture = mPlayer.setSurface(
+                mActivity.getSurfaceHolder().getSurface());
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
 
         // Timestamp needs to be reported when playback starts.
         mOnMediaTimeDiscontinuityCalled.reset();
-        mPlayer.play();
+        Future<PlayerResult> playFuture = mPlayer.play();
+        assertFutureSuccess(setSurfaceFuture);
+        assertFutureSuccess(prepareFuture);
+        assertFutureSuccess(playFuture);
         do {
             assertTrue(mOnMediaTimeDiscontinuityCalled.waitForSignal(1000));
         } while (Math.abs(timestamps.getLast().getMediaClockRate() - 1.0f) > 0.01f);
 
         // Timestamp needs to be reported when seeking is done.
         mOnMediaTimeDiscontinuityCalled.reset();
-        assertEquals(RESULT_SUCCESS, mPlayer.seekTo(3000).get().getResultCode());
+        assertFutureSuccess(mPlayer.seekTo(3000));
         do {
             assertTrue(mOnMediaTimeDiscontinuityCalled.waitForSignal(1000));
         } while (Math.abs(timestamps.getLast().getMediaClockRate() - 1.0f) > 0.01f);
 
         // Timestamp needs to be updated when playback rate changes.
         mOnMediaTimeDiscontinuityCalled.reset();
-        mPlayer.setPlaybackParams(new PlaybackParams.Builder().setSpeed(0.5f).build());
+        assertFutureSuccess(mPlayer.setPlaybackParams(
+                new PlaybackParams.Builder().setSpeed(0.5f).build()));
         mOnMediaTimeDiscontinuityCalled.waitForSignal();
         do {
             assertTrue(mOnMediaTimeDiscontinuityCalled.waitForSignal(1000));
@@ -863,7 +899,7 @@
 
         // Timestamp needs to be updated when player is paused.
         mOnMediaTimeDiscontinuityCalled.reset();
-        mPlayer.pause();
+        assertFutureSuccess(mPlayer.pause());
         mOnMediaTimeDiscontinuityCalled.waitForSignal();
         do {
             assertTrue(mOnMediaTimeDiscontinuityCalled.waitForSignal(1000));
@@ -883,30 +919,35 @@
                 TestDataSourceCallback.fromAssetFd(mResources.openRawResourceFd(resid));
         // Test returning -1 from getSize() to indicate unknown size.
         dataSource.returnFromGetSize(-1);
-        mPlayer.setMediaItem(new CallbackMediaItem.Builder(dataSource).build());
-        mPlayer.prepare();
-        mPlayer.play().get();
-        assertTrue(mPlayer.getPlayerState() == MediaPlayer.PLAYER_STATE_PLAYING);
+        Future<PlayerResult> setItemFuture = mPlayer.setMediaItem(
+                new CallbackMediaItem.Builder(dataSource).build());
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
+        Future<PlayerResult> playFuture = mPlayer.play();
+        assertFutureSuccess(setItemFuture);
+        assertFutureSuccess(prepareFuture);
+        assertFutureSuccess(playFuture);
+        assertEquals(MediaPlayer.PLAYER_STATE_PLAYING, mPlayer.getPlayerState());
 
         // Test pause and restart.
-        mPlayer.pause();
-        Thread.sleep(SLEEP_TIME);
-        assertFalse(mPlayer.getPlayerState() == MediaPlayer.PLAYER_STATE_PLAYING);
+        assertFutureSuccess(mPlayer.pause());
+        assertNotEquals(MediaPlayer.PLAYER_STATE_PLAYING, mPlayer.getPlayerState());
 
-        mPlayer.play().get();
-        assertTrue(mPlayer.getPlayerState() == MediaPlayer.PLAYER_STATE_PLAYING);
+        assertFutureSuccess(mPlayer.play());
+        assertEquals(MediaPlayer.PLAYER_STATE_PLAYING, mPlayer.getPlayerState());
 
         // Test reset.
         mPlayer.reset();
-        mPlayer.setMediaItem(new CallbackMediaItem.Builder(dataSource).build());
-
-        mPlayer.prepare();
-        mPlayer.play().get();
-        assertTrue(mPlayer.getPlayerState() == MediaPlayer.PLAYER_STATE_PLAYING);
+        setItemFuture = mPlayer.setMediaItem(new CallbackMediaItem.Builder(dataSource).build());
+        prepareFuture = mPlayer.prepare();
+        playFuture = mPlayer.play();
+        assertFutureSuccess(setItemFuture);
+        assertFutureSuccess(prepareFuture);
+        assertFutureSuccess(playFuture);
+        assertEquals(MediaPlayer.PLAYER_STATE_PLAYING, mPlayer.getPlayerState());
 
         // Test seek. Note: the seek position is cached and returned as the
         // current position so there's no point in comparing them.
-        mPlayer.seekTo(duration - SLEEP_TIME, MediaPlayer.SEEK_PREVIOUS_SYNC);
+        assertFutureSuccess(mPlayer.seekTo(duration - SLEEP_TIME, MediaPlayer.SEEK_PREVIOUS_SYNC));
         while (mPlayer.getPlayerState() == MediaPlayer.PLAYER_STATE_PLAYING) {
             Thread.sleep(SLEEP_TIME);
         }
@@ -917,7 +958,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     public void testNullMedia2DataSourceIsRejected() throws Exception {
         try {
-            mPlayer.setMediaItem(null);
+            assertNotNull(mPlayer.setMediaItem(null));
             fail();
         } catch (NullPointerException e) {
             // Expected exception
@@ -929,9 +970,8 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     public void testMedia2DataSourceIsClosedOnReset() throws Exception {
         TestDataSourceCallback dataSource = new TestDataSourceCallback(new byte[0]);
-        assertEquals(RESULT_SUCCESS,
-                mPlayer.setMediaItem(new CallbackMediaItem.Builder(dataSource).build()).get()
-                        .getResultCode());
+        assertFutureSuccess(mPlayer.setMediaItem(
+                new CallbackMediaItem.Builder(dataSource).build()));
         mPlayer.reset();
         assertTrue(dataSource.isClosed());
     }
@@ -955,12 +995,14 @@
                 TestDataSourceCallback.fromAssetFd(mResources.openRawResourceFd(resid));
         // Ensure that we throw after reading enough data for preparation to complete.
         dataSource.throwFromReadAtPosition(500_000);
-        mPlayer.setMediaItem(new CallbackMediaItem.Builder(dataSource).build());
-
-        mPlayer.prepare().get();
+        Future<PlayerResult> setItemFuture = mPlayer.setMediaItem(
+                new CallbackMediaItem.Builder(dataSource).build());
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
+        assertFutureSuccess(setItemFuture);
+        assertFutureSuccess(prepareFuture);
 
         mOnErrorCalled.reset();
-        mPlayer.play();
+        assertFutureSuccess(mPlayer.play());
         assertTrue(mOnErrorCalled.waitForSignal());
     }
 
@@ -999,8 +1041,9 @@
         List<MediaItem> items = new ArrayList<>();
         items.add(dsd1);
         items.add(dsd2);
-        mPlayer.setPlaylist(items, null);
-        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
+        Future<PlayerResult> setListFuture = mPlayer.setPlaylist(items, null);
+        Future<PlayerResult> setSurfaceFuture = mPlayer.setSurface(
+                mActivity.getSurfaceHolder().getSurface());
 
         final Monitor onCompletionCalled = new Monitor();
         MediaPlayer.PlayerCallback callback = new MediaPlayer.PlayerCallback() {
@@ -1011,10 +1054,16 @@
         };
         mPlayer.registerPlayerCallback(mExecutor, callback);
 
-        mPlayer.prepare().get();
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
+        assertFutureSuccess(setListFuture);
+        assertFutureSuccess(setSurfaceFuture);
+        assertFutureSuccess(prepareFuture);
 
-        mPlayer.setPlaybackParams(new PlaybackParams.Builder().setSpeed(2.0f).build());
-        mPlayer.play();
+        Future<PlayerResult> setParamsFuture = mPlayer.setPlaybackParams(
+                new PlaybackParams.Builder().setSpeed(2.0f).build());
+        Future<PlayerResult> playFuture = mPlayer.play();
+        assertFutureSuccess(setParamsFuture);
+        assertFutureSuccess(playFuture);
 
         onCompletionCalled.waitForSignal();
         assertEquals(dsd2, mPlayer.getCurrentMediaItem());
@@ -1028,7 +1077,7 @@
         if (!loadResource(R.raw.testvideo_with_2_subtitle_tracks)) {
             fail();
         }
-        mPlayer.prepare().get();
+        assertFutureSuccess(mPlayer.prepare());
 
         PlaybackParams playbackParams = mPlayer.getPlaybackParams();
         assertEquals(PlaybackParams.AUDIO_FALLBACK_MODE_DEFAULT,
@@ -1079,22 +1128,25 @@
             }
         };
         mPlayer.registerPlayerCallback(mExecutor, callback);
-        mPlayer.setMediaItem(new CallbackMediaItem.Builder(dataSource).build());
+        Future<PlayerResult> setItemFuture = mPlayer.setMediaItem(
+                new CallbackMediaItem.Builder(dataSource).build());
 
         mOnErrorCalled.reset();
 
         // prepare() will be pending until readAllowed is signaled.
-        mPlayer.prepare();
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
 
-        ListenableFuture<PlayerResult> seekFuture1 = mPlayer.seekTo(3000);
-        ListenableFuture<PlayerResult> seekFuture2 = mPlayer.seekTo(2000);
-        ListenableFuture<PlayerResult> seekFuture3 = mPlayer.seekTo(1000);
+        Future<PlayerResult> seekFuture1 = mPlayer.seekTo(3000);
+        Future<PlayerResult> seekFuture2 = mPlayer.seekTo(2000);
+        Future<PlayerResult> seekFuture3 = mPlayer.seekTo(1000);
 
         readAllowed.signal();
 
-        assertEquals(RESULT_INFO_SKIPPED, seekFuture1.get().getResultCode());
-        assertEquals(RESULT_INFO_SKIPPED, seekFuture2.get().getResultCode());
-        assertEquals(RESULT_SUCCESS, seekFuture3.get().getResultCode());
+        assertFutureSuccess(setItemFuture);
+        assertFutureSuccess(prepareFuture);
+        assertFutureStateEquals(seekFuture1, RESULT_INFO_SKIPPED);
+        assertFutureStateEquals(seekFuture2, RESULT_INFO_SKIPPED);
+        assertFutureSuccess(seekFuture3);
         assertFalse(mOnErrorCalled.isSignalled());
     }
 
@@ -1105,28 +1157,27 @@
         if (!loadResource(R.raw.testvideo)) {
             fail();
         }
-        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
+        Future<PlayerResult> setSurfaceFuture = mPlayer.setSurface(
+                mActivity.getSurfaceHolder().getSurface());
 
-        ListenableFuture<PlayerResult> future;
         assertEquals(MediaPlayer.BUFFERING_STATE_UNKNOWN, mPlayer.getBufferingState());
         assertEquals(MediaPlayer.PLAYER_STATE_IDLE, mPlayer.getPlayerState());
 
-        future = mPlayer.prepare();
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
+        assertFutureSuccess(setSurfaceFuture);
+        assertFutureSuccess(prepareFuture);
 
         assertEquals(MediaPlayer.BUFFERING_STATE_BUFFERING_AND_PLAYABLE,
                 mPlayer.getBufferingState());
         assertEquals(MediaPlayer.PLAYER_STATE_PAUSED, mPlayer.getPlayerState());
 
-        future = mPlayer.play();
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
+        assertFutureSuccess(mPlayer.play());
 
         assertEquals(MediaPlayer.BUFFERING_STATE_BUFFERING_AND_PLAYABLE,
                 mPlayer.getBufferingState());
         assertEquals(MediaPlayer.PLAYER_STATE_PLAYING, mPlayer.getPlayerState());
 
-        future = mPlayer.pause();
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
+        assertFutureSuccess(mPlayer.pause());
 
         assertEquals(MediaPlayer.BUFFERING_STATE_BUFFERING_AND_PLAYABLE,
                 mPlayer.getBufferingState());
@@ -1146,7 +1197,6 @@
             return; // skip;
         }
 
-        ListenableFuture<PlayerResult> future;
         final TestUtils.Monitor onSeekCompleteCalled = new TestUtils.Monitor();
         final TestUtils.Monitor onPlayerStateChangedCalled = new TestUtils.Monitor();
         final AtomicInteger playerState = new AtomicInteger();
@@ -1181,16 +1231,18 @@
             }
         };
         mPlayer.registerPlayerCallback(mExecutor, callback);
-        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
+        Future<PlayerResult> setSurfaceFuture = mPlayer.setSurface(
+                mActivity.getSurfaceHolder().getSurface());
 
         onPlayerStateChangedCalled.reset();
         onBufferingStateChangedCalled.reset();
-        future = mPlayer.prepare();
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
         do {
             assertTrue(onBufferingStateChangedCalled.waitForSignal(1000));
         } while (bufferingState.get() != MediaPlayer.BUFFERING_STATE_BUFFERING_AND_STARVED);
 
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
+        assertFutureSuccess(setSurfaceFuture);
+        assertFutureSuccess(prepareFuture);
 
         do {
             assertTrue(onPlayerStateChangedCalled.waitForSignal(1000));
@@ -1200,11 +1252,11 @@
         } while (bufferingState.get() != MediaPlayer.BUFFERING_STATE_BUFFERING_AND_PLAYABLE);
 
         onSeekCompleteCalled.reset();
-        mPlayer.seekTo(mp4Duration >> 1);
+        assertFutureSuccess(mPlayer.seekTo(mp4Duration >> 1));
         onSeekCompleteCalled.waitForSignal();
 
         onPlaybackSpeedChanged.reset();
-        mPlayer.setPlaybackSpeed(0.5f);
+        assertFutureSuccess(mPlayer.setPlaybackSpeed(0.5f));
         do {
             assertTrue(onPlaybackSpeedChanged.waitForSignal(1000));
         } while (Math.abs(playbackSpeed.get() - 0.5f) > FLOAT_TOLERANCE);
@@ -1220,16 +1272,10 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     public void testSetPlaybackSpeedWithIllegalArguments() throws Throwable {
         // Zero is not allowed.
-        ListenableFuture<PlayerResult> future = mPlayer.setPlaybackSpeed(0.0f);
-        PlayerResult result = future.get();
-        assertNotNull(result);
-        assertEquals(RESULT_ERROR_BAD_VALUE, result.getResultCode());
+        assertFutureStateEquals(mPlayer.setPlaybackSpeed(0.0f), RESULT_ERROR_BAD_VALUE);
 
         // Negative values are not allowed.
-        future = mPlayer.setPlaybackSpeed(-1.0f);
-        result = future.get();
-        assertNotNull(result);
-        assertEquals(RESULT_ERROR_BAD_VALUE, result.getResultCode());
+        assertFutureStateEquals(mPlayer.setPlaybackSpeed(-1.0f), RESULT_ERROR_BAD_VALUE);
     }
 
     @Test
@@ -1240,9 +1286,9 @@
         AudioAttributesCompat attributes = new AudioAttributesCompat.Builder()
                 .setLegacyStreamType(AudioManager.STREAM_MUSIC)
                 .build();
-        mPlayer.setAudioAttributes(attributes);
-        mPlayer.prepare();
-        mPlayer.play();
+        assertNotNull(mPlayer.setAudioAttributes(attributes));
+        assertNotNull(mPlayer.prepare());
+        assertNotNull(mPlayer.play());
         mPlayer.close();
 
         // Set the player to null so we don't try to close it again in tearDown().
@@ -1260,7 +1306,7 @@
         AudioAttributesCompat attributes = new AudioAttributesCompat.Builder()
                 .setLegacyStreamType(AudioManager.STREAM_MUSIC)
                 .build();
-        mPlayer.setAudioAttributes(attributes);
+        assertNotNull(mPlayer.setAudioAttributes(attributes));
 
         mPlayer.reset();
 
@@ -1310,13 +1356,14 @@
 
         mOnErrorCalled.reset();
 
-        mPlayer.setMediaItem(new CallbackMediaItem.Builder(dataSource).build());
+        Future<PlayerResult> setItemFuture = mPlayer.setMediaItem(
+                new CallbackMediaItem.Builder(dataSource).build());
 
         // prepare() will be pending until readAllowed is signaled.
-        mPlayer.prepare();
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
 
-        ListenableFuture<PlayerResult> seekFuture = mPlayer.seekTo(1000);
-        ListenableFuture<PlayerResult> volumeFuture = mPlayer.setPlayerVolume(0.7f);
+        Future<PlayerResult> seekFuture = mPlayer.seekTo(1000);
+        Future<PlayerResult> volumeFuture = mPlayer.setPlayerVolume(0.7f);
 
         readRequested.waitForSignal();
 
@@ -1326,7 +1373,9 @@
 
         // Make the on-going prepare operation resumed and check the results.
         readAllowed.signal();
-        mPlayer.setSurface(null).get();
+        assertFutureSuccess(setItemFuture);
+        assertFutureSuccess(prepareFuture);
+        assertFutureSuccess(mPlayer.setSurface(null));
 
         assertEquals(0 /* default value */, mPlayer.getCurrentPosition());
         assertEquals(1.0f /* default value */, mPlayer.getPlayerVolume(), 0.001f);
@@ -1350,44 +1399,35 @@
         mPlayer.registerPlayerCallback(mExecutor, callback);
 
         int shuffleMode = mPlayer.getShuffleMode();
-        ListenableFuture<PlayerResult> future;
-        PlayerResult result;
         if (shuffleMode != SessionPlayer.SHUFFLE_MODE_NONE) {
             onShuffleModeChangedMonitor.reset();
-            future = mPlayer.setShuffleMode(SessionPlayer.SHUFFLE_MODE_NONE);
+            assertFutureSuccess(mPlayer.setShuffleMode(SessionPlayer.SHUFFLE_MODE_NONE));
             assertTrue(onShuffleModeChangedMonitor.waitForSignal(WAIT_TIME_MS));
-            result = future.get();
             assertEquals(mPlayer, mPlayerCbArg1);
-            assertEquals(RESULT_SUCCESS, result.getResultCode());
             assertEquals(SessionPlayer.SHUFFLE_MODE_NONE, ((Integer) mPlayerCbArg2).intValue());
             assertEquals(SessionPlayer.SHUFFLE_MODE_NONE, mPlayer.getShuffleMode());
         }
 
         onShuffleModeChangedMonitor.reset();
-        future = mPlayer.setShuffleMode(SessionPlayer.SHUFFLE_MODE_ALL);
+        assertFutureSuccess(mPlayer.setShuffleMode(SessionPlayer.SHUFFLE_MODE_ALL));
         assertTrue(onShuffleModeChangedMonitor.waitForSignal(WAIT_TIME_MS));
-        result = future.get();
         assertEquals(mPlayer, mPlayerCbArg1);
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
         assertEquals(SessionPlayer.SHUFFLE_MODE_ALL, ((Integer) mPlayerCbArg2).intValue());
         assertEquals(SessionPlayer.SHUFFLE_MODE_ALL, mPlayer.getShuffleMode());
 
         onShuffleModeChangedMonitor.reset();
-        future = mPlayer.setShuffleMode(SessionPlayer.SHUFFLE_MODE_GROUP);
+        assertFutureSuccess(mPlayer.setShuffleMode(SessionPlayer.SHUFFLE_MODE_GROUP));
         assertTrue(onShuffleModeChangedMonitor.waitForSignal(WAIT_TIME_MS));
-        result = future.get();
         assertEquals(mPlayer, mPlayerCbArg1);
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
         assertEquals(SessionPlayer.SHUFFLE_MODE_GROUP, ((Integer) mPlayerCbArg2).intValue());
         assertEquals(SessionPlayer.SHUFFLE_MODE_GROUP, mPlayer.getShuffleMode());
 
         // INVALID_SHUFFLE_MODE will not change the shuffle mode.
         onShuffleModeChangedMonitor.reset();
-        future = mPlayer.setShuffleMode(INVALID_SHUFFLE_MODE);
+        assertFutureStateEquals(mPlayer.setShuffleMode(INVALID_SHUFFLE_MODE),
+                RESULT_ERROR_BAD_VALUE);
         assertFalse(onShuffleModeChangedMonitor.waitForSignal(WAIT_TIME_MS));
-        result = future.get();
         assertEquals(mPlayer, mPlayerCbArg1);
-        assertEquals(RESULT_ERROR_BAD_VALUE, result.getResultCode());
         assertEquals(SessionPlayer.SHUFFLE_MODE_GROUP, mPlayer.getShuffleMode());
     }
 
@@ -1407,44 +1447,34 @@
         mPlayer.registerPlayerCallback(mExecutor, callback);
 
         int repeatMode = mPlayer.getRepeatMode();
-        ListenableFuture<PlayerResult> future;
-        PlayerResult result;
         if (repeatMode != SessionPlayer.REPEAT_MODE_NONE) {
             onRepeatModeChangedMonitor.reset();
-            future = mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_NONE);
+            assertFutureSuccess(mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_NONE));
             assertTrue(onRepeatModeChangedMonitor.waitForSignal(WAIT_TIME_MS));
-            result = future.get();
             assertEquals(mPlayer, mPlayerCbArg1);
-            assertEquals(RESULT_SUCCESS, result.getResultCode());
             assertEquals(SessionPlayer.REPEAT_MODE_NONE, ((Integer) mPlayerCbArg2).intValue());
             assertEquals(SessionPlayer.REPEAT_MODE_NONE, mPlayer.getRepeatMode());
         }
 
         onRepeatModeChangedMonitor.reset();
-        future = mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_ALL);
+        assertFutureSuccess(mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_ALL));
         assertTrue(onRepeatModeChangedMonitor.waitForSignal(WAIT_TIME_MS));
-        result = future.get();
         assertEquals(mPlayer, mPlayerCbArg1);
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
         assertEquals(SessionPlayer.REPEAT_MODE_ALL, ((Integer) mPlayerCbArg2).intValue());
         assertEquals(SessionPlayer.REPEAT_MODE_ALL, mPlayer.getRepeatMode());
 
         onRepeatModeChangedMonitor.reset();
-        future = mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_GROUP);
+        assertFutureSuccess(mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_GROUP));
         assertTrue(onRepeatModeChangedMonitor.waitForSignal(WAIT_TIME_MS));
-        result = future.get();
         assertEquals(mPlayer, mPlayerCbArg1);
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
         assertEquals(SessionPlayer.REPEAT_MODE_GROUP, ((Integer) mPlayerCbArg2).intValue());
         assertEquals(SessionPlayer.REPEAT_MODE_GROUP, mPlayer.getRepeatMode());
 
         // INVALID_REPEAT_MODE will not change the repeat mode.
         onRepeatModeChangedMonitor.reset();
-        future = mPlayer.setRepeatMode(INVALID_REPEAT_MODE);
+        assertFutureStateEquals(mPlayer.setRepeatMode(INVALID_REPEAT_MODE), RESULT_ERROR_BAD_VALUE);
         assertFalse(onRepeatModeChangedMonitor.waitForSignal(WAIT_TIME_MS));
-        result = future.get();
         assertEquals(mPlayer, mPlayerCbArg1);
-        assertEquals(RESULT_ERROR_BAD_VALUE, result.getResultCode());
         assertEquals(SessionPlayer.REPEAT_MODE_GROUP, mPlayer.getRepeatMode());
     }
 
@@ -1458,7 +1488,7 @@
                 new PlayerCallbackForPlaylist(playlist, onCurrentMediaItemChangedMonitor));
 
         try {
-            mPlayer.setPlaylist(null, null);
+            assertNotNull(mPlayer.setPlaylist(null, null));
             fail();
         } catch (Exception e) {
             // pass-through
@@ -1466,15 +1496,13 @@
         try {
             List<MediaItem> list = new ArrayList<>();
             list.add(null);
-            mPlayer.setPlaylist(list, null);
+            assertNotNull(mPlayer.setPlaylist(list, null));
             fail();
         } catch (Exception e) {
             // pass-through
         }
-        ListenableFuture<PlayerResult> future = mPlayer.setPlaylist(playlist, null);
-        PlayerResult result = future.get();
+        assertFutureSuccess(mPlayer.setPlaylist(playlist, null));
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
         assertEquals(playlist.size(), mPlayer.getPlaylist().size());
         assertEquals(playlist.get(0), mPlayer.getCurrentMediaItem());
     }
@@ -1486,7 +1514,7 @@
         MediaItem closedItem = createMediaItem();
         ((FileMediaItem) closedItem).close();
         try {
-            mPlayer.setMediaItem(closedItem);
+            assertNotNull(mPlayer.setMediaItem(closedItem));
             fail();
         } catch (Exception e) {
             // Expected.
@@ -1495,25 +1523,24 @@
         final List<MediaItem> closedPlaylist = createPlaylist(1);
         ((FileMediaItem) closedPlaylist.get(0)).close();
         try {
-            mPlayer.setPlaylist(closedPlaylist, null);
+            assertNotNull(mPlayer.setPlaylist(closedPlaylist, null));
             fail();
         } catch (Exception e) {
             // Expected.
         }
 
         List<MediaItem> playlist = createPlaylist(2);
-        ListenableFuture<PlayerResult> future = mPlayer.setPlaylist(playlist, null);
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
+        assertFutureSuccess(mPlayer.setPlaylist(playlist, null));
 
         try {
-            mPlayer.addPlaylistItem(0, closedItem);
+            assertNotNull(mPlayer.addPlaylistItem(0, closedItem));
             fail();
         } catch (Exception e) {
             // Expected.
         }
 
         try {
-            mPlayer.replacePlaylistItem(0, closedItem);
+            assertNotNull(mPlayer.replacePlaylistItem(0, closedItem));
             fail();
         } catch (Exception e) {
             // Expected.
@@ -1521,8 +1548,7 @@
 
         List<MediaItem> reversedList = new ArrayList<>(
                 Arrays.asList(playlist.get(1), playlist.get(0)));
-        future = mPlayer.setPlaylist(playlist, null);
-        assertEquals(RESULT_SUCCESS, future.get().getResultCode());
+        assertFutureSuccess(mPlayer.setPlaylist(reversedList, null));
     }
 
     @Test
@@ -1542,54 +1568,44 @@
         MediaItem item1 = playlist.get(1);
         MediaItem item2 = playlist.get(2);
         MediaItem item3 = createMediaItem();
-        ListenableFuture<PlayerResult> future = mPlayer.setPlaylist(playlist, null);
-        PlayerResult result = future.get();
+        assertFutureSuccess(mPlayer.setPlaylist(playlist, null));
         assertTrue(playlistChangeMonitor.waitForSignal(WAIT_TIME_MS));
         playlistChangeMonitor.reset();
         // mPlayer's playlist will be [0 (current) 1 2]
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
         assertEquals(playlist.size(), mPlayer.getPlaylist().size());
         assertEquals(item0, mPlayer.getCurrentMediaItem());
         assertEquals(0, mPlayer.getCurrentMediaItemIndex());
         assertEquals(1, mPlayer.getNextMediaItemIndex());
 
-        future = mPlayer.addPlaylistItem(0, item3);
-        result = future.get();
+        assertFutureSuccess(mPlayer.addPlaylistItem(0, item3));
         assertTrue(playlistChangeMonitor.waitForSignal(WAIT_TIME_MS));
         playlistChangeMonitor.reset();
         // mPlayer's playlist will be [3 0 (current) 1 2]
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
         assertEquals(playlist.size() + 1, mPlayer.getPlaylist().size());
         assertEquals(item0, mPlayer.getCurrentMediaItem());
         assertEquals(1, mPlayer.getCurrentMediaItemIndex());
         assertEquals(2, mPlayer.getNextMediaItemIndex());
 
-        future = mPlayer.removePlaylistItem(1);
-        result = future.get();
+        assertFutureSuccess(mPlayer.removePlaylistItem(1));
         assertTrue(playlistChangeMonitor.waitForSignal(WAIT_TIME_MS));
         playlistChangeMonitor.reset();
         // mPlayer's playlist will be [3 1 (current) 2]
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
         assertEquals(playlist.size(), mPlayer.getPlaylist().size());
         assertEquals(item1, mPlayer.getCurrentMediaItem());
         assertEquals(1, mPlayer.getCurrentMediaItemIndex());
         assertEquals(2, mPlayer.getNextMediaItemIndex());
 
-        future = mPlayer.movePlaylistItem(1, 0);
-        result = future.get();
+        assertFutureSuccess(mPlayer.movePlaylistItem(1, 0));
         assertTrue(playlistChangeMonitor.waitForSignal(WAIT_TIME_MS));
         playlistChangeMonitor.reset();
         // mPlayer's playlist will be [1 (current), 3, 2]
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
         assertEquals(playlist.size(), mPlayer.getPlaylist().size());
         assertEquals(item1, mPlayer.getCurrentMediaItem());
         assertEquals(0, mPlayer.getCurrentMediaItemIndex());
         assertEquals(1, mPlayer.getNextMediaItemIndex());
 
-        future = mPlayer.skipToNextPlaylistItem();
-        result = future.get();
+        assertFutureSuccess(mPlayer.skipToNextPlaylistItem());
         // mPlayer's playlist will be [1, 3 (current), 2]
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
         assertEquals(playlist.size(), mPlayer.getPlaylist().size());
         assertEquals(item3, mPlayer.getCurrentMediaItem());
         assertEquals(1, mPlayer.getCurrentMediaItemIndex());
@@ -1606,16 +1622,13 @@
         mPlayer.registerPlayerCallback(mExecutor,
                 new PlayerCallbackForPlaylist(playlist, onCurrentMediaItemChangedMonitor));
 
-        PlayerResult result = mPlayer.setPlaylist(playlist, null).get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.setPlaylist(playlist, null));
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
-        mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_NONE).get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_NONE));
 
         // Test skipToPlaylistItem
         for (int i = listSize - 1; i >= 0; --i) {
-            result = mPlayer.skipToPlaylistItem(i).get();
-            assertEquals(RESULT_SUCCESS, result.getResultCode());
+            assertFutureSuccess(mPlayer.skipToPlaylistItem(i));
             assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
             assertEquals(i, mPlayer.getCurrentMediaItemIndex());
             assertEquals(playlist.get(i), mPlayer.getCurrentMediaItem());
@@ -1632,23 +1645,19 @@
         mPlayer.registerPlayerCallback(mExecutor,
                 new PlayerCallbackForPlaylist(playlist, onCurrentMediaItemChangedMonitor));
 
-        PlayerResult result = mPlayer.setPlaylist(playlist, null).get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.setPlaylist(playlist, null));
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
-        mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_NONE).get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_NONE));
 
         // Test skipToNextPlaylistItem
         // curPlayPos = 0
         for (int curPlayPos = 0; curPlayPos < listSize - 1; ++curPlayPos) {
-            result = mPlayer.skipToNextPlaylistItem().get();
-            assertEquals(RESULT_SUCCESS, result.getResultCode());
+            assertFutureSuccess(mPlayer.skipToNextPlaylistItem());
             assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
             assertEquals(curPlayPos + 1, mPlayer.getCurrentMediaItemIndex());
             assertEquals(playlist.get(curPlayPos + 1), mPlayer.getCurrentMediaItem());
         }
-        result = mPlayer.skipToNextPlaylistItem().get();
-        assertEquals(RESULT_ERROR_INVALID_STATE, result.getResultCode());
+        assertFutureStateEquals(mPlayer.skipToNextPlaylistItem(), RESULT_ERROR_INVALID_STATE);
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, false);
         assertEquals(listSize - 1, mPlayer.getCurrentMediaItemIndex());
         assertEquals(playlist.get(listSize - 1), mPlayer.getCurrentMediaItem());
@@ -1664,27 +1673,22 @@
         mPlayer.registerPlayerCallback(mExecutor,
                 new PlayerCallbackForPlaylist(playlist, onCurrentMediaItemChangedMonitor));
 
-        PlayerResult result = mPlayer.setPlaylist(playlist, null).get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.setPlaylist(playlist, null));
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
-        mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_NONE).get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_NONE));
 
-        result = mPlayer.skipToPlaylistItem(listSize - 1).get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.skipToPlaylistItem(listSize - 1));
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
 
         // Test skipToPrevious
         // curPlayPos = listSize - 1
         for (int curPlayPos = listSize - 1; curPlayPos > 0; --curPlayPos) {
-            result = mPlayer.skipToPreviousPlaylistItem().get();
-            assertEquals(RESULT_SUCCESS, result.getResultCode());
+            assertFutureSuccess(mPlayer.skipToPreviousPlaylistItem());
             assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
             assertEquals(curPlayPos - 1, mPlayer.getCurrentMediaItemIndex());
             assertEquals(playlist.get(curPlayPos - 1), mPlayer.getCurrentMediaItem());
         }
-        result = mPlayer.skipToPreviousPlaylistItem().get();
-        assertEquals(RESULT_ERROR_INVALID_STATE, result.getResultCode());
+        assertFutureStateEquals(mPlayer.skipToPreviousPlaylistItem(), RESULT_ERROR_INVALID_STATE);
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, false);
         assertEquals(0, mPlayer.getCurrentMediaItemIndex());
         assertEquals(playlist.get(0), mPlayer.getCurrentMediaItem());
@@ -1700,22 +1704,18 @@
         mPlayer.registerPlayerCallback(mExecutor,
                 new PlayerCallbackForPlaylist(playlist, onCurrentMediaItemChangedMonitor));
 
-        PlayerResult result = mPlayer.setPlaylist(playlist, null).get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.setPlaylist(playlist, null));
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
-        result = mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_ALL).get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_ALL));
 
         assertEquals(listSize - 1, mPlayer.getPreviousMediaItemIndex());
-        result = mPlayer.skipToPreviousPlaylistItem().get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.skipToPreviousPlaylistItem());
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
         assertEquals(listSize - 1, mPlayer.getCurrentMediaItemIndex());
         assertEquals(playlist.get(listSize - 1), mPlayer.getCurrentMediaItem());
 
         assertEquals(0, mPlayer.getNextMediaItemIndex());
-        result = mPlayer.skipToNextPlaylistItem().get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.skipToNextPlaylistItem());
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
         assertEquals(0, mPlayer.getCurrentMediaItemIndex());
         assertEquals(playlist.get(0), mPlayer.getCurrentMediaItem());
@@ -1730,29 +1730,24 @@
         TestUtils.Monitor onCurrentMediaItemChangedMonitor = new TestUtils.Monitor();
         mPlayer.registerPlayerCallback(mExecutor,
                 new PlayerCallbackForPlaylist(playlist, onCurrentMediaItemChangedMonitor));
-        PlayerResult result = mPlayer.setPlaylist(playlist, null).get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.setPlaylist(playlist, null));
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
         assertEquals(0, mPlayer.getCurrentMediaItemIndex());
         assertEquals(playlist.get(0), mPlayer.getCurrentMediaItem());
 
-        result = mPlayer.skipToNextPlaylistItem().get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.skipToNextPlaylistItem());
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
         assertEquals(1, mPlayer.getCurrentMediaItemIndex());
         assertEquals(playlist.get(1), mPlayer.getCurrentMediaItem());
 
         // Will not go to the next if the next is end of the playlist
-        result = mPlayer.skipToNextPlaylistItem().get();
-        assertEquals(RESULT_ERROR_INVALID_STATE, result.getResultCode());
+        assertFutureStateEquals(mPlayer.skipToNextPlaylistItem(), RESULT_ERROR_INVALID_STATE);
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, false);
         assertEquals(1, mPlayer.getCurrentMediaItemIndex());
         assertEquals(playlist.get(1), mPlayer.getCurrentMediaItem());
 
-        result = mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_ALL).get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
-        result = mPlayer.skipToNextPlaylistItem().get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_ALL));
+        assertFutureSuccess(mPlayer.skipToNextPlaylistItem());
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
         assertEquals(0, mPlayer.getCurrentMediaItemIndex());
         assertEquals(playlist.get(0), mPlayer.getCurrentMediaItem());
@@ -1767,23 +1762,19 @@
         TestUtils.Monitor onCurrentMediaItemChangedMonitor = new TestUtils.Monitor();
         mPlayer.registerPlayerCallback(mExecutor,
                 new PlayerCallbackForPlaylist(playlist, onCurrentMediaItemChangedMonitor));
-        PlayerResult result = mPlayer.setPlaylist(playlist, null).get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.setPlaylist(playlist, null));
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
         assertEquals(0, mPlayer.getCurrentMediaItemIndex());
         assertEquals(playlist.get(0), mPlayer.getCurrentMediaItem());
 
         // Will not go to the previous if the current is the first one
-        result = mPlayer.skipToPreviousPlaylistItem().get();
-        assertEquals(RESULT_ERROR_INVALID_STATE, result.getResultCode());
+        assertFutureStateEquals(mPlayer.skipToPreviousPlaylistItem(), RESULT_ERROR_INVALID_STATE);
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, false);
         assertEquals(0, mPlayer.getCurrentMediaItemIndex());
         assertEquals(playlist.get(0), mPlayer.getCurrentMediaItem());
 
-        result = mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_ALL).get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
-        result = mPlayer.skipToPreviousPlaylistItem().get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.setRepeatMode(SessionPlayer.REPEAT_MODE_ALL));
+        assertFutureSuccess(mPlayer.skipToPreviousPlaylistItem());
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
         assertEquals(1, mPlayer.getCurrentMediaItemIndex());
         assertEquals(playlist.get(1), mPlayer.getCurrentMediaItem());
@@ -1808,13 +1799,11 @@
         };
         mPlayer.registerPlayerCallback(mExecutor, callback);
 
-        PlayerResult result1 = mPlayer.setMediaItem(item1).get();
-        assertEquals(RESULT_SUCCESS, result1.getResultCode());
+        assertFutureSuccess(mPlayer.setMediaItem(item1));
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
 
         // Test if multiple calls to setMediaItem calls onCurrentMediaItemChanged.
-        PlayerResult result2 = mPlayer.setMediaItem(item2).get();
-        assertEquals(RESULT_SUCCESS, result2.getResultCode());
+        assertFutureSuccess(mPlayer.setMediaItem(item2));
         assertWaitForSignalAndReset(onCurrentMediaItemChangedMonitor, true);
     }
 
@@ -1823,15 +1812,13 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     public void testCurrentMediaItemChangedCalledAfterSetPlayList() throws Exception {
         int listSize = 2;
-        final int currentIdx = 0;
         List<MediaItem> playlist = createPlaylist(listSize);
 
         TestUtils.Monitor onCurrentMediaItemChangedMonitor = new TestUtils.Monitor();
         mPlayer.registerPlayerCallback(mExecutor,
                 new PlayerCallbackForPlaylist(playlist, onCurrentMediaItemChangedMonitor));
 
-        PlayerResult result = mPlayer.setPlaylist(playlist, null).get();
-        assertEquals(RESULT_SUCCESS, result.getResultCode());
+        assertFutureSuccess(mPlayer.setPlaylist(playlist, null));
         assertTrue(onCurrentMediaItemChangedMonitor.waitForSignal(WAIT_TIME_MS));
     }
 
diff --git a/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayerTestBase.java b/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayerTestBase.java
index 81ab1ee..5a0a778 100644
--- a/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayerTestBase.java
+++ b/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayerTestBase.java
@@ -18,6 +18,10 @@
 
 import static android.content.Context.KEYGUARD_SERVICE;
 
+import static androidx.media2.common.BaseResult.RESULT_SUCCESS;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 
 import android.app.Instrumentation;
@@ -47,6 +51,7 @@
 import java.util.List;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
 
 /**
  * Base class for {@link MediaPlayer} tests.
@@ -126,13 +131,13 @@
 
     boolean loadResource(int resid) throws Exception {
         try (AssetFileDescriptor afd = mResources.openRawResourceFd(resid)) {
-            mPlayer.setMediaItem(new FileMediaItem.Builder(
+            return mPlayer.setMediaItem(new FileMediaItem.Builder(
                     ParcelFileDescriptor.dup(afd.getFileDescriptor()))
                     .setFileDescriptorOffset(afd.getStartOffset())
                     .setFileDescriptorLength(afd.getLength())
-                    .build());
+                    .build()).get().getResultCode()
+                    == SessionPlayer.PlayerResult.RESULT_SUCCESS;
         }
-        return true;
     }
 
     private void setKeepScreenOn() throws Throwable {
@@ -156,4 +161,17 @@
         });
         mInstrumentation.waitForIdleSync();
     }
+
+    static <T extends SessionPlayer.PlayerResult> void assertFutureSuccess(Future<T> future)
+            throws Exception {
+        assertFutureStateEquals(future, RESULT_SUCCESS);
+    }
+
+    static <T extends SessionPlayer.PlayerResult> void assertFutureStateEquals(Future<T> future,
+            int expectedResultCode) throws Exception {
+        assertNotNull(future);
+        SessionPlayer.PlayerResult result = future.get();
+        assertNotNull(result);
+        assertEquals(expectedResultCode, result.getResultCode());
+    }
 }
diff --git a/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayer_AudioFocusTest.java b/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayer_AudioFocusTest.java
index 6aed379..0fe226c 100644
--- a/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayer_AudioFocusTest.java
+++ b/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayer_AudioFocusTest.java
@@ -52,6 +52,7 @@
 import androidx.annotation.NonNull;
 import androidx.media.AudioAttributesCompat;
 import androidx.media2.common.SessionPlayer;
+import androidx.media2.common.SessionPlayer.PlayerResult;
 import androidx.media2.player.test.R;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
@@ -61,7 +62,6 @@
 
 import org.junit.After;
 import org.junit.AfterClass;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -69,6 +69,7 @@
 
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
+import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -168,9 +169,10 @@
 
     private void initPlayer(AudioAttributesCompat attr) throws Exception {
         loadResource(R.raw.loudsoftogg);
-        mPlayer.setAudioAttributes(attr);
-        Assert.assertEquals(SessionPlayer.PlayerResult.RESULT_SUCCESS,
-                mPlayer.prepare().get(WAIT_TIME_MS, TimeUnit.MILLISECONDS).getResultCode());
+        Future<PlayerResult> setAttrFuture = mPlayer.setAudioAttributes(attr);
+        Future<PlayerResult> prepareFuture = mPlayer.prepare();
+        assertFutureSuccess(setAttrFuture);
+        assertFutureSuccess(prepareFuture);
     }
 
     private void testPausedAfterAction(final AudioAttributesCompat attr,
@@ -194,7 +196,7 @@
             });
 
         // Play here for registering noisy intent.
-        mPlayer.play();
+        assertFutureSuccess(mPlayer.play());
         // Playback becomes PLAYING needs to be propagated to the session and its focus handler.
         // Wait for a while for that.
         assertTrue(latchForPlaying.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
@@ -221,7 +223,7 @@
                 }
             }
         });
-        mPlayer.play();
+        assertFutureSuccess(mPlayer.play());
         // Playback becomes PLAYING needs to be propagated to the session and its focus handler.
         // Wait for a while for that.
         assertTrue(latchForPlaying.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
@@ -309,7 +311,7 @@
         initPlayer(createAudioAttributes(CONTENT_TYPE_MUSIC, USAGE_MEDIA));
 
         // Play should request audio focus with AUDIOFOCUS_GAIN for USAGE_MEDIA
-        mPlayer.play();
+        assertFutureSuccess(mPlayer.play());
 
         // Previously focused one should loss audio focus
         waitForAudioFocus(AUDIOFOCUS_LOSS);
@@ -325,7 +327,7 @@
         initPlayer(createAudioAttributes(CONTENT_TYPE_MUSIC, USAGE_UNKNOWN));
 
         // Play should request audio focus with AUDIOFOCUS_GAIN for USAGE_MEDIA
-        mPlayer.play();
+        assertFutureSuccess(mPlayer.play());
 
         // Previously focused one should loss audio focus
         waitForAudioFocus(AUDIOFOCUS_LOSS);
@@ -341,7 +343,7 @@
         initPlayer(createAudioAttributes(CONTENT_TYPE_MUSIC, USAGE_ALARM));
 
         // Play should request audio focus with AUDIOFOCUS_GAIN_TRANSIENT for USAGE_ALARM
-        mPlayer.play();
+        assertFutureSuccess(mPlayer.play());
 
         waitForAudioFocus(AUDIOFOCUS_LOSS_TRANSIENT);
     }
@@ -358,7 +360,7 @@
 
         // Play should request audio focus with AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK for
         // USAGE_ASSISTANCE_NAVIGATION_GUIDANCE.
-        mPlayer.play();
+        assertFutureSuccess(mPlayer.play());
 
         waitForAudioFocus(AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK);
     }
diff --git a/media2/player/src/main/java/androidx/media2/player/AudioFocusHandler.java b/media2/player/src/main/java/androidx/media2/player/AudioFocusHandler.java
index 54797a6..9ebe58c 100644
--- a/media2/player/src/main/java/androidx/media2/player/AudioFocusHandler.java
+++ b/media2/player/src/main/java/androidx/media2/player/AudioFocusHandler.java
@@ -344,6 +344,8 @@
             }
 
             // Note: This is always the main thread, except for the test.
+            // TODO(b/138091975) Do not ignore returned Futures if feasible.
+            @SuppressWarnings("FutureReturnValueIgnored")
             @Override
             public void onReceive(Context context, Intent intent) {
                 if (!AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
@@ -387,6 +389,8 @@
 
             // This is the thread where the AudioManager was originally instantiated.
             // see: b/78617702
+            // TODO(b/138091975) Do not ignore returned Futures if feasible.
+            @SuppressWarnings("FutureReturnValueIgnored")
             @Override
             public void onAudioFocusChange(int focusGain) {
                 switch (focusGain) {
diff --git a/media2/player/src/main/java/androidx/media2/player/exoplayer/DurationProvidingMediaSource.java b/media2/player/src/main/java/androidx/media2/player/exoplayer/DurationProvidingMediaSource.java
deleted file mode 100644
index 5c52b8f..0000000
--- a/media2/player/src/main/java/androidx/media2/player/exoplayer/DurationProvidingMediaSource.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2019 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.media2.player.exoplayer;
-
-import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
-
-import android.annotation.SuppressLint;
-
-import androidx.annotation.RestrictTo;
-import androidx.media2.exoplayer.external.C;
-import androidx.media2.exoplayer.external.Timeline;
-import androidx.media2.exoplayer.external.source.CompositeMediaSource;
-import androidx.media2.exoplayer.external.source.MediaPeriod;
-import androidx.media2.exoplayer.external.source.MediaSource;
-import androidx.media2.exoplayer.external.upstream.Allocator;
-import androidx.media2.exoplayer.external.upstream.TransferListener;
-
-/**
- * Wraps a {@link MediaSource} and exposes its duration.
- *
- * @hide
- */
-@RestrictTo(LIBRARY_GROUP_PREFIX)
-@SuppressLint("RestrictedApi") // TODO(b/68398926): Remove once RestrictedApi checks are fixed.
-/* package */ class DurationProvidingMediaSource extends CompositeMediaSource<Void> {
-
-    private final MediaSource mMediaSource;
-
-    private Timeline mCurrentTimeline;
-
-    DurationProvidingMediaSource(MediaSource mediaSource) {
-        mMediaSource = mediaSource;
-    }
-
-    /**
-     * Returns the duration of the wrapped source in milliseconds if known, or {@link C#TIME_UNSET}
-     * otherwise.
-     */
-    public long getDurationMs() {
-        return mCurrentTimeline == null ? C.TIME_UNSET :
-                mCurrentTimeline.getWindow(
-                        /* windowIndex= */ 0,
-                        new Timeline.Window()).getDurationMs();
-    }
-
-    @Override
-    public void prepareSourceInternal(TransferListener mediaTransferListener) {
-        super.prepareSourceInternal(mediaTransferListener);
-        prepareChildSource(/* id= */ null, mMediaSource);
-    }
-
-    @Override
-    protected void onChildSourceInfoRefreshed(Void id,
-            MediaSource mediaSource, Timeline timeline) {
-        mCurrentTimeline = timeline;
-        refreshSourceInfo(timeline);
-    }
-
-    @Override
-    public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs) {
-        return mMediaSource.createPeriod(id, allocator, startPositionUs);
-    }
-
-    @Override
-    public void releasePeriod(MediaPeriod mediaPeriod) {
-        mMediaSource.releasePeriod(mediaPeriod);
-    }
-
-}
diff --git a/media2/player/src/main/java/androidx/media2/player/exoplayer/ExoPlayerMediaPlayer2Impl.java b/media2/player/src/main/java/androidx/media2/player/exoplayer/ExoPlayerMediaPlayer2Impl.java
index 74c82e5..8e998a4 100644
--- a/media2/player/src/main/java/androidx/media2/player/exoplayer/ExoPlayerMediaPlayer2Impl.java
+++ b/media2/player/src/main/java/androidx/media2/player/exoplayer/ExoPlayerMediaPlayer2Impl.java
@@ -570,7 +570,6 @@
                 }
             }
         }
-        mTaskHandler.removeCallbacksAndMessages(null);
         runPlayerCallableBlocking(new Callable<Void>() {
             @Override
             public Void call() {
@@ -591,13 +590,19 @@
             }
             mHandlerThread = null;
         }
-        runPlayerCallableBlocking(new Callable<Void>() {
+        final ResolvableFuture<Void> future = ResolvableFuture.create();
+        mTaskHandler.post(new Runnable() {
             @Override
-            public Void call() {
-                mPlayer.close();
-                return null;
+            public void run() {
+                try {
+                    mPlayer.close();
+                    future.set(null);
+                } catch (Throwable e) {
+                    future.setException(e);
+                }
             }
         });
+        getPlayerFuture(future);
         handlerThread.quit();
     }
 
@@ -826,22 +831,30 @@
      * Runs the specified callable on the player thread, blocking the calling thread until a result
      * is returned.
      *
-     * <p>Note: ExoPlayer methods apart from {@link Player#release} are asynchronous, so calling
-     * player methods will not block the caller thread for a substantial amount of time.
+     * <p>Note: ExoPlayer methods do not block (except {@link Player#release}, which needs to
+     * block until resources have been released) so the caller thread will not be blocked for a
+     * substantial amount of time.
      */
     private <T> T runPlayerCallableBlocking(final Callable<T> callable) {
         final ResolvableFuture<T> future = ResolvableFuture.create();
-        boolean success = mTaskHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    future.set(callable.call());
-                } catch (Throwable e) {
-                    future.setException(e);
+        synchronized (mLock) {
+            Preconditions.checkNotNull(mHandlerThread);
+            boolean success = mTaskHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        future.set(callable.call());
+                    } catch (Throwable e) {
+                        future.setException(e);
+                    }
                 }
-            }
-        });
-        Preconditions.checkState(success);
+            });
+            Preconditions.checkState(success);
+        }
+        return getPlayerFuture(future);
+    }
+
+    private static <T> T getPlayerFuture(ResolvableFuture<T> future) {
         try {
             T result;
             boolean wasInterrupted = false;
diff --git a/media2/player/src/main/java/androidx/media2/player/exoplayer/ExoPlayerWrapper.java b/media2/player/src/main/java/androidx/media2/player/exoplayer/ExoPlayerWrapper.java
index f7b801f..3881bc8 100644
--- a/media2/player/src/main/java/androidx/media2/player/exoplayer/ExoPlayerWrapper.java
+++ b/media2/player/src/main/java/androidx/media2/player/exoplayer/ExoPlayerWrapper.java
@@ -232,41 +232,23 @@
 
     public void seekTo(long position, @MediaPlayer2.SeekMode int mode) {
         mPlayer.setSeekParameters(ExoPlayerUtils.getSeekParameters(mode));
-        MediaItem mediaItem = mMediaItemQueue.getCurrentMediaItem();
-        if (mediaItem != null) {
-            Preconditions.checkArgument(
-                    mediaItem.getStartPosition() <= position
-                            && mediaItem.getEndPosition() >= position,
-                    "Requested seek position is out of range : " + position);
-            position -= mediaItem.getStartPosition();
-        }
         mPlayer.seekTo(position);
     }
 
     public long getCurrentPosition() {
         Preconditions.checkState(getState() != MediaPlayer2.PLAYER_STATE_IDLE);
-        long position = Math.max(0, mPlayer.getCurrentPosition());
-        MediaItem mediaItem = mMediaItemQueue.getCurrentMediaItem();
-        if (mediaItem != null) {
-            position += mediaItem.getStartPosition();
-        }
-        return position;
+        return Math.max(0, mPlayer.getCurrentPosition());
     }
 
     public long getDuration() {
         Preconditions.checkState(getState() != MediaPlayer2.PLAYER_STATE_IDLE);
-        long duration = mMediaItemQueue.getCurrentMediaItemDuration();
+        long duration = mPlayer.getDuration();
         return duration == C.TIME_UNSET ? -1 : duration;
     }
 
     public long getBufferedPosition() {
         Preconditions.checkState(getState() != MediaPlayer2.PLAYER_STATE_IDLE);
-        long position = mPlayer.getBufferedPosition();
-        MediaItem mediaItem = mMediaItemQueue.getCurrentMediaItem();
-        if (mediaItem != null) {
-            position += mediaItem.getStartPosition();
-        }
-        return position;
+        return mPlayer.getBufferedPosition();
     }
 
     public @MediaPlayer2.MediaPlayer2State int getState() {
@@ -829,16 +811,10 @@
     private static final class MediaItemInfo {
 
         final MediaItem mMediaItem;
-        @Nullable
-        final DurationProvidingMediaSource mDurationProvidingMediaSource;
         final boolean mIsRemote;
 
-        MediaItemInfo(
-                MediaItem mediaItem,
-                @Nullable DurationProvidingMediaSource durationProvidingMediaSource,
-                boolean isRemote) {
+        MediaItemInfo(MediaItem mediaItem, boolean isRemote) {
             mMediaItem = mediaItem;
-            mDurationProvidingMediaSource = durationProvidingMediaSource;
             mIsRemote = isRemote;
         }
 
@@ -923,11 +899,12 @@
 
         public void setNextMediaItems(List<MediaItem> mediaItems) {
             int size = mConcatenatingMediaSource.getSize();
+            List<MediaItemInfo> oldMediaItemInfos = new ArrayList<>(size > 1 ? size - 1 : 0);
             if (size > 1) {
                 mConcatenatingMediaSource.removeMediaSourceRange(
                         /* fromIndex= */ 1, /* toIndex= */ size);
                 while (mMediaItemInfos.size() > 1) {
-                    releaseMediaItem(mMediaItemInfos.removeLast());
+                    oldMediaItemInfos.add(mMediaItemInfos.removeLast());
                 }
             }
 
@@ -943,6 +920,13 @@
                         mediaSources);
             }
             mConcatenatingMediaSource.addMediaSources(mediaSources);
+
+            // Release old media items after appending new ones, so that any items that are present
+            // both before and after this call have their reference counts incremented before they
+            // are decremented.
+            for (MediaItemInfo mediaItemInfo : oldMediaItemInfos) {
+                releaseMediaItem(mediaItemInfo);
+            }
         }
 
         public void preparePlayer() {
@@ -954,19 +938,6 @@
             return mMediaItemInfos.isEmpty() ? null : mMediaItemInfos.peekFirst().mMediaItem;
         }
 
-        public long getCurrentMediaItemDuration() {
-            if (mMediaItemInfos.isEmpty()) {
-                return C.TIME_UNSET;
-            }
-            DurationProvidingMediaSource durationProvidingMediaSource =
-                    mMediaItemInfos.peekFirst().mDurationProvidingMediaSource;
-            if (durationProvidingMediaSource != null) {
-                return durationProvidingMediaSource.getDurationMs();
-            } else {
-                return mPlayer.getDuration();
-            }
-        }
-
         public long getCurrentMediaItemPlayingTimeMs() {
             return C.usToMs(mCurrentMediaItemPlayingTimeUs);
         }
@@ -1055,16 +1026,16 @@
             MediaSource mediaSource = ExoPlayerUtils.createUnclippedMediaSource(
                     mContext, dataSourceFactory, mediaItem);
 
-            // Apply clipping if needed. Because ExoPlayer doesn't expose the unclipped duration, we
-            // wrap the child source in an intermediate source that lets us access its duration.
-            DurationProvidingMediaSource durationProvidingMediaSource = null;
+            // Apply clipping if needed.
             long startPosition = mediaItem.getStartPosition();
             long endPosition = mediaItem.getEndPosition();
             if (startPosition != 0L || endPosition != MediaItem.POSITION_UNKNOWN) {
-                durationProvidingMediaSource = new DurationProvidingMediaSource(mediaSource);
+                if (endPosition == MediaItem.POSITION_UNKNOWN) {
+                    endPosition = C.TIME_END_OF_SOURCE;
+                }
                 // Disable the initial discontinuity to give seamless transitions to clips.
                 mediaSource = new ClippingMediaSource(
-                        durationProvidingMediaSource,
+                        mediaSource,
                         C.msToUs(startPosition),
                         C.msToUs(endPosition),
                         /* enableInitialDiscontinuity= */ false,
@@ -1075,8 +1046,7 @@
             boolean isRemote = mediaItem instanceof UriMediaItem
                     && !Util.isLocalFileUri(((UriMediaItem) mediaItem).getUri());
             mediaSources.add(mediaSource);
-            mediaItemInfos.add(
-                    new MediaItemInfo(mediaItem, durationProvidingMediaSource, isRemote));
+            mediaItemInfos.add(new MediaItemInfo(mediaItem, isRemote));
         }
 
         private void releaseMediaItem(MediaItemInfo mediaItemInfo) {
@@ -1089,8 +1059,7 @@
                     mFileDescriptorRegistry.unregisterMediaItem(fileDescriptor);
                     ((FileMediaItem) mediaItem).decreaseRefCount();
                 } else if (mediaItem instanceof CallbackMediaItem) {
-                    ((CallbackMediaItem) mediaItemInfo.mMediaItem)
-                            .getDataSourceCallback().close();
+                    ((CallbackMediaItem) mediaItem).getDataSourceCallback().close();
                 }
             } catch (IOException e) {
                 Log.w(TAG, "Error releasing media item " + mediaItem, e);
diff --git a/media2/session/api/api_lint.ignore b/media2/session/api/api_lint.ignore
index 3cd34b0..8ed00c0 100644
--- a/media2/session/api/api_lint.ignore
+++ b/media2/session/api/api_lint.ignore
@@ -3,3 +3,37 @@
     Inconsistent interface constant; expected 'MediaLibraryService'`
 InterfaceConstant: androidx.media2.session.MediaSessionService#SERVICE_INTERFACE:
     Inconsistent interface constant; expected 'MediaSessionService'`
+
+
+MissingNullability: androidx.media2.session.HeartRating#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.media2.session.HeartRating#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.media2.session.MediaLibraryService#onBind(android.content.Intent):
+    Missing nullability on method `onBind` return
+MissingNullability: androidx.media2.session.MediaSession.ControllerInfo#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.media2.session.MediaSession.ControllerInfo#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.media2.session.MediaSessionService#onStartCommand(android.content.Intent, int, int) parameter #0:
+    Missing nullability on parameter `intent` in method `onStartCommand`
+MissingNullability: androidx.media2.session.PercentageRating#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.media2.session.PercentageRating#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.media2.session.SessionCommand#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.media2.session.SessionCommandGroup#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.media2.session.SessionToken#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.media2.session.SessionToken#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.media2.session.StarRating#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.media2.session.StarRating#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.media2.session.ThumbRating#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.media2.session.ThumbRating#toString():
+    Missing nullability on method `toString` return
diff --git a/media2/session/src/main/java/androidx/media2/session/ConnectedControllersManager.java b/media2/session/src/main/java/androidx/media2/session/ConnectedControllersManager.java
index 2b5fcc2..7b541e6 100644
--- a/media2/session/src/main/java/androidx/media2/session/ConnectedControllersManager.java
+++ b/media2/session/src/main/java/androidx/media2/session/ConnectedControllersManager.java
@@ -160,7 +160,7 @@
      *
      * @param controllerKey key
      * @return sequenced future manager. Can be {@code null} if the controller was null or
-     *         disconencted.
+     *         disconnected.
      */
     public SequencedFutureManager getSequencedFutureManager(@Nullable T controllerKey) {
         ConnectedControllerRecord info;
diff --git a/media2/session/src/main/java/androidx/media2/session/MediaBrowser.java b/media2/session/src/main/java/androidx/media2/session/MediaBrowser.java
index 9e1e3a8..34538d4 100644
--- a/media2/session/src/main/java/androidx/media2/session/MediaBrowser.java
+++ b/media2/session/src/main/java/androidx/media2/session/MediaBrowser.java
@@ -75,11 +75,11 @@
     }
 
     /**
-     * Create a {@link MediaBrowser} from the {@link SessionToken}.
+     * Creates a {@link MediaBrowser} from the {@link SessionToken}.
      *
-     * @param context Context
+     * @param context context
      * @param token token to connect to
-     * @param executor executor to run callbacks on.
+     * @param executor executor to run callbacks on
      * @param callback controller callback to receive changes in
      */
     MediaBrowser(@NonNull Context context, @NonNull SessionToken token,
@@ -152,7 +152,7 @@
      * Unsubscribes for changes to the children of the parent, which was previously subscribed with
      * {@link #subscribe(String, LibraryParams)}.
      * <p>
-     * This unsubscribes all previous subscription with the parent id, regardless of the library
+     * This unsubscribes all previous subscriptions with the parent id, regardless of the library
      * param that was previously sent to the library service.
      *
      * @param parentId non-empty parent id
@@ -176,7 +176,7 @@
      *
      * @param parentId non-empty parent id for getting the children
      * @param page page number to get the result. Starts from {@code 0}
-     * @param pageSize page size. Should be greater or equal to {@code 1}
+     * @param pageSize page size. Should be greater than or equal to {@code 1}
      * @param params library params
      * @see LibraryResult#getMediaItems()
      */
@@ -222,16 +222,15 @@
     /**
      * Sends a search request to the library service.
      * <p>
-     * Returned {@link LibraryResult} will only tell whether the attemp to search was successful.
-     * For getting the search result, waits for
-     * {@link BrowserCallback#getSearchResult(String, int, int, LibraryParams)}
-     * the search result
-     * and calls {@link #getSearchResult(String, int, int, LibraryParams)}}
+     * Returned {@link LibraryResult} will only tell whether the attempt to search was successful.
+     * For getting the search result, wait for
+     * {@link BrowserCallback#onSearchResultChanged(MediaBrowser, String, int, LibraryParams)}
+     * being called and call {@link #getSearchResult(String, int, int, LibraryParams)}}
      * for getting the result.
      *
      * @param query non-empty search query
      * @param params library params
-     * @see BrowserCallback#getSearchResult(String, int, int, LibraryParams)
+     * @see BrowserCallback#onSearchResultChanged(MediaBrowser, String, int, LibraryParams)
      * @see #getSearchResult(String, int, int, LibraryParams)
      */
     @NonNull
@@ -247,7 +246,7 @@
     }
 
     /**
-     * Gets the search result from lhe library service.
+     * Gets the search result from the library service.
      * <p>
      * If it's successfully completed, {@link LibraryResult#getMediaItems()} will return the search
      * result.
@@ -336,9 +335,9 @@
         }
 
         /**
-         * Build {@link MediaBrowser}.
-         * <p>
-         * It will throw an {@link IllegalArgumentException} if both {@link SessionToken} and
+         * Builds a {@link MediaBrowser}.
+         *
+         * @throws IllegalArgumentException if both {@link SessionToken} and
          * {@link MediaSessionCompat.Token} are not set.
          *
          * @return a new browser
diff --git a/media2/session/src/main/java/androidx/media2/session/MediaConstants.java b/media2/session/src/main/java/androidx/media2/session/MediaConstants.java
index 65129a7..318572d 100644
--- a/media2/session/src/main/java/androidx/media2/session/MediaConstants.java
+++ b/media2/session/src/main/java/androidx/media2/session/MediaConstants.java
@@ -28,8 +28,6 @@
     static final String ARGUMENT_PID = "androidx.media2.argument.PID";
     static final String ARGUMENT_PACKAGE_NAME = "androidx.media2.argument.PACKAGE_NAME";
 
-    static final String ROOT_EXTRA_DEFAULT = "androidx.media2.root_default_root";
-
     private MediaConstants() {
     }
 }
diff --git a/media2/session/src/main/java/androidx/media2/session/MediaController.java b/media2/session/src/main/java/androidx/media2/session/MediaController.java
index bbe069d..ae56798 100644
--- a/media2/session/src/main/java/androidx/media2/session/MediaController.java
+++ b/media2/session/src/main/java/androidx/media2/session/MediaController.java
@@ -76,7 +76,7 @@
  * <p>
  * MediaController objects are thread-safe.
  * <p>
- * Topic covered here:
+ * Topics covered here:
  * <ol>
  * <li><a href="#ControllerLifeCycle">Controller Lifecycle</a>
  * </ol>
@@ -145,11 +145,11 @@
     Long mTimeDiff;
 
     /**
-     * Create a {@link MediaController} from the {@link SessionToken}.
+     * Creates a {@link MediaController} from the {@link SessionToken}.
      *
-     * @param context Context
+     * @param context context
      * @param token token to connect to
-     * @param executor executor to run callbacks on.
+     * @param executor executor to run callbacks on
      * @param callback controller callback to receive changes in
      */
     MediaController(@NonNull final Context context, @NonNull final SessionToken token,
@@ -169,11 +169,11 @@
     }
 
     /**
-     * Create a {@link MediaController} from the {@link MediaSessionCompat.Token}.
+     * Creates a {@link MediaController} from the {@link MediaSessionCompat.Token}.
      *
-     * @param context Context
+     * @param context context
      * @param token token to connect to
-     * @param executor executor to run callbacks on.
+     * @param executor executor to run callbacks on
      * @param callback controller callback to receive changes in
      */
     MediaController(@NonNull final Context context, @NonNull final MediaSessionCompat.Token token,
@@ -224,7 +224,7 @@
     }
 
     /**
-     * Release this object, and disconnect from the session. After this, callbacks wouldn't be
+     * Releases this object, and disconnects from the session. After this, callbacks wouldn't be
      * received.
      */
     @Override
@@ -247,10 +247,10 @@
     }
 
     /**
-     * Returns {@link SessionToken} of the connected session.
+     * Returns the {@link SessionToken} of the connected session.
      * If it is not connected yet, it returns {@code null}.
      * <p>
-     * This may differ with the {@link SessionToken} from the constructor. For example, if the
+     * This may differ from the {@link SessionToken} from the constructor. For example, if the
      * controller is created with the token for {@link MediaSessionService}, this would return
      * token for the {@link MediaSession} in the service.
      *
@@ -274,7 +274,7 @@
      * <p>
      * If the player state is {@link SessionPlayer#PLAYER_STATE_IDLE}, the session would also call
      * {@link SessionPlayer#prepare} and then {@link SessionPlayer#play} to start playback. If you
-     * want to have finer grained control of the playback start call {@link #prepare} manually
+     * want to have finer grained control of the playback start, call {@link #prepare} manually
      * before this. Calling {@link #prepare} in advance would help this method to start playback
      * faster and also help to take audio focus at the last moment.
      *
@@ -322,7 +322,7 @@
     }
 
     /**
-     * Requests session to increase the playback speed.
+     * Requests that the player increases the playback speed.
      *
      * @see MediaSession.SessionCallback#onFastForward(MediaSession, MediaSession.ControllerInfo)
      */
@@ -335,7 +335,7 @@
     }
 
     /**
-     * Requests session to decrease the playback speed.
+     * Requests that the player decreases the playback speed.
      *
      * @see MediaSession.SessionCallback#onRewind(MediaSession, MediaSession.ControllerInfo)
      */
@@ -348,7 +348,7 @@
     }
 
     /**
-     * Requests session to skip backward within the current media item.
+     * Requests that the player skips backward within the current media item.
      *
      * @see MediaSession.SessionCallback#onSkipForward(MediaSession, MediaSession.ControllerInfo)
      */
@@ -362,7 +362,7 @@
     }
 
     /**
-     * Requests session to skip forward within the current media item.
+     * Requests that the player skips forward within the current media item.
      *
      * @see MediaSession.SessionCallback#onSkipBackward(MediaSession, MediaSession.ControllerInfo)
      */
@@ -376,9 +376,9 @@
     }
 
     /**
-     * Move to a new location in the media stream.
+     * Requests that the player moves to a new location in the media stream.
      *
-     * @param pos Position to move to, in milliseconds.
+     * @param pos position to move to, in milliseconds
      */
     @NonNull
     public ListenableFuture<SessionResult> seekTo(long pos) {
@@ -389,11 +389,11 @@
     }
 
     /**
-     * Requests that the player start playback for a specific media id.
+     * Requests that the player starts playback for a specific media id.
      *
-     * @param mediaId The non-empty media id
-     * @param extras Optional extras that can include extra information about the media item
-     *               to be played.
+     * @param mediaId the non-empty media id
+     * @param extras optional extras that can include extra information about the media item
+     *               to be played
      * @hide
      */
     @RestrictTo(LIBRARY_GROUP_PREFIX)
@@ -410,10 +410,10 @@
     }
 
     /**
-     * Requests that the player start playback for a specific search query.
+     * Requests that the player starts playback for a specific search query.
      *
-     * @param query The non-empty search query
-     * @param extras Optional extras that can include extra information about the query.
+     * @param query the non-empty search query
+     * @param extras optional extras that can include extra information about the query
      * @hide
      */
     @RestrictTo(LIBRARY_GROUP_PREFIX)
@@ -430,11 +430,11 @@
     }
 
     /**
-     * Requests that the player start playback for a specific {@link Uri}.
+     * Requests that the player starts playback for a specific {@link Uri}.
      *
-     * @param uri The URI of the requested media.
-     * @param extras Optional extras that can include extra information about the media item
-     *               to be played.
+     * @param uri the URI of the requested media
+     * @param extras optional extras that can include extra information about the media item
+     *               to be played
      * @hide
      */
     @RestrictTo(LIBRARY_GROUP_PREFIX)
@@ -451,7 +451,7 @@
     }
 
     /**
-     * Requests that the player prepare a media item with the media id for playback.
+     * Requests that the player prepares a media item with the media id for playback.
      * In other words, other sessions can continue to play during the preparation of this session.
      * This method can be used to speed up the start of the playback.
      * Once the prepare is done, the session will change its playback state to
@@ -459,9 +459,9 @@
      * playback. If the prepare is not needed, {@link #playFromMediaId} can be directly called
      * without this method.
      *
-     * @param mediaId The non-empty media id
-     * @param extras Optional extras that can include extra information about the media item
-     *               to be prepared.
+     * @param mediaId the non-empty media id
+     * @param extras optional extras that can include extra information about the media item
+     *               to be prepared
      * @hide
      */
     @RestrictTo(LIBRARY_GROUP_PREFIX)
@@ -478,7 +478,7 @@
     }
 
     /**
-     * Requests that the player prepare a media item with the specific search query for playback.
+     * Requests that the player prepares a media item with the specific search query for playback.
      * In other words, other sessions can continue to play during the preparation of this session.
      * This method can be used to speed up the start of the playback.
      * Once the prepare is done, the session will change its playback state to
@@ -486,8 +486,8 @@
      * playback. If the prepare is not needed, {@link #playFromSearch} can be directly called
      * without this method.
      *
-     * @param query The non-empty search query
-     * @param extras Optional extras that can include extra information about the query.
+     * @param query the non-empty search query
+     * @param extras optional extras that can include extra information about the query
      * @hide
      */
     @RestrictTo(LIBRARY_GROUP_PREFIX)
@@ -504,7 +504,7 @@
     }
 
     /**
-     * Requests that the player prepare a media item with the specific {@link Uri} for playback.
+     * Requests that the player prepares a media item with the specific {@link Uri} for playback.
      * In other words, other sessions can continue to play during the preparation of this session.
      * This method can be used to speed up the start of the playback.
      * Once the prepare is done, the session will change its playback state to
@@ -512,9 +512,9 @@
      * playback. If the prepare is not needed, {@link #playFromUri} can be directly called
      * without this method.
      *
-     * @param uri The URI of the requested media.
-     * @param extras Optional extras that can include extra information about the media item
-     *               to be prepared.
+     * @param uri the URI of the requested media
+     * @param extras optional extras that can include extra information about the media item
+     *               to be prepared
      * @hide
      */
     @RestrictTo(LIBRARY_GROUP_PREFIX)
@@ -531,8 +531,8 @@
     }
 
     /**
-     * Set the volume of the output this session is playing on. The command will be ignored if it
-     * does not support {@link VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE}.
+     * Requests that the player sets the volume of the output that is playing on. The command will
+     * be ignored if it does not support {@link VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE}.
      * <p>
      * If the session is local playback, this changes the device's volume with the stream that
      * session's player is using. Flags will be specified for the {@link AudioManager}.
@@ -541,7 +541,7 @@
      * will receive this request instead.
      *
      * @see #getPlaybackInfo()
-     * @param value The value to set it to, between 0 and the reported max.
+     * @param value the value to set it to, between 0 and the reported max
      * @param flags flags from {@link AudioManager} to include with the volume request for local
      *              playback
      */
@@ -554,8 +554,8 @@
     }
 
     /**
-     * Adjust the volume of the output this session is playing on. The direction
-     * must be one of {@link AudioManager#ADJUST_LOWER},
+     * Requests that the player adjusts the volume of the output that is playing on.
+     * The direction must be one of {@link AudioManager#ADJUST_LOWER},
      * {@link AudioManager#ADJUST_RAISE}, or {@link AudioManager#ADJUST_SAME}.
      * <p>
      * The command will be ignored if the session does not support
@@ -583,10 +583,10 @@
     }
 
     /**
-     * Get an intent for launching UI associated with this session if one exists.
+     * Gets an intent for launching UI associated with this session if one exists.
      * If it is not connected yet, it returns {@code null}.
      *
-     * @return A {@link PendingIntent} to launch UI or null
+     * @return a {@link PendingIntent} to launch UI or null
      */
     @Nullable
     public PendingIntent getSessionActivity() {
@@ -594,7 +594,7 @@
     }
 
     /**
-     * Get the lastly cached player state from
+     * Gets the lastly cached player state from
      * {@link ControllerCallback#onPlayerStateChanged(MediaController, int)}.
      * If it is not connected yet, it returns {@link SessionPlayer#PLAYER_STATE_IDLE}.
      *
@@ -628,7 +628,7 @@
     }
 
     /**
-     * Get the lastly cached playback speed from
+     * Gets the lastly cached playback speed from
      * {@link ControllerCallback#onPlaybackSpeedChanged(MediaController, float)}.
      *
      * @return speed the lastly cached playback speed, or 0f if unknown or not connected
@@ -638,8 +638,8 @@
     }
 
     /**
-     * Sets the playback speed. A value of {@code 1.0f} is the default playback value,
-     * and a negative value indicates reverse playback. {@code 0.0f} is not allowed.
+     * Requests that the player sets the playback speed. A value of {@code 1.0f} is the default
+     * playback value, and a negative value indicates reverse playback. {@code 0.0f} is not allowed.
      *
      * @throws IllegalArgumentException if the {@code speed} is equal to zero.
      */
@@ -683,7 +683,7 @@
      * Get the current playback info for this session.
      * If it is not connected yet, it returns {@code null}.
      *
-     * @return The current playback info or null
+     * @return the current playback info or null
      */
     @Nullable
     public PlaybackInfo getPlaybackInfo() {
@@ -691,16 +691,16 @@
     }
 
     /**
-     * Rate the media. This will cause the rating to be set for the current user.
-     * The rating style must follow the user rating style from the session.
+     * Requests that the player rates the media. This will cause the rating to be set for the
+     * current user. The rating style must follow the user rating style from the session.
      * You can get the rating style from the session through the
      * {@link MediaMetadata#getRating(String)} with the key
      * {@link MediaMetadata#METADATA_KEY_USER_RATING}.
      * <p>
      * If the user rating was {@code null}, the media item does not accept setting user rating.
      *
-     * @param mediaId The non-empty media id
-     * @param rating The rating to set
+     * @param mediaId the non-empty media id
+     * @param rating the rating to set
      */
     @NonNull
     public ListenableFuture<SessionResult> setRating(@NonNull String mediaId,
@@ -720,7 +720,7 @@
     }
 
     /**
-     * Send custom command to the session
+     * Sends a custom command to the session
      * <p>
      * Interoperability: When connected to
      * {@link android.support.v4.media.session.MediaSessionCompat},
@@ -752,13 +752,13 @@
      * Returns the cached playlist from {@link ControllerCallback#onPlaylistChanged}. Can be
      * {@code null} if the playlist hasn't been set or it's reset by {@link #setMediaItem}.
      * <p>
-     * This list may differ with the list that was specified with
+     * This list may differ from the list that was specified with
      * {@link #setPlaylist(List, MediaMetadata)} depending on the {@link SessionPlayer}
      * implementation. Use media items returned here for other playlist agent APIs such as
      * {@link SessionPlayer#skipToPlaylistItem}.
      *
      * @return playlist, or {@code null} if the playlist hasn't been set, controller isn't
-     *         connected, or it doesn't have enough permission.
+     *         connected, or it doesn't have enough permission
      * @see SessionCommand#COMMAND_CODE_PLAYER_GET_PLAYLIST
      */
     @Nullable
@@ -767,8 +767,8 @@
     }
 
     /**
-     * Sets the playlist with the list of media IDs. Use this or {@link #setMediaItem} to specify
-     * which items to play.
+     * Requests that the player sets the playlist with the list of media IDs. Use this or
+     * {@link #setMediaItem} to specify which items to play.
      * <p>
      * All media IDs in the list shouldn't be an empty string.
      * <p>
@@ -802,16 +802,16 @@
     }
 
     /**
-     * Sets a {@link MediaItem} for playback with the media ID. Use this or {@link #setPlaylist}
-     * to specify which items to play. If you want to change current item in the playlist, use one
-     * of {@link #skipToPlaylistItem}, {@link #skipToNextPlaylistItem}, or
+     * Requests that the player sets a {@link MediaItem} for playback with the media ID. Use this or
+     * {@link #setPlaylist} to specify which items to play. If you want to change current item
+     * in the playlist, use one of {@link #skipToPlaylistItem}, {@link #skipToNextPlaylistItem}, or
      * {@link #skipToPreviousPlaylistItem} instead of this method.
      * <p>
      * The {@link ControllerCallback#onPlaylistChanged} and
      * {@link ControllerCallback#onCurrentMediaItemChanged} would be called when it's completed.
      * The current item would be the item given here.
      *
-     * @param mediaId The non-empty media id of the item to play
+     * @param mediaId the non-empty media id of the item to play
      * @see #setPlaylist
      * @see ControllerCallback#onCurrentMediaItemChanged
      * @see ControllerCallback#onPlaylistChanged
@@ -829,7 +829,7 @@
     }
 
     /**
-     * Updates the playlist metadata
+     * Requests that the player updates the playlist metadata
      *
      * @param metadata metadata of the playlist
      */
@@ -847,7 +847,7 @@
      * {@link ControllerCallback#onPlaylistMetadataChanged} or
      * {@link ControllerCallback#onPlaylistChanged}.
      *
-     * @return metadata metadata of the playlist, or null if none is set or the controller is not
+     * @return metadata of the playlist, or null if none is set or the controller is not
      *         connected
      */
     @Nullable
@@ -856,16 +856,16 @@
     }
 
     /**
-     * Adds the media item to the playlist at the index with the media ID. Index equals or greater
-     * than the current playlist size (e.g. {@link Integer#MAX_VALUE}) will add the item at the end
-     * of the playlist.
+     * Requests that the player adds the media item to the playlist at the index with the media
+     * ID. Index equals to or greater than the current playlist size
+     * (e.g. {@link Integer#MAX_VALUE}) will add the item at the end of the playlist.
      * <p>
      * This will not change the currently playing media item.
      * If index is less than or equal to the current index of the playlist,
      * the current index of the playlist will be incremented correspondingly.
      *
      * @param index the index you want to add
-     * @param mediaId The non-empty media id of the new item
+     * @param mediaId the non-empty media id of the new item
      * @see MediaMetadata#METADATA_KEY_MEDIA_ID
      */
     @NonNull
@@ -884,7 +884,7 @@
     }
 
     /**
-     * Removes the media item at index in the playlist.
+     * Requests that the player removes the media item at index in the playlist.
      * <p>
      * If the item is the currently playing item of the playlist, current playback
      * will be stopped and playback moves to next source in the list.
@@ -903,10 +903,10 @@
     }
 
     /**
-     * Replaces the media item at index in the playlist with the media ID.
+     * Requests that the player replaces the media item at index in the playlist with the media ID.
      *
      * @param index the index of the item to replace
-     * @param mediaId The non-empty media id of the new item
+     * @param mediaId the non-empty media id of the new item
      * @see MediaMetadata#METADATA_KEY_MEDIA_ID
      */
     @NonNull
@@ -925,7 +925,8 @@
     }
 
     /**
-     * Moves the media item at {@code fromIdx} to {@code toIdx} in the playlist.
+     * Requests that the player moves the media item at {@code fromIdx} to {@code toIdx} in the
+     * playlist.
      * <p>
      * {@link ControllerCallback#onPlaylistChanged} will be called when it's completed.
      * <p>
@@ -1004,7 +1005,7 @@
     }
 
     /**
-     * Skips to the previous item in the playlist.
+     * Requests that the player skips to the previous item in the playlist.
      * <p>
      * This calls {@link SessionPlayer#skipToPreviousPlaylistItem()}.
      */
@@ -1017,7 +1018,7 @@
     }
 
     /**
-     * Skips to the next item in the playlist.
+     * Requests that the player skips to the next item in the playlist.
      * <p>
      * This calls {@link SessionPlayer#skipToNextPlaylistItem()}.
      */
@@ -1030,7 +1031,7 @@
     }
 
     /**
-     * Skips to the item in the playlist at the index.
+     * Requests that the player skips to the item in the playlist at the index.
      * <p>
      * This calls {@link SessionPlayer#skipToPlaylistItem(int)}.
      *
@@ -1063,7 +1064,7 @@
     }
 
     /**
-     * Sets the repeat mode.
+     * Requests that the player sets the repeat mode.
      *
      * @param repeatMode repeat mode
      * @see SessionPlayer#REPEAT_MODE_NONE
@@ -1094,7 +1095,7 @@
     }
 
     /**
-     * Sets the shuffle mode.
+     * Requests that the player sets the shuffle mode.
      *
      * @param shuffleMode The shuffle mode
      * @see SessionPlayer#SHUFFLE_MODE_NONE
@@ -1490,11 +1491,10 @@
         }
 
         /**
-         * Build {@link MediaController}.
-         * <p>
-         * It will throw an {@link IllegalArgumentException} if both {@link SessionToken} and
-         * {@link MediaSessionCompat.Token} are not set.
+         * Builds a {@link MediaController}.
          *
+         * @throws IllegalArgumentException if both {@link SessionToken} and
+         * {@link MediaSessionCompat.Token} are not set.
          * @return a new controller
          */
         @Override
@@ -1554,7 +1554,7 @@
         }
 
         /**
-         * Set the {@link SessionToken} for the controller to connect to.
+         * Sets the {@link SessionToken} for the controller to connect to.
          * <p>
          * When this method is called, the {@link MediaSessionCompat.Token} which was set by calling
          * {@link #setSessionCompatToken} is removed.
@@ -1585,7 +1585,7 @@
          * </ol>
          *
          * @param token token to connect to
-         * @return The Builder to allow chaining
+         * @return the Builder to allow chaining
          * @see MediaSessionService#onGetSession(ControllerInfo)
          * @see #getConnectedSessionToken()
          * @see #setConnectionHints(Bundle)
@@ -1602,13 +1602,13 @@
         }
 
         /**
-         * Set the {@link MediaSessionCompat.Token} for the controller to connect to.
+         * Sets the {@link MediaSessionCompat.Token} for the controller to connect to.
          * <p>
          * When this method is called, the {@link SessionToken} which was set by calling
          * {@link #setSessionToken(SessionToken)} is removed.
          *
          * @param compatToken token to connect to
-         * @return The Builder to allow chaining
+         * @return the Builder to allow chaining
          */
         @NonNull
         @SuppressWarnings("unchecked")
@@ -1622,7 +1622,7 @@
         }
 
         /**
-         * Set the connection hints for the controller.
+         * Sets the connection hints for the controller.
          * <p>
          * {@code connectionHints} is a session-specific argument to send to the session when
          * connecting. The contents of this bundle may affect the connection result.
@@ -1631,7 +1631,7 @@
          * They will be ignored when connecting to {@link MediaSessionCompat}.
          *
          * @param connectionHints a bundle which contains the connection hints
-         * @return The Builder to allow chaining
+         * @return the Builder to allow chaining
          * @throws IllegalArgumentException if the bundle contains any non-framework Parcelable
          * objects.
          */
@@ -1650,11 +1650,11 @@
         }
 
         /**
-         * Set callback for the controller and its executor.
+         * Sets the callback for the controller and its executor.
          *
          * @param executor callback executor
          * @param callback controller callback.
-         * @return The Builder to allow chaining
+         * @return the Builder to allow chaining
          */
         @NonNull
         @SuppressWarnings("unchecked")
@@ -2024,25 +2024,25 @@
         }
 
         /**
-         * Get the type of playback which affects volume handling. One of:
+         * Gets the type of playback which affects volume handling. One of:
          * <ul>
          * <li>{@link #PLAYBACK_TYPE_LOCAL}</li>
          * <li>{@link #PLAYBACK_TYPE_REMOTE}</li>
          * </ul>
          *
-         * @return The type of playback this session is using
+         * @return the type of playback this session is using
          */
         public int getPlaybackType() {
             return mPlaybackType;
         }
 
         /**
-         * Get the audio attributes for this session. The attributes will affect
+         * Gets the audio attributes for this session. The attributes will affect
          * volume handling for the session. When the volume type is
          * {@link #PLAYBACK_TYPE_REMOTE} these may be ignored by the
          * remote volume handler.
          *
-         * @return The attributes for this session
+         * @return the attributes for this session
          */
         @Nullable
         public AudioAttributesCompat getAudioAttributes() {
@@ -2050,36 +2050,36 @@
         }
 
         /**
-         * Get the type of volume control that can be used. One of:
+         * Gets the type of volume control that can be used. One of:
          * <ul>
          * <li>{@link VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE}</li>
          * <li>{@link VolumeProviderCompat#VOLUME_CONTROL_RELATIVE}</li>
          * <li>{@link VolumeProviderCompat#VOLUME_CONTROL_FIXED}</li>
          * </ul>
          *
-         * @return The type of volume control that may be used with this session
+         * @return the type of volume control that may be used with this session
          */
         public int getControlType() {
             return mControlType;
         }
 
         /**
-         * Get the maximum volume that may be set for this session.
+         * Gets the maximum volume that may be set for this session.
          * <p>
          * This is only meaningful when the playback type is {@link #PLAYBACK_TYPE_REMOTE}.
          *
-         * @return The maximum allowed volume where this session is playing
+         * @return the maximum allowed volume where this session is playing
          */
         public int getMaxVolume() {
             return mMaxVolume;
         }
 
         /**
-         * Get the current volume for this session.
+         * Gets the current volume for this session.
          * <p>
          * This is only meaningful when the playback type is {@link #PLAYBACK_TYPE_REMOTE}.
          *
-         * @return The current volume where this session is playing
+         * @return the current volume where this session is playing
          */
         public int getCurrentVolume() {
             return mCurrentVolume;
diff --git a/media2/session/src/main/java/androidx/media2/session/MediaControllerImplLegacy.java b/media2/session/src/main/java/androidx/media2/session/MediaControllerImplLegacy.java
index 625be61..4eaf798 100644
--- a/media2/session/src/main/java/androidx/media2/session/MediaControllerImplLegacy.java
+++ b/media2/session/src/main/java/androidx/media2/session/MediaControllerImplLegacy.java
@@ -93,13 +93,6 @@
     static final String SESSION_COMMAND_ON_CAPTIONING_ENABLED_CHANGED =
             "android.media.session.command.ON_CAPTIONING_ENALBED_CHANGED";
 
-    // Note: Using {@code null} doesn't helpful here because MediaBrowserServiceCompat always wraps
-    //       the rootHints so it becomes non-null.
-    static final Bundle sDefaultRootExtras = new Bundle();
-    static {
-        sDefaultRootExtras.putBoolean(MediaConstants.ROOT_EXTRA_DEFAULT, true);
-    }
-
     final Context mContext;
 
     @SuppressWarnings("WeakerAccess") /* synthetic access */
@@ -952,7 +945,7 @@
             public void run() {
                 synchronized (mLock) {
                     mBrowserCompat = new MediaBrowserCompat(mContext, mToken.getComponentName(),
-                            new ConnectionCallback(), sDefaultRootExtras);
+                            new ConnectionCallback(), null);
                     mBrowserCompat.connect();
                 }
             }
diff --git a/media2/session/src/main/java/androidx/media2/session/MediaLibraryService.java b/media2/session/src/main/java/androidx/media2/session/MediaLibraryService.java
index c9ad506..9e5b8041 100644
--- a/media2/session/src/main/java/androidx/media2/session/MediaLibraryService.java
+++ b/media2/session/src/main/java/androidx/media2/session/MediaLibraryService.java
@@ -333,7 +333,7 @@
         }
 
         /**
-         * Notify the controller of the change in a parent's children.
+         * Notifies the controller of the change in a parent's children.
          * <p>
          * If the controller hasn't subscribed to the parent, the API will do nothing.
          * <p>
@@ -363,7 +363,7 @@
         }
 
         /**
-         * Notify all controllers that subscribed to the parent about change in the parent's
+         * Notifies all controllers that subscribed to the parent about change in the parent's
          * children, regardless of the library params supplied by
          * {@link MediaBrowser#subscribe(String, LibraryParams)}.
          *  @param parentId non-empty parent id
@@ -383,7 +383,7 @@
         }
 
         /**
-         * Notify controller about change in the search result.
+         * Notifies controller about change in the search result.
          *
          * @param controller controller to notify
          * @param query previously sent non-empty search query from the controller.
@@ -568,7 +568,7 @@
         }
 
         /**
-         * Builds {@link LibraryParams}.
+         * Builds a {@link LibraryParams}.
          */
         public static final class Builder {
             private boolean mRecent;
@@ -639,7 +639,7 @@
             }
 
             /**
-             * Builds {@link LibraryParams}.
+             * Builds a {@link LibraryParams}.
              *
              * @return new LibraryParams
              */
diff --git a/media2/session/src/main/java/androidx/media2/session/MediaSession.java b/media2/session/src/main/java/androidx/media2/session/MediaSession.java
index 90664f5..8b5de07 100644
--- a/media2/session/src/main/java/androidx/media2/session/MediaSession.java
+++ b/media2/session/src/main/java/androidx/media2/session/MediaSession.java
@@ -80,7 +80,7 @@
  * instead. With it, your playback can be revived even after playback is finished. See
  * {@link MediaSessionService} for details.
  * <p>
- * Topic covered here:
+ * Topics covered here:
  * <ol>
  * <li><a href="#SessionLifecycle">Session Lifecycle</a>
  * <li><a href="#AudioFocusAndNoisyIntent">Audio focus and noisy intent</a>
@@ -339,7 +339,7 @@
     }
 
     /**
-     * Broadcasts custom command to all connected controllers.
+     * Broadcasts a custom command to all connected controllers.
      * <p>
      * This is synchronous call and doesn't wait for result from the controller. Use
      * {@link #sendCustomCommand(ControllerInfo, SessionCommand, Bundle)} for getting the result.
@@ -361,7 +361,7 @@
     }
 
     /**
-     * Send custom command to a specific controller.
+     * Sends a custom command to a specific controller.
      * <p>
      * A command is not accepted if it is not a custom command.
      *
@@ -958,9 +958,9 @@
         }
 
         /**
-         * Return if the controller has granted {@code android.permission.MEDIA_CONTENT_CONTROL} or
-         * has a enabled notification listener so can be trusted to accept connection and incoming
-         * command request.
+         * Returns if the controller has been granted
+         * {@code android.permission.MEDIA_CONTENT_CONTROL} or has a enabled notification listener
+         * so can be trusted to accept connection and incoming command request.
          *
          * @return {@code true} if the controller is trusted.
          * @hide
@@ -1035,8 +1035,8 @@
         }
 
         /**
-         * Get command associated with this button. Can be {@code null} if the button isn't enabled
-         * and only providing placeholder.
+         * Gets the command associated with this button. Can be {@code null} if the button isn't
+         * enabled and only providing placeholder.
          *
          * @return command or {@code null}
          */
@@ -1046,8 +1046,8 @@
         }
 
         /**
-         * Resource id of the button in this package. Can be {@code 0} if the command is predefined
-         * and custom icon isn't needed.
+         * Gets the resource id of the button in this package. Can be {@code 0} if the command is
+         * predefined and custom icon isn't needed.
          *
          * @return resource id of the icon. Can be {@code 0}.
          */
@@ -1056,8 +1056,8 @@
         }
 
         /**
-         * Display name of the button. Can be {@code null} or empty if the command is predefined
-         * and custom name isn't needed.
+         * Gets the display name of the button. Can be {@code null} or empty if the command is
+         * predefined and custom name isn't needed.
          *
          * @return custom display name. Can be {@code null} or empty.
          */
@@ -1067,7 +1067,8 @@
         }
 
         /**
-         * Extra information of the button. It's private information between session and controller.
+         * Gets extra information of the button. It's private information between session and
+         * controller.
          *
          * @return
          */
@@ -1077,7 +1078,7 @@
         }
 
         /**
-         * Return whether it's enabled.
+         * Returns whether it's enabled.
          *
          * @return {@code true} if enabled. {@code false} otherwise.
          */
@@ -1305,7 +1306,7 @@
         }
 
         /**
-         * Set an intent for launching UI for this Session. This can be used as a
+         * Sets an intent for launching UI for this Session. This can be used as a
          * quick link to an ongoing media screen. The intent should be for an
          * activity that may be started using {@link Context#startActivity(Intent)}.
          *
@@ -1319,7 +1320,8 @@
         }
 
         /**
-         * Set ID of the session. If it's not set, an empty string will be used to create a session.
+         * Sets the ID of the session. If it's not set, an empty string will be used to create a
+         * session.
          * <p>
          * Use this if and only if your app supports multiple playback at the same time and also
          * wants to provide external apps to have finer controls of them.
@@ -1341,10 +1343,10 @@
         }
 
         /**
-         * Set callback for the session.
+         * Sets callback for the session.
          *
          * @param executor callback executor
-         * @param callback session callback.
+         * @param callback session callback
          * @return
          */
         @SuppressWarnings("unchecked")
@@ -1362,10 +1364,10 @@
         }
 
         /**
-         * Set extras for the session token.  If not set, {@link SessionToken#getExtras()}
+         * Sets extras for the session token.  If not set, {@link SessionToken#getExtras()}
          * will return an empty {@link Bundle}.
          *
-         * @return The Builder to allow chaining
+         * @return the Builder to allow chaining
          * @throws IllegalArgumentException if the bundle contains any non-framework Parcelable
          * objects.
          * @see SessionToken#getExtras()
@@ -1385,10 +1387,10 @@
         }
 
         /**
-         * Build {@link MediaSession}.
+         * Builds a {@link MediaSession}.
          *
          * @return a new session
-         * @throws IllegalStateException if the session with the same id is already exists for the
+         * @throws IllegalStateException if the session with the same id already exists for the
          *      package.
          */
         @NonNull abstract T build();
diff --git a/media2/session/src/main/java/androidx/media2/session/MediaSessionManager.java b/media2/session/src/main/java/androidx/media2/session/MediaSessionManager.java
index a578940..01ae8f2 100644
--- a/media2/session/src/main/java/androidx/media2/session/MediaSessionManager.java
+++ b/media2/session/src/main/java/androidx/media2/session/MediaSessionManager.java
@@ -62,7 +62,7 @@
     /**
      * Gets an instance of MediaSessionManager associated with the context.
      *
-     * @return the MediaSessionManager instance for this context.
+     * @return the MediaSessionManager instance for this context
      */
     @NonNull
     public static MediaSessionManager getInstance(@NonNull Context context) {
diff --git a/media2/session/src/main/java/androidx/media2/session/MediaSessionService.java b/media2/session/src/main/java/androidx/media2/session/MediaSessionService.java
index c8dbcb5..8fb01ce 100644
--- a/media2/session/src/main/java/androidx/media2/session/MediaSessionService.java
+++ b/media2/session/src/main/java/androidx/media2/session/MediaSessionService.java
@@ -53,16 +53,15 @@
  * &lt;/service&gt;</pre>
  * <p>
  * You may also declare <pre>android.media.browse.MediaBrowserService</pre> for compatibility with
- * {@link android.support.v4.media.MediaBrowserCompat}. This service can handle handle it
- * automatically.
+ * {@link android.support.v4.media.MediaBrowserCompat}. This service can handle it automatically.
  * <p>
  * It's recommended for an app to have a single {@link MediaSessionService} declared in the
  * manifest. Otherwise, your app might be shown twice in the list of the Auto/Wearable, or another
- * app fails to pick the right session service when it wants to start the playback this app.
+ * app fails to pick the right session service when it wants to start the playback of this app.
  * If you want to provide multiple sessions here, take a look at
  * <a href="#MultipleSessions">Supporting Multiple Sessions</a>.
  * <p>
- * Topic covered here:
+ * Topics covered here:
  * <ol>
  * <li><a href="#ServiceLifecycle">Service Lifecycle</a>
  * <li><a href="#Permissions">Permissions</a>
@@ -72,7 +71,7 @@
  * <a name="ServiceLifecycle"></a>
  * <h3>Service Lifecycle</h3>
  * <p>
- * Session service is bound service. When a {@link MediaController} is created for the
+ * Session service is a bound service. When a {@link MediaController} is created for the
  * session service, the controller binds to the session service.
  * {@link #onGetSession(ControllerInfo)} would be called inside of the {@link #onBind(Intent)}.
  * <p>
@@ -168,7 +167,7 @@
      * <p>
      * This method is always called on the main thread.
      *
-     * @param controllerInfo information of the controller which is trying to connect.
+     * @param controllerInfo information of the controller which is trying to connect
      * @return a {@link MediaSession} instance for the controller to connect to, or {@code null}
      *         to reject connection
      * @see MediaSession.Builder
@@ -221,8 +220,8 @@
      * the permission {@link android.Manifest.permission#FOREGROUND_SERVICE} in order to use
      * this API. It becomes background service after the playback is stopped.
      *
-     * @param session a session that needs notification update.
-     * @return a {@link MediaNotification}. Can be {@code null}.
+     * @param session a session that needs notification update
+     * @return a {@link MediaNotification}. Can be {@code null}
      */
     @Nullable
     public MediaNotification onUpdateNotification(@NonNull MediaSession session) {
diff --git a/media2/session/src/main/java/androidx/media2/session/RemoteSessionPlayer.java b/media2/session/src/main/java/androidx/media2/session/RemoteSessionPlayer.java
index ff2d72707..3f9c075 100644
--- a/media2/session/src/main/java/androidx/media2/session/RemoteSessionPlayer.java
+++ b/media2/session/src/main/java/androidx/media2/session/RemoteSessionPlayer.java
@@ -65,8 +65,8 @@
     public static final int VOLUME_CONTROL_ABSOLUTE = 2;
 
     /**
-     * Adjust player volume with the direction. Override this API to customize volume change in
-     * remote device
+     * Adjusts player volume with the direction. Override this API to customize volume change in
+     * remote device.
      * <p>
      * This would be ignored when volume control type is {@link #VOLUME_CONTROL_FIXED}.
      *
diff --git a/media2/session/src/main/java/androidx/media2/session/SessionCommand.java b/media2/session/src/main/java/androidx/media2/session/SessionCommand.java
index f718c36..3e18824 100644
--- a/media2/session/src/main/java/androidx/media2/session/SessionCommand.java
+++ b/media2/session/src/main/java/androidx/media2/session/SessionCommand.java
@@ -45,7 +45,7 @@
 import java.util.List;
 
 /**
- * Define a command that a {@link MediaController} can send to a {@link MediaSession}.
+ * Defines a command that a {@link MediaController} can send to a {@link MediaSession}.
  * <p>
  * If {@link #getCommandCode()} isn't {@link #COMMAND_CODE_CUSTOM}), it's predefined command.
  * If {@link #getCommandCode()} is {@link #COMMAND_CODE_CUSTOM}), it's custom command and
diff --git a/media2/session/src/main/java/androidx/media2/session/SessionCommandGroup.java b/media2/session/src/main/java/androidx/media2/session/SessionCommandGroup.java
index 6eac952..004c3aa 100644
--- a/media2/session/src/main/java/androidx/media2/session/SessionCommandGroup.java
+++ b/media2/session/src/main/java/androidx/media2/session/SessionCommandGroup.java
@@ -248,9 +248,9 @@
         }
 
         /**
-         * Builds {@link SessionCommandGroup}.
+         * Builds a {@link SessionCommandGroup}.
          *
-         * @return a new {@link SessionCommandGroup}.
+         * @return a new {@link SessionCommandGroup}
          */
         @NonNull
         public SessionCommandGroup build() {
diff --git a/media2/session/src/main/res/values-af/strings.xml b/media2/session/src/main/res/values-af/strings.xml
new file mode 100644
index 0000000..5d55fb4
--- /dev/null
+++ b/media2/session/src/main/res/values-af/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Speel tans"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Speel"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Onderbreek"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Slaan oor na vorige item"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Slaan oor na volgende item"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-am/strings.xml b/media2/session/src/main/res/values-am/strings.xml
new file mode 100644
index 0000000..d3b28b7
--- /dev/null
+++ b/media2/session/src/main/res/values-am/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"አሁን በመጫወት ላይ"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"አጫውት"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"ባለበት አቁም"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"ወደ ቀዳሚው ንጥል ዝለል"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"ወደ ቀጣዩ ንጥል ዝለል"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-ar/strings.xml b/media2/session/src/main/res/values-ar/strings.xml
new file mode 100644
index 0000000..548305a07
--- /dev/null
+++ b/media2/session/src/main/res/values-ar/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"التشغيل الآن"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"تشغيل"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"إيقاف مؤقت"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"التخطي إلى العنصر السابق"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"التخطي إلى العنصر التالي"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-as/strings.xml b/media2/session/src/main/res/values-as/strings.xml
new file mode 100644
index 0000000..eb241d0
--- /dev/null
+++ b/media2/session/src/main/res/values-as/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"এতিয়া প্লে’ হৈ আছে"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"প্লে\'"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"পজ"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"পূৰ্বৱৰ্তী বস্তুটোলৈ যাওক"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"পৰৱৰ্তী বস্তুটোলৈ যাওক"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-az/strings.xml b/media2/session/src/main/res/values-az/strings.xml
new file mode 100644
index 0000000..fc43bef
--- /dev/null
+++ b/media2/session/src/main/res/values-az/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"İndi oxudulur"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Oxudun"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pauza"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Əvvəlki elementə keçin"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Növbəti elementə keçin"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-b+sr+Latn/strings.xml b/media2/session/src/main/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..42eb6b7
--- /dev/null
+++ b/media2/session/src/main/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Trenutno svira"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Pustite"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pauzirajte"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Pređite na prethodnu stavku"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Pređite na sledeću stavku"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-be/strings.xml b/media2/session/src/main/res/values-be/strings.xml
new file mode 100644
index 0000000..976ad12
--- /dev/null
+++ b/media2/session/src/main/res/values-be/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Зараз іграе"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Прайграць"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Прыпыніць"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Перайсці да папярэдняга элемента"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Перайсці да наступнага элемента"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-bg/strings.xml b/media2/session/src/main/res/values-bg/strings.xml
new file mode 100644
index 0000000..01758d8
--- /dev/null
+++ b/media2/session/src/main/res/values-bg/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Сега слушате"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Пускане"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Поставяне на пауза"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Преминаване към предишния елемент"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Преминаване към следващия елемент"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-bn/strings.xml b/media2/session/src/main/res/values-bn/strings.xml
new file mode 100644
index 0000000..2224b12
--- /dev/null
+++ b/media2/session/src/main/res/values-bn/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"এখন চলছে"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"চালান"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"পজ করুন"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"এটিকে এড়িয়ে পূর্ববর্তী আইটেমে যান"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"এটিকে এড়িয়ে পরবর্তী আইটেমে যান"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-bs/strings.xml b/media2/session/src/main/res/values-bs/strings.xml
new file mode 100644
index 0000000..e7c46a5
--- /dev/null
+++ b/media2/session/src/main/res/values-bs/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Trenutno se reproducira"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Reproduciraj"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pauza"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Preskoči na prethodnu stavku"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Preskoči na sljedeću stavku"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-ca/strings.xml b/media2/session/src/main/res/values-ca/strings.xml
new file mode 100644
index 0000000..7ed65dc
--- /dev/null
+++ b/media2/session/src/main/res/values-ca/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"S\'està reproduint"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Reprodueix"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Posa en pausa"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Ves a l\'element anterior"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Ves a l\'element següent"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-cs/strings.xml b/media2/session/src/main/res/values-cs/strings.xml
new file mode 100644
index 0000000..637cf21
--- /dev/null
+++ b/media2/session/src/main/res/values-cs/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Přehrává se"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Přehrát"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pozastavit"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Přejít na předchozí položku"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Přejít na další položku"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-da/strings.xml b/media2/session/src/main/res/values-da/strings.xml
new file mode 100644
index 0000000..aa2b549
--- /dev/null
+++ b/media2/session/src/main/res/values-da/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Afspiller nu"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Afspil"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Sæt på pause"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Gå til forrige element"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Gå til næste element"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-de/strings.xml b/media2/session/src/main/res/values-de/strings.xml
new file mode 100644
index 0000000..a8b55ac
--- /dev/null
+++ b/media2/session/src/main/res/values-de/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Läuft gerade"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Wiedergeben"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pause"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Zum vorherigen Element springen"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Zum nächsten Element springen"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-el/strings.xml b/media2/session/src/main/res/values-el/strings.xml
new file mode 100644
index 0000000..669c0ba
--- /dev/null
+++ b/media2/session/src/main/res/values-el/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Ακούγεται τώρα"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Αναπαραγωγή"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Παύση"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Μετάβαση στο προηγούμενο στοιχείο"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Μετάβαση στο επόμενο στοιχείο"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-en-rAU/strings.xml b/media2/session/src/main/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..b026306
--- /dev/null
+++ b/media2/session/src/main/res/values-en-rAU/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Now playing"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Play"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pause"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Skip to previous item"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Skip to next item"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-en-rGB/strings.xml b/media2/session/src/main/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..b026306
--- /dev/null
+++ b/media2/session/src/main/res/values-en-rGB/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Now playing"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Play"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pause"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Skip to previous item"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Skip to next item"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-en-rIN/strings.xml b/media2/session/src/main/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..b026306
--- /dev/null
+++ b/media2/session/src/main/res/values-en-rIN/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Now playing"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Play"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pause"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Skip to previous item"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Skip to next item"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-es-rUS/strings.xml b/media2/session/src/main/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..dcdf617
--- /dev/null
+++ b/media2/session/src/main/res/values-es-rUS/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"En reproducción"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Reproducir"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pausar"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Ir al elemento anterior"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Ir al siguiente elemento"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-es/strings.xml b/media2/session/src/main/res/values-es/strings.xml
new file mode 100644
index 0000000..f9fc075
--- /dev/null
+++ b/media2/session/src/main/res/values-es/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Está sonando"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Reproducir"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pausar"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Saltar al elemento anterior"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Saltar al siguiente elemento"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-et/strings.xml b/media2/session/src/main/res/values-et/strings.xml
new file mode 100644
index 0000000..317600e
--- /dev/null
+++ b/media2/session/src/main/res/values-et/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Hetkel mängimas"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Esitamine"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Peatamine"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Eelmise üksuse juurde liikumine"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Järgmise üksuse juurde liikumine"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-eu/strings.xml b/media2/session/src/main/res/values-eu/strings.xml
new file mode 100644
index 0000000..6d5c549
--- /dev/null
+++ b/media2/session/src/main/res/values-eu/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Orain erreproduzitzen"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Erreproduzitu"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pausatu"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Saltatu aurreko elementura"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Saltatu hurrengo elementura"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-fa/strings.xml b/media2/session/src/main/res/values-fa/strings.xml
new file mode 100644
index 0000000..eab4bec
--- /dev/null
+++ b/media2/session/src/main/res/values-fa/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"درحال پخش"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"پخش"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"مکث"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"پرش به مورد قبلی"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"پرش به مورد بعدی"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-fi/strings.xml b/media2/session/src/main/res/values-fi/strings.xml
new file mode 100644
index 0000000..518d927
--- /dev/null
+++ b/media2/session/src/main/res/values-fi/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Nyt toistetaan"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Toista"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Tauko"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Siirry edelliseen"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Siirry seuraavaan"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-fr-rCA/strings.xml b/media2/session/src/main/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..dc5da69
--- /dev/null
+++ b/media2/session/src/main/res/values-fr-rCA/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"En cours de lecture"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Lire"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pause"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Accéder à l\'élément précédent"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Accéder à l\'élément suivant"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-fr/strings.xml b/media2/session/src/main/res/values-fr/strings.xml
new file mode 100644
index 0000000..33ac087
--- /dev/null
+++ b/media2/session/src/main/res/values-fr/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"En écoute"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Lecture"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pause"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Passer à l\'élément précédent"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Passer à l\'élément suivant"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-gl/strings.xml b/media2/session/src/main/res/values-gl/strings.xml
new file mode 100644
index 0000000..2ca6013
--- /dev/null
+++ b/media2/session/src/main/res/values-gl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Reproducindo"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Reproduce o contido"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pon en pausa o contido"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Omite o elemento e vai ao anterior"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Omite o elemento e vai ao seguinte"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-gu/strings.xml b/media2/session/src/main/res/values-gu/strings.xml
new file mode 100644
index 0000000..edc290c
--- /dev/null
+++ b/media2/session/src/main/res/values-gu/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"હમણાં વાગી રહ્યું છે"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"ચલાવો"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"થોભાવો"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"પહેલાંની આઇટમ પર જાઓ"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"આગલી આઇટમ પર જાઓ"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-hi/strings.xml b/media2/session/src/main/res/values-hi/strings.xml
new file mode 100644
index 0000000..4c1c301
--- /dev/null
+++ b/media2/session/src/main/res/values-hi/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"अभी चल रहा है"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"चलाएं"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"रोकें"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"पिछले आइटम पर जाएं"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"अगले आइटम पर जाएं"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-hr/strings.xml b/media2/session/src/main/res/values-hr/strings.xml
new file mode 100644
index 0000000..e8595ba
--- /dev/null
+++ b/media2/session/src/main/res/values-hr/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Upravo svira"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Pokreni"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pauza"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Preskoči na prethodnu stavku"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Preskoči na sljedeću stavku"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-hu/strings.xml b/media2/session/src/main/res/values-hu/strings.xml
new file mode 100644
index 0000000..4cf57ba
--- /dev/null
+++ b/media2/session/src/main/res/values-hu/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Most lejátszott"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Lejátszás"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Szünet"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Ugrás az előző elemre"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Ugrás a következő elemre"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-hy/strings.xml b/media2/session/src/main/res/values-hy/strings.xml
new file mode 100644
index 0000000..d25dcaf
--- /dev/null
+++ b/media2/session/src/main/res/values-hy/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Նվագարկվում է"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Նվագարկել"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Դադար"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Անցնել նախորդ տարրին"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Անցնել հաջորդ տարրին"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-in/strings.xml b/media2/session/src/main/res/values-in/strings.xml
new file mode 100644
index 0000000..4cb6e29
--- /dev/null
+++ b/media2/session/src/main/res/values-in/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Sedang diputar"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Putar"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Jeda"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Lewati ke item sebelumnya"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Lewati ke item berikutnya"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-is/strings.xml b/media2/session/src/main/res/values-is/strings.xml
new file mode 100644
index 0000000..8874eb2
--- /dev/null
+++ b/media2/session/src/main/res/values-is/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Í spilun"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Spila"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Hlé"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Fara í fyrra atriði"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Fara í næsta atriði"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-it/strings.xml b/media2/session/src/main/res/values-it/strings.xml
new file mode 100644
index 0000000..9f0dff2
--- /dev/null
+++ b/media2/session/src/main/res/values-it/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Ora in riproduzione"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Play"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pausa"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Vai all\'elemento precedente"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Vai all\'elemento successivo"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-iw/strings.xml b/media2/session/src/main/res/values-iw/strings.xml
new file mode 100644
index 0000000..111f0c46
--- /dev/null
+++ b/media2/session/src/main/res/values-iw/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"מה שומעים עכשיו?"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"הפעלה"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"השהיה"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"דילוג לפריט הקודם"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"דילוג לפריט הבא"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-ja/strings.xml b/media2/session/src/main/res/values-ja/strings.xml
new file mode 100644
index 0000000..391dba7
--- /dev/null
+++ b/media2/session/src/main/res/values-ja/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"再生中"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"再生"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"一時停止"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"前の項目にスキップ"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"次の項目にスキップ"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-ka/strings.xml b/media2/session/src/main/res/values-ka/strings.xml
new file mode 100644
index 0000000..3887d31
--- /dev/null
+++ b/media2/session/src/main/res/values-ka/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"ახლა უკრავს"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"დაკვრა"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"პაუზა"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"წინა ერთეულზე გადასვლა"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"შემდეგ ერთეულზე გადასვლა"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-kk/strings.xml b/media2/session/src/main/res/values-kk/strings.xml
new file mode 100644
index 0000000..ea00023
--- /dev/null
+++ b/media2/session/src/main/res/values-kk/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Қазір ойнап тұр"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Ойнату"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Тоқтата тұру"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Алдыңғы элементке өту"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Келесі элементке өту"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-km/strings.xml b/media2/session/src/main/res/values-km/strings.xml
new file mode 100644
index 0000000..340f7a0
--- /dev/null
+++ b/media2/session/src/main/res/values-km/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"កំពុងចាក់"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"ចាក់"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"ផ្អាក"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"រំលងទៅមេឌៀពីមុន"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"រំលងទៅមេឌៀបន្ទាប់"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-kn/strings.xml b/media2/session/src/main/res/values-kn/strings.xml
new file mode 100644
index 0000000..159529e
--- /dev/null
+++ b/media2/session/src/main/res/values-kn/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"ಪ್ಲೇ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"ಪ್ಲೇ"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"ವಿರಾಮಗೊಳಿಸಿ"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"ಹಿಂದಿನ ಐಟಂಗೆ ಸ್ಕಿಪ್‌ ಮಾಡಿ"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"ಮುಂದಿನ ಐಟಂಗೆ ಸ್ಕಿಪ್‌ ಮಾಡಿ"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-ko/strings.xml b/media2/session/src/main/res/values-ko/strings.xml
new file mode 100644
index 0000000..f3b5863
--- /dev/null
+++ b/media2/session/src/main/res/values-ko/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"지금 재생 중"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"재생"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"일시중지"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"이전 항목으로 건너뛰기"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"다음 항목으로 건너뛰기"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-ky/strings.xml b/media2/session/src/main/res/values-ky/strings.xml
new file mode 100644
index 0000000..db2b697
--- /dev/null
+++ b/media2/session/src/main/res/values-ky/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Азыр ойнотулуп жатат"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Ойнотуу"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Тындыруу"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Мурунку нерсеге өтүү"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Кийинки нерсеге өтүү"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-lo/strings.xml b/media2/session/src/main/res/values-lo/strings.xml
new file mode 100644
index 0000000..88034aca
--- /dev/null
+++ b/media2/session/src/main/res/values-lo/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"ກຳລັງຫຼິ້ນຢູ່ຕອນນີ້"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"ຫຼິ້ນ"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"ຢຸດຊົ່ວຄາວ"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"ຂ້າມໄປລາຍການກ່ອນໜ້າ"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"ຂ້າມໄປລາຍການຕໍ່ໄປ"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-lt/strings.xml b/media2/session/src/main/res/values-lt/strings.xml
new file mode 100644
index 0000000..2aca78a
--- /dev/null
+++ b/media2/session/src/main/res/values-lt/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Dabar leidžiama"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Leisti"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pristabdyti"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Pereiti prie ankstesnio elemento"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Pereiti prie kito elemento"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-lv/strings.xml b/media2/session/src/main/res/values-lv/strings.xml
new file mode 100644
index 0000000..f73844a
--- /dev/null
+++ b/media2/session/src/main/res/values-lv/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Tagad atskaņo"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Atskaņot"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pārtraukt"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Pāriet uz iepriekšējo vienumu"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Pāriet uz nākamo vienumu"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-mk/strings.xml b/media2/session/src/main/res/values-mk/strings.xml
new file mode 100644
index 0000000..3ccbd85
--- /dev/null
+++ b/media2/session/src/main/res/values-mk/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Сега се репродуцира"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Пушти"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Паузирај"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Скокни на претходната ставка"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Скокни на следната ставка"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-ml/strings.xml b/media2/session/src/main/res/values-ml/strings.xml
new file mode 100644
index 0000000..2b8afc8
--- /dev/null
+++ b/media2/session/src/main/res/values-ml/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"ഇപ്പോൾ കേൾക്കുന്നത്"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"പ്ലേ ചെയ്യുക"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"തൽക്കാലം നിർത്തുക"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"മുമ്പത്തെ ഇനത്തിലേക്ക് പോവുക"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"അടുത്ത ഇനത്തിലേക്ക് പോവുക"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-mn/strings.xml b/media2/session/src/main/res/values-mn/strings.xml
new file mode 100644
index 0000000..791d112
--- /dev/null
+++ b/media2/session/src/main/res/values-mn/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Now playing"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Тоглох"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Түр зогсоох"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Өмнөх зүйл рүү очих"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Дараагийн зүйл рүү очих"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-mr/strings.xml b/media2/session/src/main/res/values-mr/strings.xml
new file mode 100644
index 0000000..64dd982
--- /dev/null
+++ b/media2/session/src/main/res/values-mr/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"आता प्ले होत आहे"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"प्ले करा"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"थांबवा"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"मागील आयटमवर जा"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"पुढील आयटमवर जा"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-ms/strings.xml b/media2/session/src/main/res/values-ms/strings.xml
new file mode 100644
index 0000000..8424a1e
--- /dev/null
+++ b/media2/session/src/main/res/values-ms/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Sedang dimainkan"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Main"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Jeda"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Langkau ke item sebelumnya"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Langkau ke item seterusnya"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-my/strings.xml b/media2/session/src/main/res/values-my/strings.xml
new file mode 100644
index 0000000..638af4b
--- /dev/null
+++ b/media2/session/src/main/res/values-my/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"ယခု ဖွင့်နေသည်"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"ဖွင့်ရန်"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"ခေတ္တရပ်ရန်"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"ပြီးခဲ့သည့်တစ်ခုသို့ ပြန်သွားရန်"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"နောက်တစ်ခုသို့ ကျော်ရန်"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-nb/strings.xml b/media2/session/src/main/res/values-nb/strings.xml
new file mode 100644
index 0000000..b4c7c20
--- /dev/null
+++ b/media2/session/src/main/res/values-nb/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Spilles nå"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Spill av"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Sett på pause"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Gå tilbake til det forrige elementet"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Hopp over til det neste elementet"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-ne/strings.xml b/media2/session/src/main/res/values-ne/strings.xml
new file mode 100644
index 0000000..7692de4
--- /dev/null
+++ b/media2/session/src/main/res/values-ne/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"अहिले प्ले हुँदै"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"प्ले गर्नुहोस्"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"पज गर्नुहोस्"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"अघिल्लो वस्तुमा जानुहोस्"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"अर्को वस्तुमा जानुहोस्"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-nl/strings.xml b/media2/session/src/main/res/values-nl/strings.xml
new file mode 100644
index 0000000..1185920
--- /dev/null
+++ b/media2/session/src/main/res/values-nl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Wordt nu afgespeeld"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Afspelen"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pauzeren"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Overslaan en naar vorig item"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Overslaan en naar volgend item"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-or/strings.xml b/media2/session/src/main/res/values-or/strings.xml
new file mode 100644
index 0000000..f2545fb
--- /dev/null
+++ b/media2/session/src/main/res/values-or/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"ଏବେ ଚାଲୁଛି"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"ଚଲାନ୍ତୁ"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"ପଜ୍ କରନ୍ତୁ"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"ପୂର୍ବବର୍ତ୍ତୀ ଆଇଟମ୍‌କୁ ଯାଆନ୍ତୁ"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"ପରବର୍ତ୍ତୀ ଆଇଟମ୍‌କୁ ଯାଆନ୍ତୁ"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-pa/strings.xml b/media2/session/src/main/res/values-pa/strings.xml
new file mode 100644
index 0000000..551c0da
--- /dev/null
+++ b/media2/session/src/main/res/values-pa/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"ਹੁਣੇ ਚੱਲ ਰਿਹਾ ਹੈ"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"ਚਲਾਓ"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"ਰੋਕੋ"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"ਪਿਛਲੀ ਆਈਟਮ \'ਤੇ ਜਾਓ"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"ਅਗਲੀ ਆਈਟਮ \'ਤੇ ਜਾਓ"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-pl/strings.xml b/media2/session/src/main/res/values-pl/strings.xml
new file mode 100644
index 0000000..490b691
--- /dev/null
+++ b/media2/session/src/main/res/values-pl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Odtwarzam teraz"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Odtwórz"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Wstrzymaj"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Przeskocz do poprzedniego elementu"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Przeskocz do następnego elementu"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-pt-rBR/strings.xml b/media2/session/src/main/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..9b979df
--- /dev/null
+++ b/media2/session/src/main/res/values-pt-rBR/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Tocando agora"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Reproduzir"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pausar"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Voltar para o item anterior"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Pular para o próximo item"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-pt-rPT/strings.xml b/media2/session/src/main/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..413b9a6
--- /dev/null
+++ b/media2/session/src/main/res/values-pt-rPT/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"A tocar"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Reproduzir"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Colocar em pausa"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Ir para o item anterior"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Ir para o item seguinte"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-pt/strings.xml b/media2/session/src/main/res/values-pt/strings.xml
new file mode 100644
index 0000000..9b979df
--- /dev/null
+++ b/media2/session/src/main/res/values-pt/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Tocando agora"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Reproduzir"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pausar"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Voltar para o item anterior"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Pular para o próximo item"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-ro/strings.xml b/media2/session/src/main/res/values-ro/strings.xml
new file mode 100644
index 0000000..7a3ef46
--- /dev/null
+++ b/media2/session/src/main/res/values-ro/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Se redă acum"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Redați"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Întrerupeți"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Treceți la elementul anterior"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Treceți la elementul următor"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-ru/strings.xml b/media2/session/src/main/res/values-ru/strings.xml
new file mode 100644
index 0000000..8c690c6
--- /dev/null
+++ b/media2/session/src/main/res/values-ru/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Текущий трек"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Воспроизвести"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Приостановить"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Перейти к предыдущему файлу"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Перейти к следующему файлу"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-si/strings.xml b/media2/session/src/main/res/values-si/strings.xml
new file mode 100644
index 0000000..f23518b
--- /dev/null
+++ b/media2/session/src/main/res/values-si/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"දැන් වාදනය වේ"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"වාදනය"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"විරාමය"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"පෙර අයිතමය වෙත යන්න"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"ඊළඟ අයිතමය වෙත යන්න"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-sk/strings.xml b/media2/session/src/main/res/values-sk/strings.xml
new file mode 100644
index 0000000..7b3e564
--- /dev/null
+++ b/media2/session/src/main/res/values-sk/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Čo to hrá"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Prehrať"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pozastaviť"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Preskočiť na predchádzajúcu položku"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Preskočiť na ďalšiu položku"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-sl/strings.xml b/media2/session/src/main/res/values-sl/strings.xml
new file mode 100644
index 0000000..2ef6d4c
--- /dev/null
+++ b/media2/session/src/main/res/values-sl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Zdaj se predvaja"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Predvajanje"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Začasna ustavitev"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Preskok na prejšnji element"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Preskok na naslednji element"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-sq/strings.xml b/media2/session/src/main/res/values-sq/strings.xml
new file mode 100644
index 0000000..e44e01e
--- /dev/null
+++ b/media2/session/src/main/res/values-sq/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Po luhet tani"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Luaj"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pauzë"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Kapërce tek artikulli i mëparshëm"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Kapërce tek artikulli tjetër"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-sr/strings.xml b/media2/session/src/main/res/values-sr/strings.xml
new file mode 100644
index 0000000..b0e126a
--- /dev/null
+++ b/media2/session/src/main/res/values-sr/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Тренутно свира"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Пустите"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Паузирајте"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Пређите на претходну ставку"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Пређите на следећу ставку"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-sv/strings.xml b/media2/session/src/main/res/values-sv/strings.xml
new file mode 100644
index 0000000..70564e5
--- /dev/null
+++ b/media2/session/src/main/res/values-sv/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Nu spelas"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Spela upp"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pausa"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Hoppa till föregående objekt"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Hoppa till nästa objekt"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-sw/strings.xml b/media2/session/src/main/res/values-sw/strings.xml
new file mode 100644
index 0000000..640f56d
--- /dev/null
+++ b/media2/session/src/main/res/values-sw/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Kitambua ngoma"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Cheza"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Sitisha"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Rudi kwenye kipengee kilichotangulia"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Nenda kwenye kipengee kinachofuata"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-ta/strings.xml b/media2/session/src/main/res/values-ta/strings.xml
new file mode 100644
index 0000000..d7ba103
--- /dev/null
+++ b/media2/session/src/main/res/values-ta/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"பாடல் விவரம்"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"இயக்கும் பட்டன்"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"இடைநிறுத்தும் பட்டன்"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"முந்தையதற்குச் செல்லும் பட்டன்"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"அடுத்ததற்குச் செல்லும் பட்டன்"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-te/strings.xml b/media2/session/src/main/res/values-te/strings.xml
new file mode 100644
index 0000000..3d3a494
--- /dev/null
+++ b/media2/session/src/main/res/values-te/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"ప్రస్తుతం ప్లే అవుతున్నది"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"ప్లే చేస్తుంది"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"పాజ్ చేస్తుంది"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"మునుపటి అంశానికి దాటవేస్తుంది"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"తర్వాత అంశానికి దాటవేస్తుంది"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-th/strings.xml b/media2/session/src/main/res/values-th/strings.xml
new file mode 100644
index 0000000..63fd628
--- /dev/null
+++ b/media2/session/src/main/res/values-th/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"กำลังเล่น"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"เล่น"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"หยุดชั่วคราว"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"ข้ามไปยังรายการก่อนหน้า"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"ข้ามไปยังรายการถัดไป"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-tl/strings.xml b/media2/session/src/main/res/values-tl/strings.xml
new file mode 100644
index 0000000..3429364
--- /dev/null
+++ b/media2/session/src/main/res/values-tl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Nagpi-play ngayon"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"I-play"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"I-pause"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Lumaktaw sa nakaraang item"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Lumaktaw sa susunod na item"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-tr/strings.xml b/media2/session/src/main/res/values-tr/strings.xml
new file mode 100644
index 0000000..1455f06
--- /dev/null
+++ b/media2/session/src/main/res/values-tr/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Şimdi oynatılıyor"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Oynat"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Duraklat"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Önceki öğeye atla"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Sonraki öğeye atla"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-uk/strings.xml b/media2/session/src/main/res/values-uk/strings.xml
new file mode 100644
index 0000000..3df4436b
--- /dev/null
+++ b/media2/session/src/main/res/values-uk/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Зараз грає"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Play"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pause"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Перейти до попереднього кадру"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Перейти до наступного кадру"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-ur/strings.xml b/media2/session/src/main/res/values-ur/strings.xml
new file mode 100644
index 0000000..922204e
--- /dev/null
+++ b/media2/session/src/main/res/values-ur/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"اب چل رہا ہے"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"چلائیں"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"موقوف کریں"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"پچھلے آئٹم پر جائیں"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"اگلے آئٹم پر جائیں"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-uz/strings.xml b/media2/session/src/main/res/values-uz/strings.xml
new file mode 100644
index 0000000..d5f01f9
--- /dev/null
+++ b/media2/session/src/main/res/values-uz/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Ijro qilinmoqda"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Ijro"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Pauza"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Avvalgi obyektga o‘tish"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Keyingi obyektga o‘tish"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-vi/strings.xml b/media2/session/src/main/res/values-vi/strings.xml
new file mode 100644
index 0000000..3ba94cb
--- /dev/null
+++ b/media2/session/src/main/res/values-vi/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Đang phát"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Phát"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Tạm dừng"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Chuyển về mục trước đó"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Chuyển đến mục tiếp theo"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-zh-rCN/strings.xml b/media2/session/src/main/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..56a2320
--- /dev/null
+++ b/media2/session/src/main/res/values-zh-rCN/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"正在播放"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"播放"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"暂停"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"跳至上一项"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"跳至下一项"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-zh-rHK/strings.xml b/media2/session/src/main/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..15d1e9e
--- /dev/null
+++ b/media2/session/src/main/res/values-zh-rHK/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"現正播放"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"播放"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"暫停"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"跳去上一個項目"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"跳去下一個項目"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-zh-rTW/strings.xml b/media2/session/src/main/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..aa1ec5c
--- /dev/null
+++ b/media2/session/src/main/res/values-zh-rTW/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"現正播放"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"播放"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"暫停"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"跳到上一個項目"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"跳到下一個項目"</string>
+</resources>
diff --git a/media2/session/src/main/res/values-zu/strings.xml b/media2/session/src/main/res/values-zu/strings.xml
new file mode 100644
index 0000000..3179f84
--- /dev/null
+++ b/media2/session/src/main/res/values-zu/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright 2018 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="default_notification_channel_name" msgid="6743534657295236036">"Okudlala manje"</string>
+    <string name="play_button_content_description" msgid="6034272287948142298">"Dlala"</string>
+    <string name="pause_button_content_description" msgid="4221330012095125431">"Phumula"</string>
+    <string name="skip_to_previous_item_button_content_description" msgid="7233771088610629683">"Yeqela kunto yangaphambilini"</string>
+    <string name="skip_to_next_item_button_content_description" msgid="17824442457643717">"Yeqela kunto elandelayo"</string>
+</resources>
diff --git a/media2/session/version-compat-tests/current/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSession_KeyEventTest.java b/media2/session/version-compat-tests/current/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSession_KeyEventTest.java
index 9976d50..8228a4a 100644
--- a/media2/session/version-compat-tests/current/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSession_KeyEventTest.java
+++ b/media2/session/version-compat-tests/current/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSession_KeyEventTest.java
@@ -60,6 +60,10 @@
 public class MediaSession_KeyEventTest extends MediaSessionTestBase {
     private static String sExpectedControllerPackageName;
 
+    // Intentionally member variable to prevent GC while playback is running.
+    // Should be only used on the sHandler.
+    private MediaPlayer mMediaPlayer;
+
     private AudioManager mAudioManager;
     private MediaSession mSession;
     private MockPlayer mPlayer;
@@ -90,35 +94,50 @@
                 .setSessionCallback(sHandlerExecutor, mSessionCallback)
                 .build();
 
-        // Make this test to get priority for handling media key event
-        // SDK < 26: Playback state should become *playing*
-        mPlayer.notifyPlayerStateChanged(SessionPlayer.PLAYER_STATE_PLAYING);
-
-        // SDK >= 26: Play a media item in the same process of the session.
-        // Target raw resource should be short enough to finish within the time limit of @SmallTest.
-        final CountDownLatch latch = new CountDownLatch(1);
-        sHandler.postAndSync(new Runnable() {
-            @Override
-            public void run() {
-                // Pick the shortest media.
-                final MediaPlayer player = MediaPlayer.create(mContext, R.raw.camera_click);
-                player.setOnCompletionListener(new OnCompletionListener() {
-                    @Override
-                    public void onCompletion(MediaPlayer mp) {
-                        latch.countDown();
-                        player.release();
-                    }
-                });
-                player.start();
-            }
-        });
-        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        // Make this test to get priority for handling media key event.
+        // Here's the requirement for an app to receive media key events via MediaSession.
+        // SDK < 26: Playback state should become *playing* for receiving key events.
+        // SDK >= 26: Play a media item in the same process of the session for receiving key
+        //            events.
+        if (Build.VERSION.SDK_INT < 26) {
+            mPlayer.notifyPlayerStateChanged(SessionPlayer.PLAYER_STATE_PLAYING);
+        } else {
+            final CountDownLatch latch = new CountDownLatch(1);
+            sHandler.postAndSync(new Runnable() {
+                @Override
+                public void run() {
+                    // Pick the shortest media to finish within the TIMEOUT_MS.
+                    mMediaPlayer = MediaPlayer.create(mContext, R.raw.camera_click);
+                    mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
+                        @Override
+                        public void onCompletion(MediaPlayer mp) {
+                            if (mMediaPlayer != null) {
+                                mMediaPlayer.release();
+                                mMediaPlayer = null;
+                                latch.countDown();
+                            }
+                        }
+                    });
+                    mMediaPlayer.start();
+                }
+            });
+            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        }
     }
 
     @After
     @Override
     public void cleanUp() throws Exception {
         super.cleanUp();
+        sHandler.postAndSync(new Runnable() {
+            @Override
+            public void run() {
+                if (mMediaPlayer != null) {
+                    mMediaPlayer.release();
+                    mMediaPlayer = null;
+                }
+            }
+        });
         mSession.close();
     }
 
diff --git a/media2/session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSession_KeyEventTest.java b/media2/session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSession_KeyEventTest.java
index b605f9b..bef96da 100644
--- a/media2/session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSession_KeyEventTest.java
+++ b/media2/session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSession_KeyEventTest.java
@@ -59,6 +59,10 @@
 public class MediaSession_KeyEventTest extends MediaSessionTestBase {
     private static String sExpectedControllerPackageName;
 
+    // Intentionally member variable to prevent GC while playback is running.
+    // Should be only used on the sHandler.
+    private MediaPlayer mMediaPlayer;
+
     private AudioManager mAudioManager;
     private MediaSession mSession;
     private MockPlayer mPlayer;
@@ -93,31 +97,50 @@
         // SDK < 26: Playback state should become *playing*
         mPlayer.notifyPlayerStateChanged(SessionPlayer.PLAYER_STATE_PLAYING);
 
-        // SDK >= 26: Play a media item in the same process of the session.
-        // Target raw resource should be short enough to finish within the time limit of @SmallTest.
-        final CountDownLatch latch = new CountDownLatch(1);
-        sHandler.postAndSync(new Runnable() {
-            @Override
-            public void run() {
-                // Pick the shortest media.
-                final MediaPlayer player = MediaPlayer.create(mContext, R.raw.camera_click);
-                player.setOnCompletionListener(new OnCompletionListener() {
-                    @Override
-                    public void onCompletion(MediaPlayer mp) {
-                        latch.countDown();
-                        player.release();
-                    }
-                });
-                player.start();
-            }
-        });
-        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        // Make this test to get priority for handling media key event.
+        // Here's the requirement for an app to receive media key events via MediaSession.
+        // SDK < 26: Playback state should become *playing* for receiving key events.
+        // SDK >= 26: Play a media item in the same process of the session for receiving key
+        //            events.
+        if (Build.VERSION.SDK_INT < 26) {
+            mPlayer.notifyPlayerStateChanged(SessionPlayer.PLAYER_STATE_PLAYING);
+        } else {
+            final CountDownLatch latch = new CountDownLatch(1);
+            sHandler.postAndSync(new Runnable() {
+                @Override
+                public void run() {
+                    // Pick the shortest media to finish within the TIMEOUT_MS.
+                    mMediaPlayer = MediaPlayer.create(mContext, R.raw.camera_click);
+                    mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
+                        @Override
+                        public void onCompletion(MediaPlayer mp) {
+                            if (mMediaPlayer != null) {
+                                mMediaPlayer.release();
+                                mMediaPlayer = null;
+                                latch.countDown();
+                            }
+                        }
+                    });
+                    mMediaPlayer.start();
+                }
+            });
+            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        }
     }
 
     @After
     @Override
     public void cleanUp() throws Exception {
         super.cleanUp();
+        sHandler.postAndSync(new Runnable() {
+            @Override
+            public void run() {
+                if (mMediaPlayer != null) {
+                    mMediaPlayer.release();
+                    mMediaPlayer = null;
+                }
+            }
+        });
         mSession.close();
     }
 
diff --git a/media2/session/version-compat-tests/runtest.sh b/media2/session/version-compat-tests/runtest.sh
index e0d7b53..1fc908b 100755
--- a/media2/session/version-compat-tests/runtest.sh
+++ b/media2/session/version-compat-tests/runtest.sh
@@ -56,11 +56,11 @@
   ./gradlew $SERVICE_MODULE_NAME:assembleDebugAndroidTest || { echo "Build failed. Aborting."; exit 1; }
 
   echo "Installing the test apks"
-  adb $DEVICE_SERIAL install -r "../../out/dist/apks/$CLIENT_MODULE_NAME.apk" || { echo "Apk installation failed. Aborting."; exit 1; }
-  adb $DEVICE_SERIAL install -r "../../out/dist/apks/$SERVICE_MODULE_NAME.apk" || { echo "Apk installation failed. Aborting."; exit 1; }
+  $ADB $DEVICE_SERIAL install -r "../../out/dist/apks/$CLIENT_MODULE_NAME.apk" || { echo "Apk installation failed. Aborting."; exit 1; }
+  $ADB $DEVICE_SERIAL install -r "../../out/dist/apks/$SERVICE_MODULE_NAME.apk" || { echo "Apk installation failed. Aborting."; exit 1; }
 
   echo "Running the tests"
-  local test_command="adb $DEVICE_SERIAL shell am instrument -w -e debug false -e client_version $CLIENT_VERSION -e service_version $SERVICE_VERSION"
+  local test_command="$ADB $DEVICE_SERIAL shell am instrument -w -e debug false -e client_version $CLIENT_VERSION -e service_version $SERVICE_VERSION"
   local client_test_runner="androidx.media2.test.client.test/androidx.test.runner.AndroidJUnitRunner"
   local service_test_runner="androidx.media2.test.service.test/androidx.test.runner.AndroidJUnitRunner"
 
@@ -88,6 +88,18 @@
   exit 1;
 fi
 
+if [ "`uname`" == "Darwin" ]; then
+  PLATFORM="darwin"
+else
+  PLATFORM="linux"
+fi
+ADB="../../prebuilts/fullsdk-$PLATFORM/platform-tools/adb"
+if [ ! -f "$ADB" ]; then
+  echo "adb not found at $ADB, finding adb in \$PATH..." 1>&2
+  command -v adb > /dev/null 2>&1 || { echo "adb not found in \$PATH" 1>&2; exit 1; }
+  ADB="adb"
+fi
+
 case ${1} in
   1|2|3|4)
     VERSION_COMBINATION=${1}
diff --git a/media2/widget/api/1.0.0-rc02.txt b/media2/widget/api/1.0.0-rc02.txt
new file mode 100644
index 0000000..b614f1a
--- /dev/null
+++ b/media2/widget/api/1.0.0-rc02.txt
@@ -0,0 +1,38 @@
+// Signature format: 3.0
+package androidx.media2.widget {
+
+  public class MediaControlView extends android.view.ViewGroup {
+    ctor public MediaControlView(android.content.Context);
+    ctor public MediaControlView(android.content.Context, android.util.AttributeSet?);
+    ctor public MediaControlView(android.content.Context, android.util.AttributeSet?, int);
+    method public void requestPlayButtonFocus();
+    method public void setMediaController(androidx.media2.session.MediaController);
+    method public void setOnFullScreenListener(androidx.media2.widget.MediaControlView.OnFullScreenListener?);
+    method public void setPlayer(androidx.media2.common.SessionPlayer);
+  }
+
+  public static interface MediaControlView.OnFullScreenListener {
+    method public void onFullScreen(android.view.View, boolean);
+  }
+
+  public class VideoView extends android.view.ViewGroup {
+    ctor public VideoView(android.content.Context);
+    ctor public VideoView(android.content.Context, android.util.AttributeSet?);
+    ctor public VideoView(android.content.Context, android.util.AttributeSet?, int);
+    method public androidx.media2.widget.MediaControlView? getMediaControlView();
+    method public int getViewType();
+    method public void setMediaControlView(androidx.media2.widget.MediaControlView, long);
+    method public void setMediaController(androidx.media2.session.MediaController);
+    method public void setOnViewTypeChangedListener(androidx.media2.widget.VideoView.OnViewTypeChangedListener?);
+    method public void setPlayer(androidx.media2.common.SessionPlayer);
+    method public void setViewType(int);
+    field public static final int VIEW_TYPE_SURFACEVIEW = 0; // 0x0
+    field public static final int VIEW_TYPE_TEXTUREVIEW = 1; // 0x1
+  }
+
+  public static interface VideoView.OnViewTypeChangedListener {
+    method public void onViewTypeChanged(android.view.View, int);
+  }
+
+}
+
diff --git a/media2/widget/api/api_lint.ignore b/media2/widget/api/api_lint.ignore
new file mode 100644
index 0000000..3b205f2
--- /dev/null
+++ b/media2/widget/api/api_lint.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+MissingNullability: androidx.media2.widget.MediaControlView#getAccessibilityClassName():
+    Missing nullability on method `getAccessibilityClassName` return
+MissingNullability: androidx.media2.widget.MediaControlView#onTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onTouchEvent`
+MissingNullability: androidx.media2.widget.MediaControlView#onTrackballEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onTrackballEvent`
+MissingNullability: androidx.media2.widget.VideoView#getAccessibilityClassName():
+    Missing nullability on method `getAccessibilityClassName` return
diff --git a/media2/widget/api/res-1.0.0-rc02.txt b/media2/widget/api/res-1.0.0-rc02.txt
new file mode 100644
index 0000000..9015818
--- /dev/null
+++ b/media2/widget/api/res-1.0.0-rc02.txt
@@ -0,0 +1,2 @@
+attr enableControlView
+attr viewType
diff --git a/media2/widget/api/restricted_1.0.0-rc02.txt b/media2/widget/api/restricted_1.0.0-rc02.txt
new file mode 100644
index 0000000..b614f1a
--- /dev/null
+++ b/media2/widget/api/restricted_1.0.0-rc02.txt
@@ -0,0 +1,38 @@
+// Signature format: 3.0
+package androidx.media2.widget {
+
+  public class MediaControlView extends android.view.ViewGroup {
+    ctor public MediaControlView(android.content.Context);
+    ctor public MediaControlView(android.content.Context, android.util.AttributeSet?);
+    ctor public MediaControlView(android.content.Context, android.util.AttributeSet?, int);
+    method public void requestPlayButtonFocus();
+    method public void setMediaController(androidx.media2.session.MediaController);
+    method public void setOnFullScreenListener(androidx.media2.widget.MediaControlView.OnFullScreenListener?);
+    method public void setPlayer(androidx.media2.common.SessionPlayer);
+  }
+
+  public static interface MediaControlView.OnFullScreenListener {
+    method public void onFullScreen(android.view.View, boolean);
+  }
+
+  public class VideoView extends android.view.ViewGroup {
+    ctor public VideoView(android.content.Context);
+    ctor public VideoView(android.content.Context, android.util.AttributeSet?);
+    ctor public VideoView(android.content.Context, android.util.AttributeSet?, int);
+    method public androidx.media2.widget.MediaControlView? getMediaControlView();
+    method public int getViewType();
+    method public void setMediaControlView(androidx.media2.widget.MediaControlView, long);
+    method public void setMediaController(androidx.media2.session.MediaController);
+    method public void setOnViewTypeChangedListener(androidx.media2.widget.VideoView.OnViewTypeChangedListener?);
+    method public void setPlayer(androidx.media2.common.SessionPlayer);
+    method public void setViewType(int);
+    field public static final int VIEW_TYPE_SURFACEVIEW = 0; // 0x0
+    field public static final int VIEW_TYPE_TEXTUREVIEW = 1; // 0x1
+  }
+
+  public static interface VideoView.OnViewTypeChangedListener {
+    method public void onViewTypeChanged(android.view.View, int);
+  }
+
+}
+
diff --git a/media2/widget/build.gradle b/media2/widget/build.gradle
index 19cc8f8..45725fc 100644
--- a/media2/widget/build.gradle
+++ b/media2/widget/build.gradle
@@ -29,7 +29,7 @@
     api("androidx.media2:media2-session:1.0.0-rc01")
     implementation("androidx.appcompat:appcompat:1.0.2")
     implementation("androidx.palette:palette:1.0.0")
-    implementation("androidx.concurrent:concurrent-futures:1.0.0-beta01")
+    implementation("androidx.concurrent:concurrent-futures:1.0.0-rc01")
 
     androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
     androidTestImplementation(ANDROIDX_TEST_CORE)
diff --git a/media2/widget/src/androidTest/java/androidx/media2/widget/VideoView_WithPlayerTest.java b/media2/widget/src/androidTest/java/androidx/media2/widget/VideoView_WithPlayerTest.java
index 688d67b..ad262a1 100644
--- a/media2/widget/src/androidTest/java/androidx/media2/widget/VideoView_WithPlayerTest.java
+++ b/media2/widget/src/androidTest/java/androidx/media2/widget/VideoView_WithPlayerTest.java
@@ -328,6 +328,9 @@
             // TODO: This if-block for API 28 should be removed. (b/137321781)
             return;
         }
+        if (Build.DEVICE.equals("fugu") && Build.VERSION.SDK_INT == 24) {
+            return;
+        }
         if (Build.VERSION.SDK_INT >= 24) {
             final int bufferQueueToleranceMs = 200;
             final int elapsedTimeForSecondScreenshotMs = 400;
diff --git a/mediarouter/api/api_lint.ignore b/mediarouter/api/api_lint.ignore
index 1090c0a..fea6a3c 100644
--- a/mediarouter/api/api_lint.ignore
+++ b/mediarouter/api/api_lint.ignore
@@ -61,6 +61,538 @@
     Method can be invoked as a "in" operator from Kotlin: `contains` (this is usually desirable; just make sure it makes sense for this type of object)
 
 
+MissingNullability: androidx.mediarouter.app.MediaRouteActionProvider#MediaRouteActionProvider(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `MediaRouteActionProvider`
+MissingNullability: androidx.mediarouter.app.MediaRouteActionProvider#onCreateActionView():
+    Missing nullability on method `onCreateActionView` return
+MissingNullability: androidx.mediarouter.app.MediaRouteActionProvider#onCreateMediaRouteButton():
+    Missing nullability on method `onCreateMediaRouteButton` return
+MissingNullability: androidx.mediarouter.app.MediaRouteButton#MediaRouteButton(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `MediaRouteButton`
+MissingNullability: androidx.mediarouter.app.MediaRouteButton#MediaRouteButton(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `MediaRouteButton`
+MissingNullability: androidx.mediarouter.app.MediaRouteButton#MediaRouteButton(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `MediaRouteButton`
+MissingNullability: androidx.mediarouter.app.MediaRouteButton#MediaRouteButton(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `MediaRouteButton`
+MissingNullability: androidx.mediarouter.app.MediaRouteButton#MediaRouteButton(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `MediaRouteButton`
+MissingNullability: androidx.mediarouter.app.MediaRouteButton#onCreateDrawableState(int):
+    Missing nullability on method `onCreateDrawableState` return
+MissingNullability: androidx.mediarouter.app.MediaRouteButton#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `onDraw`
+MissingNullability: androidx.mediarouter.app.MediaRouteButton#setRemoteIndicatorDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `d` in method `setRemoteIndicatorDrawable`
+MissingNullability: androidx.mediarouter.app.MediaRouteButton#setRouteSelector(androidx.mediarouter.media.MediaRouteSelector) parameter #0:
+    Missing nullability on parameter `selector` in method `setRouteSelector`
+MissingNullability: androidx.mediarouter.app.MediaRouteButton#verifyDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `who` in method `verifyDrawable`
+MissingNullability: androidx.mediarouter.app.MediaRouteChooserDialog#MediaRouteChooserDialog(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `MediaRouteChooserDialog`
+MissingNullability: androidx.mediarouter.app.MediaRouteChooserDialog#MediaRouteChooserDialog(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `MediaRouteChooserDialog`
+MissingNullability: androidx.mediarouter.app.MediaRouteChooserDialog#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.mediarouter.app.MediaRouteChooserDialog#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.mediarouter.app.MediaRouteChooserDialogFragment#getRouteSelector():
+    Missing nullability on method `getRouteSelector` return
+MissingNullability: androidx.mediarouter.app.MediaRouteChooserDialogFragment#onConfigurationChanged(android.content.res.Configuration) parameter #0:
+    Missing nullability on parameter `newConfig` in method `onConfigurationChanged`
+MissingNullability: androidx.mediarouter.app.MediaRouteChooserDialogFragment#onCreateChooserDialog(android.content.Context, android.os.Bundle):
+    Missing nullability on method `onCreateChooserDialog` return
+MissingNullability: androidx.mediarouter.app.MediaRouteChooserDialogFragment#onCreateChooserDialog(android.content.Context, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `context` in method `onCreateChooserDialog`
+MissingNullability: androidx.mediarouter.app.MediaRouteChooserDialogFragment#onCreateChooserDialog(android.content.Context, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateChooserDialog`
+MissingNullability: androidx.mediarouter.app.MediaRouteChooserDialogFragment#onCreateDialog(android.os.Bundle):
+    Missing nullability on method `onCreateDialog` return
+MissingNullability: androidx.mediarouter.app.MediaRouteChooserDialogFragment#onCreateDialog(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateDialog`
+MissingNullability: androidx.mediarouter.app.MediaRouteChooserDialogFragment#setRouteSelector(androidx.mediarouter.media.MediaRouteSelector) parameter #0:
+    Missing nullability on parameter `selector` in method `setRouteSelector`
+MissingNullability: androidx.mediarouter.app.MediaRouteControllerDialog#MediaRouteControllerDialog(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `MediaRouteControllerDialog`
+MissingNullability: androidx.mediarouter.app.MediaRouteControllerDialog#MediaRouteControllerDialog(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `MediaRouteControllerDialog`
+MissingNullability: androidx.mediarouter.app.MediaRouteControllerDialog#getMediaControlView():
+    Missing nullability on method `getMediaControlView` return
+MissingNullability: androidx.mediarouter.app.MediaRouteControllerDialog#getMediaSession():
+    Missing nullability on method `getMediaSession` return
+MissingNullability: androidx.mediarouter.app.MediaRouteControllerDialog#getRoute():
+    Missing nullability on method `getRoute` return
+MissingNullability: androidx.mediarouter.app.MediaRouteControllerDialog#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.mediarouter.app.MediaRouteControllerDialog#onCreateMediaControlView(android.os.Bundle):
+    Missing nullability on method `onCreateMediaControlView` return
+MissingNullability: androidx.mediarouter.app.MediaRouteControllerDialog#onCreateMediaControlView(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateMediaControlView`
+MissingNullability: androidx.mediarouter.app.MediaRouteControllerDialog#onKeyDown(int, android.view.KeyEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onKeyDown`
+MissingNullability: androidx.mediarouter.app.MediaRouteControllerDialog#onKeyUp(int, android.view.KeyEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onKeyUp`
+MissingNullability: androidx.mediarouter.app.MediaRouteControllerDialogFragment#onConfigurationChanged(android.content.res.Configuration) parameter #0:
+    Missing nullability on parameter `newConfig` in method `onConfigurationChanged`
+MissingNullability: androidx.mediarouter.app.MediaRouteControllerDialogFragment#onCreateControllerDialog(android.content.Context, android.os.Bundle):
+    Missing nullability on method `onCreateControllerDialog` return
+MissingNullability: androidx.mediarouter.app.MediaRouteControllerDialogFragment#onCreateControllerDialog(android.content.Context, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `context` in method `onCreateControllerDialog`
+MissingNullability: androidx.mediarouter.app.MediaRouteControllerDialogFragment#onCreateControllerDialog(android.content.Context, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateControllerDialog`
+MissingNullability: androidx.mediarouter.app.MediaRouteControllerDialogFragment#onCreateDialog(android.os.Bundle):
+    Missing nullability on method `onCreateDialog` return
+MissingNullability: androidx.mediarouter.app.MediaRouteControllerDialogFragment#onCreateDialog(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateDialog`
+MissingNullability: androidx.mediarouter.app.MediaRouteDiscoveryFragment#getMediaRouter():
+    Missing nullability on method `getMediaRouter` return
+MissingNullability: androidx.mediarouter.app.MediaRouteDiscoveryFragment#getRouteSelector():
+    Missing nullability on method `getRouteSelector` return
+MissingNullability: androidx.mediarouter.app.MediaRouteDiscoveryFragment#onCreateCallback():
+    Missing nullability on method `onCreateCallback` return
+MissingNullability: androidx.mediarouter.app.MediaRouteDiscoveryFragment#setRouteSelector(androidx.mediarouter.media.MediaRouteSelector) parameter #0:
+    Missing nullability on parameter `selector` in method `setRouteSelector`
+MissingNullability: androidx.mediarouter.media.MediaItemStatus#asBundle():
+    Missing nullability on method `asBundle` return
+MissingNullability: androidx.mediarouter.media.MediaItemStatus#fromBundle(android.os.Bundle):
+    Missing nullability on method `fromBundle` return
+MissingNullability: androidx.mediarouter.media.MediaItemStatus#fromBundle(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `bundle` in method `fromBundle`
+MissingNullability: androidx.mediarouter.media.MediaItemStatus#getExtras():
+    Missing nullability on method `getExtras` return
+MissingNullability: androidx.mediarouter.media.MediaItemStatus#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.mediarouter.media.MediaItemStatus.Builder#Builder(androidx.mediarouter.media.MediaItemStatus) parameter #0:
+    Missing nullability on parameter `status` in method `Builder`
+MissingNullability: androidx.mediarouter.media.MediaItemStatus.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.mediarouter.media.MediaItemStatus.Builder#setContentDuration(long):
+    Missing nullability on method `setContentDuration` return
+MissingNullability: androidx.mediarouter.media.MediaItemStatus.Builder#setContentPosition(long):
+    Missing nullability on method `setContentPosition` return
+MissingNullability: androidx.mediarouter.media.MediaItemStatus.Builder#setExtras(android.os.Bundle):
+    Missing nullability on method `setExtras` return
+MissingNullability: androidx.mediarouter.media.MediaItemStatus.Builder#setExtras(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `extras` in method `setExtras`
+MissingNullability: androidx.mediarouter.media.MediaItemStatus.Builder#setPlaybackState(int):
+    Missing nullability on method `setPlaybackState` return
+MissingNullability: androidx.mediarouter.media.MediaItemStatus.Builder#setTimestamp(long):
+    Missing nullability on method `setTimestamp` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor#asBundle():
+    Missing nullability on method `asBundle` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor#fromBundle(android.os.Bundle):
+    Missing nullability on method `fromBundle` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor#fromBundle(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `bundle` in method `fromBundle`
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor#getControlFilters():
+    Missing nullability on method `getControlFilters` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor#getDescription():
+    Missing nullability on method `getDescription` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor#getExtras():
+    Missing nullability on method `getExtras` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor#getIconUri():
+    Missing nullability on method `getIconUri` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor#getId():
+    Missing nullability on method `getId` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor#getName():
+    Missing nullability on method `getName` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor#getSettingsActivity():
+    Missing nullability on method `getSettingsActivity` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#Builder(String, String) parameter #0:
+    Missing nullability on parameter `id` in method `Builder`
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#Builder(String, String) parameter #1:
+    Missing nullability on parameter `name` in method `Builder`
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#Builder(androidx.mediarouter.media.MediaRouteDescriptor) parameter #0:
+    Missing nullability on parameter `descriptor` in method `Builder`
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#addControlFilter(android.content.IntentFilter):
+    Missing nullability on method `addControlFilter` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#addControlFilter(android.content.IntentFilter) parameter #0:
+    Missing nullability on parameter `filter` in method `addControlFilter`
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#addControlFilters(java.util.Collection<android.content.IntentFilter>):
+    Missing nullability on method `addControlFilters` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#addControlFilters(java.util.Collection<android.content.IntentFilter>) parameter #0:
+    Missing nullability on parameter `filters` in method `addControlFilters`
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setCanDisconnect(boolean):
+    Missing nullability on method `setCanDisconnect` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setConnectionState(int):
+    Missing nullability on method `setConnectionState` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setDescription(String):
+    Missing nullability on method `setDescription` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setDescription(String) parameter #0:
+    Missing nullability on parameter `description` in method `setDescription`
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setDeviceType(int):
+    Missing nullability on method `setDeviceType` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setEnabled(boolean):
+    Missing nullability on method `setEnabled` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setExtras(android.os.Bundle):
+    Missing nullability on method `setExtras` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setExtras(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `extras` in method `setExtras`
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setIconUri(android.net.Uri):
+    Missing nullability on method `setIconUri` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setIconUri(android.net.Uri) parameter #0:
+    Missing nullability on parameter `iconUri` in method `setIconUri`
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setId(String):
+    Missing nullability on method `setId` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setId(String) parameter #0:
+    Missing nullability on parameter `id` in method `setId`
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setIsDynamicGroupRoute(boolean):
+    Missing nullability on method `setIsDynamicGroupRoute` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setName(String):
+    Missing nullability on method `setName` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setName(String) parameter #0:
+    Missing nullability on parameter `name` in method `setName`
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setPlaybackStream(int):
+    Missing nullability on method `setPlaybackStream` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setPlaybackType(int):
+    Missing nullability on method `setPlaybackType` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setPresentationDisplayId(int):
+    Missing nullability on method `setPresentationDisplayId` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setSettingsActivity(android.content.IntentSender):
+    Missing nullability on method `setSettingsActivity` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setSettingsActivity(android.content.IntentSender) parameter #0:
+    Missing nullability on parameter `is` in method `setSettingsActivity`
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setVolume(int):
+    Missing nullability on method `setVolume` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setVolumeHandling(int):
+    Missing nullability on method `setVolumeHandling` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDescriptor.Builder#setVolumeMax(int):
+    Missing nullability on method `setVolumeMax` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDiscoveryRequest#MediaRouteDiscoveryRequest(androidx.mediarouter.media.MediaRouteSelector, boolean) parameter #0:
+    Missing nullability on parameter `selector` in method `MediaRouteDiscoveryRequest`
+MissingNullability: androidx.mediarouter.media.MediaRouteDiscoveryRequest#asBundle():
+    Missing nullability on method `asBundle` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDiscoveryRequest#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.mediarouter.media.MediaRouteDiscoveryRequest#fromBundle(android.os.Bundle):
+    Missing nullability on method `fromBundle` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDiscoveryRequest#fromBundle(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `bundle` in method `fromBundle`
+MissingNullability: androidx.mediarouter.media.MediaRouteDiscoveryRequest#getSelector():
+    Missing nullability on method `getSelector` return
+MissingNullability: androidx.mediarouter.media.MediaRouteDiscoveryRequest#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider#getContext():
+    Missing nullability on method `getContext` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider#getHandler():
+    Missing nullability on method `getHandler` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider#getMetadata():
+    Missing nullability on method `getMetadata` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider#setDiscoveryRequest(androidx.mediarouter.media.MediaRouteDiscoveryRequest) parameter #0:
+    Missing nullability on parameter `request` in method `setDiscoveryRequest`
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController#notifyDynamicRoutesChanged(java.util.Collection<androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor>) parameter #0:
+    Missing nullability on parameter `routes` in method `notifyDynamicRoutesChanged`
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController#onRemoveMemberRoute(String) parameter #0:
+    Missing nullability on parameter `routeId` in method `onRemoveMemberRoute`
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder#Builder(androidx.mediarouter.media.MediaRouteDescriptor) parameter #0:
+    Missing nullability on parameter `descriptor` in method `Builder`
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder#Builder(androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor) parameter #0:
+    Missing nullability on parameter `dynamicRouteDescriptor` in method `Builder`
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder#setIsGroupable(boolean):
+    Missing nullability on method `setIsGroupable` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder#setIsTransferable(boolean):
+    Missing nullability on method `setIsTransferable` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder#setIsUnselectable(boolean):
+    Missing nullability on method `setIsUnselectable` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder#setSelectionState(int):
+    Missing nullability on method `setSelectionState` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider.ProviderMetadata#getComponentName():
+    Missing nullability on method `getComponentName` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider.ProviderMetadata#getPackageName():
+    Missing nullability on method `getPackageName` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider.ProviderMetadata#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProvider.RouteController#onControlRequest(android.content.Intent, androidx.mediarouter.media.MediaRouter.ControlRequestCallback) parameter #0:
+    Missing nullability on parameter `intent` in method `onControlRequest`
+MissingNullability: androidx.mediarouter.media.MediaRouteProviderDescriptor#asBundle():
+    Missing nullability on method `asBundle` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProviderDescriptor#fromBundle(android.os.Bundle):
+    Missing nullability on method `fromBundle` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProviderDescriptor#fromBundle(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `bundle` in method `fromBundle`
+MissingNullability: androidx.mediarouter.media.MediaRouteProviderDescriptor#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProviderDescriptor.Builder#Builder(androidx.mediarouter.media.MediaRouteProviderDescriptor) parameter #0:
+    Missing nullability on parameter `descriptor` in method `Builder`
+MissingNullability: androidx.mediarouter.media.MediaRouteProviderDescriptor.Builder#addRoute(androidx.mediarouter.media.MediaRouteDescriptor):
+    Missing nullability on method `addRoute` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProviderDescriptor.Builder#addRoute(androidx.mediarouter.media.MediaRouteDescriptor) parameter #0:
+    Missing nullability on parameter `route` in method `addRoute`
+MissingNullability: androidx.mediarouter.media.MediaRouteProviderDescriptor.Builder#addRoutes(java.util.Collection<androidx.mediarouter.media.MediaRouteDescriptor>):
+    Missing nullability on method `addRoutes` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProviderDescriptor.Builder#addRoutes(java.util.Collection<androidx.mediarouter.media.MediaRouteDescriptor>) parameter #0:
+    Missing nullability on parameter `routes` in method `addRoutes`
+MissingNullability: androidx.mediarouter.media.MediaRouteProviderDescriptor.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProviderDescriptor.Builder#setSupportsDynamicGroupRoute(boolean):
+    Missing nullability on method `setSupportsDynamicGroupRoute` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProviderService#getMediaRouteProvider():
+    Missing nullability on method `getMediaRouteProvider` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProviderService#onBind(android.content.Intent):
+    Missing nullability on method `onBind` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProviderService#onBind(android.content.Intent) parameter #0:
+    Missing nullability on parameter `intent` in method `onBind`
+MissingNullability: androidx.mediarouter.media.MediaRouteProviderService#onCreateMediaRouteProvider():
+    Missing nullability on method `onCreateMediaRouteProvider` return
+MissingNullability: androidx.mediarouter.media.MediaRouteProviderService#onUnbind(android.content.Intent) parameter #0:
+    Missing nullability on parameter `intent` in method `onUnbind`
+MissingNullability: androidx.mediarouter.media.MediaRouteSelector#EMPTY:
+    Missing nullability on field `EMPTY` in class `class androidx.mediarouter.media.MediaRouteSelector`
+MissingNullability: androidx.mediarouter.media.MediaRouteSelector#asBundle():
+    Missing nullability on method `asBundle` return
+MissingNullability: androidx.mediarouter.media.MediaRouteSelector#contains(androidx.mediarouter.media.MediaRouteSelector) parameter #0:
+    Missing nullability on parameter `selector` in method `contains`
+MissingNullability: androidx.mediarouter.media.MediaRouteSelector#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.mediarouter.media.MediaRouteSelector#fromBundle(android.os.Bundle):
+    Missing nullability on method `fromBundle` return
+MissingNullability: androidx.mediarouter.media.MediaRouteSelector#getControlCategories():
+    Missing nullability on method `getControlCategories` return
+MissingNullability: androidx.mediarouter.media.MediaRouteSelector#hasControlCategory(String) parameter #0:
+    Missing nullability on parameter `category` in method `hasControlCategory`
+MissingNullability: androidx.mediarouter.media.MediaRouteSelector#matchesControlFilters(java.util.List<android.content.IntentFilter>) parameter #0:
+    Missing nullability on parameter `filters` in method `matchesControlFilters`
+MissingNullability: androidx.mediarouter.media.MediaRouteSelector#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.mediarouter.media.MediaRouter#addCallback(androidx.mediarouter.media.MediaRouteSelector, androidx.mediarouter.media.MediaRouter.Callback) parameter #0:
+    Missing nullability on parameter `selector` in method `addCallback`
+MissingNullability: androidx.mediarouter.media.MediaRouter#addCallback(androidx.mediarouter.media.MediaRouteSelector, androidx.mediarouter.media.MediaRouter.Callback) parameter #1:
+    Missing nullability on parameter `callback` in method `addCallback`
+MissingNullability: androidx.mediarouter.media.MediaRouter#getBluetoothRoute():
+    Missing nullability on method `getBluetoothRoute` return
+MissingNullability: androidx.mediarouter.media.MediaRouter#getInstance(android.content.Context):
+    Missing nullability on method `getInstance` return
+MissingNullability: androidx.mediarouter.media.MediaRouter#getMediaSessionToken():
+    Missing nullability on method `getMediaSessionToken` return
+MissingNullability: androidx.mediarouter.media.MediaRouter#getProviders():
+    Missing nullability on method `getProviders` return
+MissingNullability: androidx.mediarouter.media.MediaRouter#getRoutes():
+    Missing nullability on method `getRoutes` return
+MissingNullability: androidx.mediarouter.media.MediaRouter#setMediaSession(Object) parameter #0:
+    Missing nullability on parameter `mediaSession` in method `setMediaSession`
+MissingNullability: androidx.mediarouter.media.MediaRouter#setMediaSessionCompat(android.support.v4.media.session.MediaSessionCompat) parameter #0:
+    Missing nullability on parameter `mediaSession` in method `setMediaSessionCompat`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onProviderAdded(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.ProviderInfo) parameter #0:
+    Missing nullability on parameter `router` in method `onProviderAdded`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onProviderAdded(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.ProviderInfo) parameter #1:
+    Missing nullability on parameter `provider` in method `onProviderAdded`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onProviderChanged(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.ProviderInfo) parameter #0:
+    Missing nullability on parameter `router` in method `onProviderChanged`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onProviderChanged(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.ProviderInfo) parameter #1:
+    Missing nullability on parameter `provider` in method `onProviderChanged`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onProviderRemoved(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.ProviderInfo) parameter #0:
+    Missing nullability on parameter `router` in method `onProviderRemoved`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onProviderRemoved(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.ProviderInfo) parameter #1:
+    Missing nullability on parameter `provider` in method `onProviderRemoved`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onRouteAdded(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo) parameter #0:
+    Missing nullability on parameter `router` in method `onRouteAdded`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onRouteAdded(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo) parameter #1:
+    Missing nullability on parameter `route` in method `onRouteAdded`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onRouteChanged(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo) parameter #0:
+    Missing nullability on parameter `router` in method `onRouteChanged`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onRouteChanged(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo) parameter #1:
+    Missing nullability on parameter `route` in method `onRouteChanged`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onRoutePresentationDisplayChanged(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo) parameter #0:
+    Missing nullability on parameter `router` in method `onRoutePresentationDisplayChanged`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onRoutePresentationDisplayChanged(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo) parameter #1:
+    Missing nullability on parameter `route` in method `onRoutePresentationDisplayChanged`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onRouteRemoved(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo) parameter #0:
+    Missing nullability on parameter `router` in method `onRouteRemoved`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onRouteRemoved(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo) parameter #1:
+    Missing nullability on parameter `route` in method `onRouteRemoved`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onRouteSelected(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo) parameter #0:
+    Missing nullability on parameter `router` in method `onRouteSelected`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onRouteSelected(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo) parameter #1:
+    Missing nullability on parameter `route` in method `onRouteSelected`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onRouteUnselected(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo) parameter #0:
+    Missing nullability on parameter `router` in method `onRouteUnselected`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onRouteUnselected(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo) parameter #1:
+    Missing nullability on parameter `route` in method `onRouteUnselected`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onRouteUnselected(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo, int) parameter #0:
+    Missing nullability on parameter `router` in method `onRouteUnselected`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onRouteUnselected(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo, int) parameter #1:
+    Missing nullability on parameter `route` in method `onRouteUnselected`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onRouteVolumeChanged(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo) parameter #0:
+    Missing nullability on parameter `router` in method `onRouteVolumeChanged`
+MissingNullability: androidx.mediarouter.media.MediaRouter.Callback#onRouteVolumeChanged(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo) parameter #1:
+    Missing nullability on parameter `route` in method `onRouteVolumeChanged`
+MissingNullability: androidx.mediarouter.media.MediaRouter.ControlRequestCallback#onError(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `error` in method `onError`
+MissingNullability: androidx.mediarouter.media.MediaRouter.ControlRequestCallback#onError(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `data` in method `onError`
+MissingNullability: androidx.mediarouter.media.MediaRouter.ControlRequestCallback#onResult(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `data` in method `onResult`
+MissingNullability: androidx.mediarouter.media.MediaRouter.ProviderInfo#getComponentName():
+    Missing nullability on method `getComponentName` return
+MissingNullability: androidx.mediarouter.media.MediaRouter.ProviderInfo#getPackageName():
+    Missing nullability on method `getPackageName` return
+MissingNullability: androidx.mediarouter.media.MediaRouter.ProviderInfo#getProviderInstance():
+    Missing nullability on method `getProviderInstance` return
+MissingNullability: androidx.mediarouter.media.MediaRouter.ProviderInfo#getRoutes():
+    Missing nullability on method `getRoutes` return
+MissingNullability: androidx.mediarouter.media.MediaRouter.ProviderInfo#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.mediarouter.media.MediaRouter.RouteInfo#getControlFilters():
+    Missing nullability on method `getControlFilters` return
+MissingNullability: androidx.mediarouter.media.MediaRouter.RouteInfo#getIconUri():
+    Missing nullability on method `getIconUri` return
+MissingNullability: androidx.mediarouter.media.MediaRouter.RouteInfo#getName():
+    Missing nullability on method `getName` return
+MissingNullability: androidx.mediarouter.media.MediaRouter.RouteInfo#getProvider():
+    Missing nullability on method `getProvider` return
+MissingNullability: androidx.mediarouter.media.MediaRouter.RouteInfo#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.mediarouter.media.MediaSessionStatus#asBundle():
+    Missing nullability on method `asBundle` return
+MissingNullability: androidx.mediarouter.media.MediaSessionStatus#fromBundle(android.os.Bundle):
+    Missing nullability on method `fromBundle` return
+MissingNullability: androidx.mediarouter.media.MediaSessionStatus#fromBundle(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `bundle` in method `fromBundle`
+MissingNullability: androidx.mediarouter.media.MediaSessionStatus#getExtras():
+    Missing nullability on method `getExtras` return
+MissingNullability: androidx.mediarouter.media.MediaSessionStatus#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.mediarouter.media.MediaSessionStatus.Builder#Builder(androidx.mediarouter.media.MediaSessionStatus) parameter #0:
+    Missing nullability on parameter `status` in method `Builder`
+MissingNullability: androidx.mediarouter.media.MediaSessionStatus.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.mediarouter.media.MediaSessionStatus.Builder#setExtras(android.os.Bundle):
+    Missing nullability on method `setExtras` return
+MissingNullability: androidx.mediarouter.media.MediaSessionStatus.Builder#setExtras(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `extras` in method `setExtras`
+MissingNullability: androidx.mediarouter.media.MediaSessionStatus.Builder#setQueuePaused(boolean):
+    Missing nullability on method `setQueuePaused` return
+MissingNullability: androidx.mediarouter.media.MediaSessionStatus.Builder#setSessionState(int):
+    Missing nullability on method `setSessionState` return
+MissingNullability: androidx.mediarouter.media.MediaSessionStatus.Builder#setTimestamp(long):
+    Missing nullability on method `setTimestamp` return
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#RemotePlaybackClient(android.content.Context, androidx.mediarouter.media.MediaRouter.RouteInfo) parameter #0:
+    Missing nullability on parameter `context` in method `RemotePlaybackClient`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#RemotePlaybackClient(android.content.Context, androidx.mediarouter.media.MediaRouter.RouteInfo) parameter #1:
+    Missing nullability on parameter `route` in method `RemotePlaybackClient`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#endSession(android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback) parameter #0:
+    Missing nullability on parameter `extras` in method `endSession`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#endSession(android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback) parameter #1:
+    Missing nullability on parameter `callback` in method `endSession`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#enqueue(android.net.Uri, String, android.os.Bundle, long, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #0:
+    Missing nullability on parameter `contentUri` in method `enqueue`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#enqueue(android.net.Uri, String, android.os.Bundle, long, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #1:
+    Missing nullability on parameter `mimeType` in method `enqueue`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#enqueue(android.net.Uri, String, android.os.Bundle, long, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #2:
+    Missing nullability on parameter `metadata` in method `enqueue`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#enqueue(android.net.Uri, String, android.os.Bundle, long, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #4:
+    Missing nullability on parameter `extras` in method `enqueue`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#enqueue(android.net.Uri, String, android.os.Bundle, long, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #5:
+    Missing nullability on parameter `callback` in method `enqueue`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#getSessionId():
+    Missing nullability on method `getSessionId` return
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#getSessionStatus(android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback) parameter #0:
+    Missing nullability on parameter `extras` in method `getSessionStatus`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#getSessionStatus(android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback) parameter #1:
+    Missing nullability on parameter `callback` in method `getSessionStatus`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#getStatus(String, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #0:
+    Missing nullability on parameter `itemId` in method `getStatus`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#getStatus(String, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #1:
+    Missing nullability on parameter `extras` in method `getStatus`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#getStatus(String, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #2:
+    Missing nullability on parameter `callback` in method `getStatus`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#pause(android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback) parameter #0:
+    Missing nullability on parameter `extras` in method `pause`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#pause(android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback) parameter #1:
+    Missing nullability on parameter `callback` in method `pause`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#play(android.net.Uri, String, android.os.Bundle, long, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #0:
+    Missing nullability on parameter `contentUri` in method `play`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#play(android.net.Uri, String, android.os.Bundle, long, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #1:
+    Missing nullability on parameter `mimeType` in method `play`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#play(android.net.Uri, String, android.os.Bundle, long, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #2:
+    Missing nullability on parameter `metadata` in method `play`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#play(android.net.Uri, String, android.os.Bundle, long, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #4:
+    Missing nullability on parameter `extras` in method `play`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#play(android.net.Uri, String, android.os.Bundle, long, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #5:
+    Missing nullability on parameter `callback` in method `play`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#remove(String, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #0:
+    Missing nullability on parameter `itemId` in method `remove`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#remove(String, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #1:
+    Missing nullability on parameter `extras` in method `remove`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#remove(String, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #2:
+    Missing nullability on parameter `callback` in method `remove`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#resume(android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback) parameter #0:
+    Missing nullability on parameter `extras` in method `resume`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#resume(android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback) parameter #1:
+    Missing nullability on parameter `callback` in method `resume`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#seek(String, long, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #0:
+    Missing nullability on parameter `itemId` in method `seek`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#seek(String, long, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #2:
+    Missing nullability on parameter `extras` in method `seek`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#seek(String, long, android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback) parameter #3:
+    Missing nullability on parameter `callback` in method `seek`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#sendMessage(android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback) parameter #0:
+    Missing nullability on parameter `message` in method `sendMessage`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#sendMessage(android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback) parameter #1:
+    Missing nullability on parameter `callback` in method `sendMessage`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#setOnMessageReceivedListener(androidx.mediarouter.media.RemotePlaybackClient.OnMessageReceivedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnMessageReceivedListener`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#setSessionId(String) parameter #0:
+    Missing nullability on parameter `sessionId` in method `setSessionId`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#setStatusCallback(androidx.mediarouter.media.RemotePlaybackClient.StatusCallback) parameter #0:
+    Missing nullability on parameter `callback` in method `setStatusCallback`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#startSession(android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback) parameter #0:
+    Missing nullability on parameter `extras` in method `startSession`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#startSession(android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback) parameter #1:
+    Missing nullability on parameter `callback` in method `startSession`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#stop(android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback) parameter #0:
+    Missing nullability on parameter `extras` in method `stop`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient#stop(android.os.Bundle, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback) parameter #1:
+    Missing nullability on parameter `callback` in method `stop`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.ActionCallback#onError(String, int, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `error` in method `onError`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.ActionCallback#onError(String, int, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `data` in method `onError`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback#onResult(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus, String, androidx.mediarouter.media.MediaItemStatus) parameter #0:
+    Missing nullability on parameter `data` in method `onResult`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback#onResult(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus, String, androidx.mediarouter.media.MediaItemStatus) parameter #1:
+    Missing nullability on parameter `sessionId` in method `onResult`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback#onResult(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus, String, androidx.mediarouter.media.MediaItemStatus) parameter #2:
+    Missing nullability on parameter `sessionStatus` in method `onResult`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback#onResult(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus, String, androidx.mediarouter.media.MediaItemStatus) parameter #3:
+    Missing nullability on parameter `itemId` in method `onResult`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback#onResult(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus, String, androidx.mediarouter.media.MediaItemStatus) parameter #4:
+    Missing nullability on parameter `itemStatus` in method `onResult`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.OnMessageReceivedListener#onMessageReceived(String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `sessionId` in method `onMessageReceived`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.OnMessageReceivedListener#onMessageReceived(String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `message` in method `onMessageReceived`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback#onResult(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus) parameter #0:
+    Missing nullability on parameter `data` in method `onResult`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback#onResult(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus) parameter #1:
+    Missing nullability on parameter `sessionId` in method `onResult`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback#onResult(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus) parameter #2:
+    Missing nullability on parameter `sessionStatus` in method `onResult`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.StatusCallback#onItemStatusChanged(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus, String, androidx.mediarouter.media.MediaItemStatus) parameter #0:
+    Missing nullability on parameter `data` in method `onItemStatusChanged`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.StatusCallback#onItemStatusChanged(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus, String, androidx.mediarouter.media.MediaItemStatus) parameter #1:
+    Missing nullability on parameter `sessionId` in method `onItemStatusChanged`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.StatusCallback#onItemStatusChanged(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus, String, androidx.mediarouter.media.MediaItemStatus) parameter #2:
+    Missing nullability on parameter `sessionStatus` in method `onItemStatusChanged`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.StatusCallback#onItemStatusChanged(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus, String, androidx.mediarouter.media.MediaItemStatus) parameter #3:
+    Missing nullability on parameter `itemId` in method `onItemStatusChanged`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.StatusCallback#onItemStatusChanged(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus, String, androidx.mediarouter.media.MediaItemStatus) parameter #4:
+    Missing nullability on parameter `itemStatus` in method `onItemStatusChanged`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.StatusCallback#onSessionChanged(String) parameter #0:
+    Missing nullability on parameter `sessionId` in method `onSessionChanged`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.StatusCallback#onSessionStatusChanged(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus) parameter #0:
+    Missing nullability on parameter `data` in method `onSessionStatusChanged`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.StatusCallback#onSessionStatusChanged(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus) parameter #1:
+    Missing nullability on parameter `sessionId` in method `onSessionStatusChanged`
+MissingNullability: androidx.mediarouter.media.RemotePlaybackClient.StatusCallback#onSessionStatusChanged(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus) parameter #2:
+    Missing nullability on parameter `sessionStatus` in method `onSessionStatusChanged`
+
+
 RegistrationName: androidx.mediarouter.media.MediaRouter#addCallback(androidx.mediarouter.media.MediaRouteSelector, androidx.mediarouter.media.MediaRouter.Callback):
     Callback methods should be named register/unregister; was addCallback
 RegistrationName: androidx.mediarouter.media.MediaRouter#addCallback(androidx.mediarouter.media.MediaRouteSelector, androidx.mediarouter.media.MediaRouter.Callback, int):
diff --git a/navigation/navigation-common-ktx/api/2.2.0-alpha02.txt b/navigation/navigation-common-ktx/api/2.2.0-alpha02.txt
new file mode 100644
index 0000000..133a124
--- /dev/null
+++ b/navigation/navigation-common-ktx/api/2.2.0-alpha02.txt
@@ -0,0 +1,129 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+  @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 p);
+    method public void setExit(int p);
+    method public void setPopEnter(int p);
+    method public void setPopExit(int p);
+    property public final int enter;
+    property public final int exit;
+    property public final int popEnter;
+    property public final int popExit;
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class NavActionBuilder {
+    ctor public NavActionBuilder();
+    method public int getDestinationId();
+    method public void navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
+    method public void setDestinationId(int p);
+    property public final int destinationId;
+  }
+
+  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 {
+    ctor public NavArgsLazyKt();
+  }
+
+  @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? value);
+    method public void setNullable(boolean value);
+    method public void setType(androidx.navigation.NavType<?> value);
+    property public final Object? defaultValue;
+    property public final boolean nullable;
+    property public final androidx.navigation.NavType<?> type;
+  }
+
+  @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
+    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
+    method 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 int getId();
+    method public final CharSequence? getLabel();
+    method protected final androidx.navigation.Navigator<? extends D> getNavigator();
+    method public final void setLabel(CharSequence? p);
+    property public final CharSequence? label;
+  }
+
+  @kotlin.DslMarker public @interface NavDestinationDsl {
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
+    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
+    method public void addDestination(androidx.navigation.NavDestination destination);
+    method public androidx.navigation.NavGraph build();
+    method public <D extends androidx.navigation.NavDestination> void destination(androidx.navigation.NavDestinationBuilder<? extends D> navDestination);
+    method public androidx.navigation.NavigatorProvider getProvider();
+    method public operator void unaryPlus(androidx.navigation.NavDestination);
+  }
+
+  public final class NavGraphBuilderKt {
+    ctor public NavGraphBuilderKt();
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, @IdRes int id = 0, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method 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);
+  }
+
+  public final class NavGraphKt {
+    ctor public NavGraphKt();
+    method public static operator boolean contains(androidx.navigation.NavGraph, @IdRes int id);
+    method public static inline operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, @IdRes int id);
+    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.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 public int getPopUpTo();
+    method public void popUpTo(@IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
+    method public void setLaunchSingleTop(boolean p);
+    method public void setPopUpTo(int value);
+    property public final boolean launchSingleTop;
+    property public final int popUpTo;
+  }
+
+  public final class NavOptionsBuilderKt {
+    ctor public 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 final class NavigatorProviderKt {
+    ctor public 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);
+  }
+
+  @androidx.navigation.NavOptionsDsl public final class PopUpToBuilder {
+    ctor public PopUpToBuilder();
+    method public boolean getInclusive();
+    method public void setInclusive(boolean p);
+    property public final boolean inclusive;
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha02.txt b/navigation/navigation-common-ktx/api/res-2.2.0-alpha02.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha02.txt
copy to navigation/navigation-common-ktx/api/res-2.2.0-alpha02.txt
diff --git a/navigation/navigation-common-ktx/api/restricted_2.2.0-alpha02.txt b/navigation/navigation-common-ktx/api/restricted_2.2.0-alpha02.txt
new file mode 100644
index 0000000..133a124
--- /dev/null
+++ b/navigation/navigation-common-ktx/api/restricted_2.2.0-alpha02.txt
@@ -0,0 +1,129 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+  @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 p);
+    method public void setExit(int p);
+    method public void setPopEnter(int p);
+    method public void setPopExit(int p);
+    property public final int enter;
+    property public final int exit;
+    property public final int popEnter;
+    property public final int popExit;
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class NavActionBuilder {
+    ctor public NavActionBuilder();
+    method public int getDestinationId();
+    method public void navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
+    method public void setDestinationId(int p);
+    property public final int destinationId;
+  }
+
+  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 {
+    ctor public NavArgsLazyKt();
+  }
+
+  @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? value);
+    method public void setNullable(boolean value);
+    method public void setType(androidx.navigation.NavType<?> value);
+    property public final Object? defaultValue;
+    property public final boolean nullable;
+    property public final androidx.navigation.NavType<?> type;
+  }
+
+  @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
+    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
+    method 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 int getId();
+    method public final CharSequence? getLabel();
+    method protected final androidx.navigation.Navigator<? extends D> getNavigator();
+    method public final void setLabel(CharSequence? p);
+    property public final CharSequence? label;
+  }
+
+  @kotlin.DslMarker public @interface NavDestinationDsl {
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
+    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
+    method public void addDestination(androidx.navigation.NavDestination destination);
+    method public androidx.navigation.NavGraph build();
+    method public <D extends androidx.navigation.NavDestination> void destination(androidx.navigation.NavDestinationBuilder<? extends D> navDestination);
+    method public androidx.navigation.NavigatorProvider getProvider();
+    method public operator void unaryPlus(androidx.navigation.NavDestination);
+  }
+
+  public final class NavGraphBuilderKt {
+    ctor public NavGraphBuilderKt();
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, @IdRes int id = 0, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method 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);
+  }
+
+  public final class NavGraphKt {
+    ctor public NavGraphKt();
+    method public static operator boolean contains(androidx.navigation.NavGraph, @IdRes int id);
+    method public static inline operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, @IdRes int id);
+    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.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 public int getPopUpTo();
+    method public void popUpTo(@IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
+    method public void setLaunchSingleTop(boolean p);
+    method public void setPopUpTo(int value);
+    property public final boolean launchSingleTop;
+    property public final int popUpTo;
+  }
+
+  public final class NavOptionsBuilderKt {
+    ctor public 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 final class NavigatorProviderKt {
+    ctor public 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);
+  }
+
+  @androidx.navigation.NavOptionsDsl public final class PopUpToBuilder {
+    ctor public PopUpToBuilder();
+    method public boolean getInclusive();
+    method public void setInclusive(boolean p);
+    property public final boolean inclusive;
+  }
+
+}
+
diff --git a/navigation/navigation-common/api/2.2.0-alpha02.txt b/navigation/navigation-common/api/2.2.0-alpha02.txt
new file mode 100644
index 0000000..736fe0f
--- /dev/null
+++ b/navigation/navigation-common/api/2.2.0-alpha02.txt
@@ -0,0 +1,196 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+  public final class ActionOnlyNavDirections implements androidx.navigation.NavDirections {
+    ctor public ActionOnlyNavDirections(int);
+    method public int getActionId();
+    method public android.os.Bundle getArguments();
+  }
+
+  public interface FloatingWindow {
+  }
+
+  public final class NavAction {
+    ctor public NavAction(@IdRes int);
+    ctor public NavAction(@IdRes int, androidx.navigation.NavOptions?);
+    ctor public NavAction(@IdRes int, androidx.navigation.NavOptions?, android.os.Bundle?);
+    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?);
+  }
+
+  public interface NavArgs {
+  }
+
+  public final class NavArgument {
+    method public Object? getDefaultValue();
+    method public androidx.navigation.NavType<?> getType();
+    method public boolean isDefaultValuePresent();
+    method public boolean isNullable();
+  }
+
+  public static final class NavArgument.Builder {
+    ctor public NavArgument.Builder();
+    method public androidx.navigation.NavArgument build();
+    method public androidx.navigation.NavArgument.Builder setDefaultValue(Object?);
+    method public androidx.navigation.NavArgument.Builder setIsNullable(boolean);
+    method public androidx.navigation.NavArgument.Builder setType(androidx.navigation.NavType<?>);
+  }
+
+  public class NavDestination {
+    ctor public NavDestination(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>);
+    ctor public NavDestination(String);
+    method public final void addArgument(String, androidx.navigation.NavArgument);
+    method public final void addDeepLink(String);
+    method public final androidx.navigation.NavAction? getAction(@IdRes int);
+    method public final java.util.Map<java.lang.String!,androidx.navigation.NavArgument!> getArguments();
+    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 boolean hasDeepLink(android.net.Uri);
+    method @CallSuper public void onInflate(android.content.Context, android.util.AttributeSet);
+    method protected static <C> Class<? extends C> parseClassFromName(android.content.Context, String, Class<? extends C>);
+    method public final void putAction(@IdRes int, @IdRes int);
+    method public final void putAction(@IdRes int, androidx.navigation.NavAction);
+    method public final void removeAction(@IdRes int);
+    method public final void removeArgument(String);
+    method public final void setId(@IdRes int);
+    method public final void setLabel(CharSequence?);
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) public static @interface NavDestination.ClassType {
+    method public abstract Class<?> value();
+  }
+
+  public interface NavDirections {
+    method @IdRes public int getActionId();
+    method public android.os.Bundle getArguments();
+  }
+
+  public class NavGraph extends androidx.navigation.NavDestination implements java.lang.Iterable<androidx.navigation.NavDestination> {
+    ctor public NavGraph(androidx.navigation.Navigator<? extends androidx.navigation.NavGraph>);
+    method public final void addAll(androidx.navigation.NavGraph);
+    method public final void addDestination(androidx.navigation.NavDestination);
+    method public final void addDestinations(java.util.Collection<androidx.navigation.NavDestination!>);
+    method public final void addDestinations(androidx.navigation.NavDestination!...);
+    method public final void clear();
+    method public final androidx.navigation.NavDestination? findNode(@IdRes int);
+    method @IdRes public final int getStartDestination();
+    method public final java.util.Iterator<androidx.navigation.NavDestination!> iterator();
+    method public final void remove(androidx.navigation.NavDestination);
+    method public final void setStartDestination(@IdRes int);
+  }
+
+  @androidx.navigation.Navigator.Name("navigation") public class NavGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.NavGraph> {
+    ctor public NavGraphNavigator(androidx.navigation.NavigatorProvider);
+    method public androidx.navigation.NavGraph createDestination();
+    method public androidx.navigation.NavDestination? navigate(androidx.navigation.NavGraph, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+    method public boolean popBackStack();
+  }
+
+  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 @IdRes public int getPopUpTo();
+    method public boolean isPopUpToInclusive();
+    method public boolean shouldLaunchSingleTop();
+  }
+
+  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);
+    method public androidx.navigation.NavOptions.Builder setExitAnim(@AnimRes @AnimatorRes int);
+    method public androidx.navigation.NavOptions.Builder setLaunchSingleTop(boolean);
+    method public androidx.navigation.NavOptions.Builder setPopEnterAnim(@AnimRes @AnimatorRes int);
+    method public androidx.navigation.NavOptions.Builder setPopExitAnim(@AnimRes @AnimatorRes int);
+    method public androidx.navigation.NavOptions.Builder setPopUpTo(@IdRes int, boolean);
+  }
+
+  public abstract class NavType<T> {
+    method public static androidx.navigation.NavType<?> fromArgType(String?, String?);
+    method public abstract T? get(android.os.Bundle, String);
+    method public abstract String getName();
+    method public boolean isNullableAllowed();
+    method public abstract T parseValue(String);
+    method public abstract void put(android.os.Bundle, String, T?);
+    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<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.EnumType<D extends java.lang.Enum> extends androidx.navigation.NavType.SerializableType<D> {
+    ctor public NavType.EnumType(Class<D!>);
+  }
+
+  public static final class NavType.ParcelableArrayType<D extends android.os.Parcelable> extends androidx.navigation.NavType<D[]> {
+    ctor public NavType.ParcelableArrayType(Class<D!>);
+    method public D![]? get(android.os.Bundle, String);
+    method public String getName();
+    method public D![] parseValue(String);
+    method public void put(android.os.Bundle, String, D![]?);
+  }
+
+  public static final class NavType.ParcelableType<D> extends androidx.navigation.NavType<D> {
+    ctor public NavType.ParcelableType(Class<D!>);
+    method public D? get(android.os.Bundle, String);
+    method public String getName();
+    method public D parseValue(String);
+    method public void put(android.os.Bundle, String, D?);
+  }
+
+  public static final class NavType.SerializableArrayType<D extends java.io.Serializable> extends androidx.navigation.NavType<D[]> {
+    ctor public NavType.SerializableArrayType(Class<D!>);
+    method public D![]? get(android.os.Bundle, String);
+    method public String getName();
+    method public D![] parseValue(String);
+    method public void put(android.os.Bundle, String, D![]?);
+  }
+
+  public static class NavType.SerializableType<D extends java.io.Serializable> extends androidx.navigation.NavType<D> {
+    ctor public NavType.SerializableType(Class<D!>);
+    method public D? get(android.os.Bundle, String);
+    method public String getName();
+    method public D parseValue(String);
+    method public void put(android.os.Bundle, String, D?);
+  }
+
+  public abstract class Navigator<D extends androidx.navigation.NavDestination> {
+    ctor public Navigator();
+    method public abstract D createDestination();
+    method public abstract androidx.navigation.NavDestination? navigate(D, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+    method public void onRestoreState(android.os.Bundle);
+    method public android.os.Bundle? onSaveState();
+    method public abstract boolean popBackStack();
+  }
+
+  public static interface Navigator.Extras {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) public static @interface Navigator.Name {
+    method 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>);
+    method @CallSuper public androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? addNavigator(String, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>);
+    method public final <T extends androidx.navigation.Navigator<?>> T getNavigator(Class<T!>);
+    method @CallSuper public <T extends androidx.navigation.Navigator<?>> T getNavigator(String);
+  }
+
+}
+
diff --git a/navigation/navigation-common/api/api_lint.ignore b/navigation/navigation-common/api/api_lint.ignore
index 7fcf560..a3f2c30 100644
--- a/navigation/navigation-common/api/api_lint.ignore
+++ b/navigation/navigation-common/api/api_lint.ignore
@@ -1,3 +1,23 @@
 // Baseline format: 1.0
 KotlinOperator: androidx.navigation.NavType#get(android.os.Bundle, String):
     Method can be invoked with an indexing operator from Kotlin: `get` (this is usually desirable; just make sure it makes sense for this type of object)
+
+
+MissingNullability: androidx.navigation.ActionOnlyNavDirections#equals(Object) parameter #0:
+    Missing nullability on parameter `object` in method `equals`
+MissingNullability: androidx.navigation.ActionOnlyNavDirections#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.navigation.NavArgument#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.navigation.NavDestination.ClassType#value():
+    Missing nullability on method `value` return
+MissingNullability: androidx.navigation.NavType.ParcelableArrayType#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.navigation.NavType.ParcelableType#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.navigation.NavType.SerializableArrayType#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.navigation.NavType.SerializableType#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.navigation.Navigator.Name#value():
+    Missing nullability on method `value` return
diff --git a/preference/ktx/api/res-1.1.0-alpha02.txt b/navigation/navigation-common/api/res-2.2.0-alpha02.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha02.txt
copy to navigation/navigation-common/api/res-2.2.0-alpha02.txt
diff --git a/navigation/navigation-common/api/restricted_2.2.0-alpha02.txt b/navigation/navigation-common/api/restricted_2.2.0-alpha02.txt
new file mode 100644
index 0000000..736fe0f
--- /dev/null
+++ b/navigation/navigation-common/api/restricted_2.2.0-alpha02.txt
@@ -0,0 +1,196 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+  public final class ActionOnlyNavDirections implements androidx.navigation.NavDirections {
+    ctor public ActionOnlyNavDirections(int);
+    method public int getActionId();
+    method public android.os.Bundle getArguments();
+  }
+
+  public interface FloatingWindow {
+  }
+
+  public final class NavAction {
+    ctor public NavAction(@IdRes int);
+    ctor public NavAction(@IdRes int, androidx.navigation.NavOptions?);
+    ctor public NavAction(@IdRes int, androidx.navigation.NavOptions?, android.os.Bundle?);
+    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?);
+  }
+
+  public interface NavArgs {
+  }
+
+  public final class NavArgument {
+    method public Object? getDefaultValue();
+    method public androidx.navigation.NavType<?> getType();
+    method public boolean isDefaultValuePresent();
+    method public boolean isNullable();
+  }
+
+  public static final class NavArgument.Builder {
+    ctor public NavArgument.Builder();
+    method public androidx.navigation.NavArgument build();
+    method public androidx.navigation.NavArgument.Builder setDefaultValue(Object?);
+    method public androidx.navigation.NavArgument.Builder setIsNullable(boolean);
+    method public androidx.navigation.NavArgument.Builder setType(androidx.navigation.NavType<?>);
+  }
+
+  public class NavDestination {
+    ctor public NavDestination(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>);
+    ctor public NavDestination(String);
+    method public final void addArgument(String, androidx.navigation.NavArgument);
+    method public final void addDeepLink(String);
+    method public final androidx.navigation.NavAction? getAction(@IdRes int);
+    method public final java.util.Map<java.lang.String!,androidx.navigation.NavArgument!> getArguments();
+    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 boolean hasDeepLink(android.net.Uri);
+    method @CallSuper public void onInflate(android.content.Context, android.util.AttributeSet);
+    method protected static <C> Class<? extends C> parseClassFromName(android.content.Context, String, Class<? extends C>);
+    method public final void putAction(@IdRes int, @IdRes int);
+    method public final void putAction(@IdRes int, androidx.navigation.NavAction);
+    method public final void removeAction(@IdRes int);
+    method public final void removeArgument(String);
+    method public final void setId(@IdRes int);
+    method public final void setLabel(CharSequence?);
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) public static @interface NavDestination.ClassType {
+    method public abstract Class<?> value();
+  }
+
+  public interface NavDirections {
+    method @IdRes public int getActionId();
+    method public android.os.Bundle getArguments();
+  }
+
+  public class NavGraph extends androidx.navigation.NavDestination implements java.lang.Iterable<androidx.navigation.NavDestination> {
+    ctor public NavGraph(androidx.navigation.Navigator<? extends androidx.navigation.NavGraph>);
+    method public final void addAll(androidx.navigation.NavGraph);
+    method public final void addDestination(androidx.navigation.NavDestination);
+    method public final void addDestinations(java.util.Collection<androidx.navigation.NavDestination!>);
+    method public final void addDestinations(androidx.navigation.NavDestination!...);
+    method public final void clear();
+    method public final androidx.navigation.NavDestination? findNode(@IdRes int);
+    method @IdRes public final int getStartDestination();
+    method public final java.util.Iterator<androidx.navigation.NavDestination!> iterator();
+    method public final void remove(androidx.navigation.NavDestination);
+    method public final void setStartDestination(@IdRes int);
+  }
+
+  @androidx.navigation.Navigator.Name("navigation") public class NavGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.NavGraph> {
+    ctor public NavGraphNavigator(androidx.navigation.NavigatorProvider);
+    method public androidx.navigation.NavGraph createDestination();
+    method public androidx.navigation.NavDestination? navigate(androidx.navigation.NavGraph, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+    method public boolean popBackStack();
+  }
+
+  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 @IdRes public int getPopUpTo();
+    method public boolean isPopUpToInclusive();
+    method public boolean shouldLaunchSingleTop();
+  }
+
+  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);
+    method public androidx.navigation.NavOptions.Builder setExitAnim(@AnimRes @AnimatorRes int);
+    method public androidx.navigation.NavOptions.Builder setLaunchSingleTop(boolean);
+    method public androidx.navigation.NavOptions.Builder setPopEnterAnim(@AnimRes @AnimatorRes int);
+    method public androidx.navigation.NavOptions.Builder setPopExitAnim(@AnimRes @AnimatorRes int);
+    method public androidx.navigation.NavOptions.Builder setPopUpTo(@IdRes int, boolean);
+  }
+
+  public abstract class NavType<T> {
+    method public static androidx.navigation.NavType<?> fromArgType(String?, String?);
+    method public abstract T? get(android.os.Bundle, String);
+    method public abstract String getName();
+    method public boolean isNullableAllowed();
+    method public abstract T parseValue(String);
+    method public abstract void put(android.os.Bundle, String, T?);
+    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<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.EnumType<D extends java.lang.Enum> extends androidx.navigation.NavType.SerializableType<D> {
+    ctor public NavType.EnumType(Class<D!>);
+  }
+
+  public static final class NavType.ParcelableArrayType<D extends android.os.Parcelable> extends androidx.navigation.NavType<D[]> {
+    ctor public NavType.ParcelableArrayType(Class<D!>);
+    method public D![]? get(android.os.Bundle, String);
+    method public String getName();
+    method public D![] parseValue(String);
+    method public void put(android.os.Bundle, String, D![]?);
+  }
+
+  public static final class NavType.ParcelableType<D> extends androidx.navigation.NavType<D> {
+    ctor public NavType.ParcelableType(Class<D!>);
+    method public D? get(android.os.Bundle, String);
+    method public String getName();
+    method public D parseValue(String);
+    method public void put(android.os.Bundle, String, D?);
+  }
+
+  public static final class NavType.SerializableArrayType<D extends java.io.Serializable> extends androidx.navigation.NavType<D[]> {
+    ctor public NavType.SerializableArrayType(Class<D!>);
+    method public D![]? get(android.os.Bundle, String);
+    method public String getName();
+    method public D![] parseValue(String);
+    method public void put(android.os.Bundle, String, D![]?);
+  }
+
+  public static class NavType.SerializableType<D extends java.io.Serializable> extends androidx.navigation.NavType<D> {
+    ctor public NavType.SerializableType(Class<D!>);
+    method public D? get(android.os.Bundle, String);
+    method public String getName();
+    method public D parseValue(String);
+    method public void put(android.os.Bundle, String, D?);
+  }
+
+  public abstract class Navigator<D extends androidx.navigation.NavDestination> {
+    ctor public Navigator();
+    method public abstract D createDestination();
+    method public abstract androidx.navigation.NavDestination? navigate(D, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+    method public void onRestoreState(android.os.Bundle);
+    method public android.os.Bundle? onSaveState();
+    method public abstract boolean popBackStack();
+  }
+
+  public static interface Navigator.Extras {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) public static @interface Navigator.Name {
+    method 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>);
+    method @CallSuper public androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? addNavigator(String, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>);
+    method public final <T extends androidx.navigation.Navigator<?>> T getNavigator(Class<T!>);
+    method @CallSuper public <T extends androidx.navigation.Navigator<?>> T getNavigator(String);
+  }
+
+}
+
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/AddInDefaultArgsTest.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/AddInDefaultArgsTest.kt
index fff7f49..a084bc3 100644
--- a/navigation/navigation-common/src/androidTest/java/androidx/navigation/AddInDefaultArgsTest.kt
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/AddInDefaultArgsTest.kt
@@ -17,6 +17,8 @@
 package androidx.navigation
 
 import android.os.Bundle
+import androidx.navigation.test.intArgument
+import androidx.navigation.test.stringArgument
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
@@ -24,18 +26,9 @@
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
 
-private val stringArgument = "stringArg" to NavArgument.Builder()
-    .setType(NavType.StringType)
-    .setIsNullable(true)
-    .build()
-private val stringArgumentWithDefault = "stringArg" to NavArgument.Builder()
-    .setType(NavType.StringType)
-    .setDefaultValue("aaa")
-    .build()
-private val intArgument = "intArg" to NavArgument.Builder()
-    .setType(NavType.IntType)
-    .setDefaultValue(123)
-    .build()
+private val stringArgumentWithoutDefault = "stringArg" to stringArgument(true)
+private val stringArgumentWithDefault = "stringArg" to stringArgument("aaa")
+private val intArgumentWithDefault = "intArg" to intArgument(123)
 
 @SmallTest
 @RunWith(Parameterized::class)
@@ -51,11 +44,11 @@
                 // Test with an empty set of arguments
                 mapOf(),
                 // Test with an argument with no default value
-                mapOf(stringArgument),
+                mapOf(stringArgumentWithoutDefault),
                 // Test with arguments where only some have default values
-                mapOf(stringArgument, intArgument),
+                mapOf(stringArgumentWithoutDefault, intArgumentWithDefault),
                 // Test with arguments that have default values
-                mapOf(stringArgumentWithDefault, intArgument)
+                mapOf(stringArgumentWithDefault, intArgumentWithDefault)
             ).forEach { arguments: Map<String, NavArgument> ->
                 // Run with a null Bundle
                 add(arrayOf(arguments, Bundle.EMPTY))
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDeepLinkTest.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDeepLinkTest.kt
index f400def..b26ce1c 100644
--- a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDeepLinkTest.kt
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDeepLinkTest.kt
@@ -17,9 +17,13 @@
 package androidx.navigation
 
 import android.net.Uri
+import androidx.navigation.test.intArgument
+import androidx.navigation.test.nullableStringArgument
+import androidx.navigation.test.stringArgument
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Assert.fail
 import org.junit.Test
 import java.io.UnsupportedEncodingException
 
@@ -109,7 +113,7 @@
         val id = 2
         val matchArgs = deepLink.getMatchingArguments(
             Uri.parse(deepLinkArgument.replace("{id}", id.toString())),
-            mapOf("id" to NavArgument.Builder().setType(NavType.IntType).build())
+            mapOf("id" to intArgument())
         )
         assertWithMessage("Args should not be null")
             .that(matchArgs)
@@ -127,7 +131,7 @@
         val id = "invalid"
         val matchArgs = deepLink.getMatchingArguments(
             Uri.parse(deepLinkArgument.replace("{id}", id)),
-            mapOf("id" to NavArgument.Builder().setType(NavType.IntType).build())
+            mapOf("id" to intArgument())
         )
         assertWithMessage("Args should be null")
             .that(matchArgs)
@@ -142,7 +146,7 @@
         val id = 2
         val matchArgs = deepLink.getMatchingArguments(
             Uri.parse(deepLinkArgument.replace("{id}", id.toString())),
-            mapOf("id" to NavArgument.Builder().setType(NavType.IntType).build())
+            mapOf("id" to intArgument())
         )
         assertWithMessage("Args should not be null")
             .that(matchArgs)
@@ -153,6 +157,591 @@
     }
 
     @Test
+    fun deepLinkQueryParamArgumentInvalidMatch() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?id={id}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = "invalid"
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse(deepLinkArgument.replace("{id}", id)),
+            mapOf("id" to intArgument())
+        )
+        assertWithMessage("Args should be null")
+            .that(matchArgs)
+            .isNull()
+    }
+
+    @Test
+    fun deepLinkQueryParamMultipleArgumentMatch() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?id={id}&myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = 2
+        val myarg = "test"
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse(deepLinkArgument
+                .replace("{id}", id.toString()).replace("{myarg}", myarg)),
+            mapOf("id" to intArgument(),
+                "myarg" to stringArgument())
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the id")
+            .that(matchArgs?.getInt("id"))
+            .isEqualTo(id)
+        assertWithMessage("Args should contain the argument")
+            .that(matchArgs?.getString("myarg"))
+            .isEqualTo(myarg)
+    }
+
+    @Test
+    fun deepLinkQueryParamDefaultArgumentMatch() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?id={id}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = 2
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users"),
+            mapOf("id" to intArgument(id))
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the id")
+            .that(matchArgs?.getInt("id"))
+            .isEqualTo(id)
+    }
+
+    @Test
+    fun deepLinkQueryParamNullableArgumentMatch() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users"),
+            mapOf("myarg" to nullableStringArgument())
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the argument and it should be null")
+            .that(matchArgs?.getString("myarg"))
+            .isEqualTo("@null")
+    }
+
+    // Ensure case when matching the exact argument query (i.e. param names in braces) is handled
+    @Test
+    fun deepLinkQueryParamDefaultArgumentMatchParamsInBraces() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?id={id}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = 2
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse(deepLinkArgument),
+            mapOf("id" to intArgument(id))
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the id")
+            .that(matchArgs?.getInt("id"))
+            .isEqualTo(id)
+    }
+
+    // Ensure case when matching the exact argument query (i.e. param names in braces) is handled
+    @Test
+    fun deepLinkQueryParamNullableArgumentMatchParamsInBraces() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse(deepLinkArgument),
+            mapOf("myarg" to nullableStringArgument())
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the argument and it should be null")
+            .that(matchArgs?.getString("myarg"))
+            .isEqualTo("@null")
+    }
+
+    @Test
+    fun deepLinkQueryParamMultipleArgumentMatchOptionalDefault() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?id={id}&optional={optional}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = 2
+        val optional = "test"
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users?id={id}".replace("{id}", id.toString())),
+            mapOf("id" to intArgument(),
+                "optional" to stringArgument(optional))
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the id")
+            .that(matchArgs?.getInt("id"))
+            .isEqualTo(id)
+        assertWithMessage("Args should contain optional")
+            .that(matchArgs?.getString("optional"))
+            .isEqualTo(optional)
+    }
+
+    @Test
+    fun deepLinkQueryParamMultipleArgumentReverseMatchOptionalDefault() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?id={id}&optional={optional}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = 2
+        val optional = "test"
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users?optional={optional}&id={id}"
+                .replace("{id}", id.toString())),
+            mapOf("id" to intArgument(),
+                "optional" to stringArgument(optional))
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the id")
+            .that(matchArgs?.getInt("id"))
+            .isEqualTo(id)
+        assertWithMessage("Args should contain optional")
+            .that(matchArgs?.getString("optional"))
+            .isEqualTo(optional)
+    }
+
+    @Test
+    fun deepLinkQueryParamMultipleArgumentMatchOptionalNullable() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?id={id}&optional={optional}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = 2
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users?id={id}".replace("{id}", id.toString())),
+            mapOf("id" to intArgument(),
+                "optional" to nullableStringArgument())
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the id")
+            .that(matchArgs?.getInt("id"))
+            .isEqualTo(id)
+        assertWithMessage("Args should contain optional")
+            .that(matchArgs?.getString("optional"))
+            .isEqualTo("@null")
+    }
+
+    @Test
+    fun deepLinkQueryParamArgumentMatchExtraParam() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?id={id}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = 2
+        try {
+            deepLink.getMatchingArguments(
+                Uri.parse("$DEEP_LINK_EXACT_HTTPS/users?id={id}&invalid={invalid}"
+                    .replace("{id}", id.toString())),
+                mapOf("id" to intArgument(),
+                    "invalid" to nullableStringArgument()))
+            fail(
+                "Adding parameter that does not exists in the NavDeepLink should throw " +
+                        "IllegalArgumentException"
+            )
+        } catch (e: IllegalArgumentException) {
+            assertThat(e)
+                .hasMessageThat().contains(
+                    "Please ensure the given query parameters are a subset of those in " +
+                            "NavDeepLink $deepLink"
+                )
+        }
+    }
+
+    @Test
+    fun deepLinkQueryParamArgumentMatchDifferentParamName() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?string={id}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = 2
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users?string={id}"
+                .replace("{id}", id.toString())),
+            mapOf("id" to intArgument())
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the id")
+            .that(matchArgs?.getInt("id"))
+            .isEqualTo(id)
+    }
+
+    @Test
+    fun deepLinkQueryNullableParamArgumentMatchDifferentParamName() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?string={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users"),
+            mapOf("myarg" to nullableStringArgument())
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the argument and it should be null")
+            .that(matchArgs?.getString("myarg"))
+            .isEqualTo("@null")
+    }
+
+    @Test
+    fun deepLinkQueryDefaultParamArgumentMatchDifferentParamName() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?string={id}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = 2
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users"),
+            mapOf("id" to intArgument(id))
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the id")
+            .that(matchArgs?.getInt("id"))
+            .isEqualTo(id)
+    }
+
+    @Test
+    fun deepLinkQueryParamArgumentMatchOnlyPartOfParam() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?id={id}L"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = 2
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse(deepLinkArgument.replace("{id}", id.toString())),
+            mapOf("id" to intArgument())
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the id")
+            .that(matchArgs?.getInt("id"))
+            .isEqualTo(id)
+    }
+
+    @Test
+    fun deepLinkQueryNullableParamArgumentMatchOnlyPartOfParam() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?myarg={myarg}L"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users"),
+            mapOf("myarg" to nullableStringArgument())
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the argument and it should be null")
+            .that(matchArgs?.getString("myarg"))
+            .isEqualTo("@null")
+    }
+
+    @Test
+    fun deepLinkQueryDefaultParamArgumentMatchOnlyPartOfParam() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?id={id}L"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = 2
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users"),
+            mapOf("id" to intArgument(id))
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the id")
+            .that(matchArgs?.getInt("id"))
+            .isEqualTo(id)
+    }
+
+    @Test
+    fun deepLinkQueryParamArgumentMatchMultiArgsOneParam() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?name={first}_{last}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val first = "Jane"
+        val last = "Doe"
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse(deepLinkArgument.replace("{first}", first).replace("{last}", last)),
+            mapOf("first" to stringArgument(),
+                "last" to stringArgument())
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the first name")
+            .that(matchArgs?.getString("first"))
+            .isEqualTo(first)
+        assertWithMessage("Args should contain the last name")
+            .that(matchArgs?.getString("last"))
+            .isEqualTo(last)
+    }
+
+    @Test
+    fun deepLinkQueryDefaultParamArgumentMatchMultiArgsOneParam() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?name={first}_{last}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val first = "Jane"
+        val last = "Doe"
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users"),
+            mapOf("first" to stringArgument(first),
+                "last" to stringArgument(last))
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the first name")
+            .that(matchArgs?.getString("first"))
+            .isEqualTo(first)
+        assertWithMessage("Args should contain the last name")
+            .that(matchArgs?.getString("last"))
+            .isEqualTo(last)
+    }
+
+    @Test
+    fun deepLinkQueryParamOneDefaultArgumentMatchMultiArgsOneParam() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?name={first}_{last}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val first = "Jane"
+        val last = "Doe"
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users?name=Jane_"),
+            mapOf("first" to stringArgument(),
+                "last" to stringArgument(last))
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the first name")
+            .that(matchArgs?.getString("first"))
+            .isEqualTo(first)
+        assertWithMessage("Args should contain the last name")
+            .that(matchArgs?.getString("last"))
+            .isEqualTo(last)
+    }
+
+    @Test
+    fun deepLinkQueryNullableParamArgumentMatchMultiArgsOneParam() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?name={first}_{last}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users"),
+            mapOf("first" to nullableStringArgument(),
+                "last" to nullableStringArgument())
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the first name")
+            .that(matchArgs?.getString("first"))
+            .isEqualTo("@null")
+        assertWithMessage("Args should contain the last name")
+            .that(matchArgs?.getString("last"))
+            .isEqualTo("@null")
+    }
+
+    @Test
+    fun deepLinkQueryParamArgumentWithWildCard() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?productId=.*-{id}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = 2
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users?productId=wildCardMatch-{id}"
+                .replace("{id}", id.toString())),
+            mapOf("id" to intArgument())
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the id")
+            .that(matchArgs?.getInt("id"))
+            .isEqualTo(id)
+    }
+
+    @Test
+    fun deepLinkQueryParamDefaultArgumentWithWildCard() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?productId=.*-{id}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = 2
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users"),
+            mapOf("id" to intArgument(id))
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the id")
+            .that(matchArgs?.getInt("id"))
+            .isEqualTo(id)
+    }
+
+    @Test
+    fun deepLinkQueryParamNullableArgumentWithWildCard() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?productId=.*-{myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users?productId=wildCardMatch-{myarg}"),
+            mapOf("myarg" to nullableStringArgument())
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain arg as null")
+            .that(matchArgs?.getString("myarg"))
+            .isEqualTo("@null")
+    }
+
+    // Handle the case were the input is wild card and separator with no argument
+    @Test
+    fun deepLinkQueryParamDefaultArgumentWithWildCardOnly() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?productId=.*-{id}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = 2
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users?productId=.*-"),
+            mapOf("id" to intArgument(id))
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the id")
+            .that(matchArgs?.getInt("id"))
+            .isEqualTo(id)
+    }
+
+    @Test
+    fun deepLinkQueryParamArgumentWithStarInFront() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?productId=A*B{id}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = 2
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users?productId=A*B{id}"
+                .replace("{id}", id.toString())),
+            mapOf("id" to intArgument())
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the id")
+            .that(matchArgs?.getInt("id"))
+            .isEqualTo(id)
+    }
+
+    @Test
+    fun deepLinkQueryParamArgumentWithStarInBack() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?productId={id}A*B"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val id = 2
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users?productId={id}A*B"
+                .replace("{id}", id.toString())),
+            mapOf("id" to intArgument())
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the id")
+            .that(matchArgs?.getInt("id"))
+            .isEqualTo(id)
+    }
+
+    @Test
+    fun deepLinkQueryParamArgumentWithRegex() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?path=go/to/{path}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val path = "directions"
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users?path=go/to/{path}".replace("{path}", path)),
+            mapOf("path" to stringArgument())
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the path")
+            .that(matchArgs?.getString("path"))
+            .isEqualTo(path)
+    }
+
+    @Test
+    fun deepLinkQueryParamDefaultArgumentWithRegex() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?path=go/to/{path}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val path = "directions"
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users"),
+            mapOf("path" to stringArgument(path))
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the path")
+            .that(matchArgs?.getString("path"))
+            .isEqualTo(path)
+    }
+
+    @Test
+    fun deepLinkQueryParamNullableArgumentWithRegex() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?path=go/to/{path}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users"),
+            mapOf("path" to nullableStringArgument())
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the path as null")
+            .that(matchArgs?.getString("path"))
+            .isEqualTo("@null")
+    }
+
+    // Handle the case were the input could be entire path except for the argument
+    @Test
+    fun deepLinkQueryParamDefaultArgumentWithRegexOnly() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?path=go/to/{path}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val path = "directions"
+        val matchArgs = deepLink.getMatchingArguments(
+            Uri.parse("$DEEP_LINK_EXACT_HTTPS/users?path=go/to/"),
+            mapOf("path" to stringArgument(path))
+        )
+        assertWithMessage("Args should not be null")
+            .that(matchArgs)
+            .isNotNull()
+        assertWithMessage("Args should contain the path")
+            .that(matchArgs?.getString("path"))
+            .isEqualTo(path)
+    }
+
+    @Test
     @Throws(UnsupportedEncodingException::class)
     fun deepLinkArgumentMatchEncoded() {
         val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users/{name}/posts"
@@ -161,7 +750,7 @@
         val name = "John Doe"
         val matchArgs = deepLink.getMatchingArguments(
             Uri.parse(deepLinkArgument.replace("{name}", Uri.encode(name))),
-            mapOf("name" to NavArgument.Builder().setType(NavType.StringType).build())
+            mapOf("name" to stringArgument())
         )
 
         assertWithMessage("Args should not be null")
@@ -183,8 +772,8 @@
             Uri.parse(deepLinkArgument
                 .replace("{id}", id.toString())
                 .replace("{postId}", postId.toString())),
-            mapOf("id" to NavArgument.Builder().setType(NavType.IntType).build(),
-                "postId" to NavArgument.Builder().setType(NavType.IntType).build())
+            mapOf("id" to intArgument(),
+                "postId" to intArgument())
         )
         assertWithMessage("Args should not be null")
             .that(matchArgs)
@@ -234,7 +823,7 @@
             Uri.parse(deepLinkMultiple
                 .replace(".*", "test")
                 .replace("{postId}", postId.toString())),
-            mapOf("postId" to NavArgument.Builder().setType(NavType.IntType).build())
+            mapOf("postId" to intArgument())
         )
         assertWithMessage("Args should not be null")
             .that(matchArgs)
@@ -254,7 +843,7 @@
             Uri.parse(deepLinkMultiple
                 .replace("{id}", id.toString())
                 .replace(".*", "test")),
-            mapOf("id" to NavArgument.Builder().setType(NavType.IntType).build())
+            mapOf("id" to intArgument())
         )
         assertWithMessage("Args should not be null")
             .that(matchArgs)
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDestinationAndroidTest.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDestinationAndroidTest.kt
index 0aab743..41bbc79 100644
--- a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDestinationAndroidTest.kt
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDestinationAndroidTest.kt
@@ -18,6 +18,8 @@
 
 import android.net.Uri
 import android.os.Bundle
+import androidx.navigation.test.intArgument
+import androidx.navigation.test.stringArgument
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
@@ -28,10 +30,7 @@
     @Test
     fun matchDeepLink() {
         val destination = NoOpNavigator().createDestination()
-        val idArgument = NavArgument.Builder()
-            .setType(NavType.IntType)
-            .build()
-        destination.addArgument("id", idArgument)
+        destination.addArgument("id", intArgument())
         destination.addDeepLink("www.example.com/users/{id}")
 
         val match = destination.matchDeepLink(
@@ -52,10 +51,7 @@
 
         destination.addDeepLink("www.example.com/users/index.html")
 
-        val idArgument = NavArgument.Builder()
-            .setType(NavType.StringType)
-            .build()
-        destination.addArgument("id", idArgument)
+        destination.addArgument("id", stringArgument())
         destination.addDeepLink("www.example.com/users/{name}")
 
         val match = destination.matchDeepLink(
@@ -89,16 +85,10 @@
     fun matchDeepLinkBestMatch() {
         val destination = NoOpNavigator().createDestination()
 
-        val idArgument = NavArgument.Builder()
-            .setType(NavType.IntType)
-            .build()
-        destination.addArgument("id", idArgument)
+        destination.addArgument("id", intArgument())
         destination.addDeepLink("www.example.com/users/{id}")
 
-        val postIdArgument = NavArgument.Builder()
-            .setType(NavType.IntType)
-            .build()
-        destination.addArgument("postId", postIdArgument)
+        destination.addArgument("postId", intArgument())
         destination.addDeepLink("www.example.com/users/{id}/posts/{postId}")
 
         val match = destination.matchDeepLink(
@@ -131,10 +121,7 @@
     @Test
     fun testIsValidDeepLinkValidLinkPattern() {
         val destination = NoOpNavigator().createDestination()
-        val stringArgument = NavArgument.Builder()
-            .setType(NavType.StringType)
-            .build()
-        destination.addArgument("testString", stringArgument)
+        destination.addArgument("testString", stringArgument())
         destination.addDeepLink("android-app://androidx.navigation.test/{testString}")
         val deepLink = Uri.parse("android-app://androidx.navigation.test/test")
         destination.addDeepLink(deepLink.toString())
@@ -156,16 +143,8 @@
     @Test
     fun addInDefaultArgs() {
         val destination = NoOpNavigator().createDestination()
-        val stringArgument = NavArgument.Builder()
-            .setType(NavType.StringType)
-            .setDefaultValue("aaa")
-            .build()
-        val intArgument = NavArgument.Builder()
-            .setType(NavType.IntType)
-            .setDefaultValue(123)
-            .build()
-        destination.addArgument("stringArg", stringArgument)
-        destination.addArgument("intArg", intArgument)
+        destination.addArgument("stringArg", stringArgument("aaa"))
+        destination.addArgument("intArg", intArgument(123))
 
         val bundle = destination.addInDefaultArgs(Bundle().apply {
             putString("stringArg", "bbb")
@@ -177,16 +156,8 @@
     @Test(expected = IllegalArgumentException::class)
     fun addInDefaultArgsWrong() {
         val destination = NoOpNavigator().createDestination()
-        val stringArgument = NavArgument.Builder()
-            .setType(NavType.StringType)
-            .setDefaultValue("aaa")
-            .build()
-        val intArgument = NavArgument.Builder()
-            .setType(NavType.IntType)
-            .setDefaultValue(123)
-            .build()
-        destination.addArgument("stringArg", stringArgument)
-        destination.addArgument("intArg", intArgument)
+        destination.addArgument("stringArg", stringArgument("aaa"))
+        destination.addArgument("intArg", intArgument(123))
 
         destination.addInDefaultArgs(Bundle().apply {
             putInt("stringArg", 123)
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/test/NavArgument.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/test/NavArgument.kt
new file mode 100644
index 0000000..1446431
--- /dev/null
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/test/NavArgument.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 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.navigation.test
+
+import androidx.navigation.NavArgument
+import androidx.navigation.NavType.IntType
+import androidx.navigation.NavType.StringType
+
+// region IntType
+fun intArgument() = NavArgument.Builder().setType(IntType).build()
+
+fun intArgument(
+    defaultValue: Int
+) = NavArgument.Builder().setType(IntType)
+    .setDefaultValue(defaultValue)
+    .build()
+// endregion
+
+// region StringType
+fun stringArgument(
+    isNullable: Boolean = false
+) = NavArgument.Builder().setType(StringType)
+    .setIsNullable(isNullable)
+    .build()
+
+fun stringArgument(
+    defaultValue: String
+) = NavArgument.Builder().setType(StringType)
+    .setDefaultValue(defaultValue)
+    .build()
+
+fun nullableStringArgument() = NavArgument.Builder().setType(StringType)
+    .setIsNullable(true)
+    .build()
+// endregion
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/NavDeepLink.java b/navigation/navigation-common/src/main/java/androidx/navigation/NavDeepLink.java
index 65846a0..9d4c939 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/NavDeepLink.java
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/NavDeepLink.java
@@ -23,6 +23,7 @@
 import androidx.annotation.Nullable;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -36,40 +37,75 @@
     private final ArrayList<String> mArguments = new ArrayList<>();
     private final Pattern mPattern;
     private final boolean mExactDeepLink;
+    private final boolean mIsParameterizedQuery;
+    private final Map<String, ParamQuery> mParamArgMap = new HashMap<>();
 
     /**
      * NavDestinations should be created via {@link Navigator#createDestination}.
      */
     NavDeepLink(@NonNull String uri) {
+        Uri parameterizedUri = Uri.parse(uri);
+        mIsParameterizedQuery = parameterizedUri.getQuery() != null;
         StringBuilder uriRegex = new StringBuilder("^");
 
         if (!SCHEME_PATTERN.matcher(uri).find()) {
             uriRegex.append("http[s]?://");
         }
         Pattern fillInPattern = Pattern.compile("\\{(.+?)\\}");
-        Matcher matcher = fillInPattern.matcher(uri);
-        int appendPos = 0;
-        // Track whether this is an exact deep link
-        boolean exactDeepLink = !uri.contains(".*");
-        while (matcher.find()) {
-            String argName = matcher.group(1);
-            mArguments.add(argName);
-            // Use Pattern.quote() to treat the input string as a literal
-            uriRegex.append(Pattern.quote(uri.substring(appendPos, matcher.start())));
-            uriRegex.append("(.+?)");
-            appendPos = matcher.end();
-            exactDeepLink = false;
-        }
-        if (appendPos < uri.length()) {
-            // Use Pattern.quote() to treat the input string as a literal
-            uriRegex.append(Pattern.quote(uri.substring(appendPos)));
+        if (mIsParameterizedQuery) {
+            Matcher matcher = Pattern.compile("(\\?)").matcher(uri);
+            if (matcher.find()) {
+                uriRegex.append(Pattern.quote(uri.substring(0, matcher.start())));
+                uriRegex.append("(.+)?");
+            }
+            mExactDeepLink = false;
+            for (String paramName : parameterizedUri.getQueryParameterNames()) {
+                StringBuilder argRegex = new StringBuilder();
+                String queryParam = parameterizedUri.getQueryParameter(paramName);
+                matcher = fillInPattern.matcher(queryParam);
+                int appendPos = 0;
+                ParamQuery param = new ParamQuery();
+                // Build the regex for each query param
+                while (matcher.find()) {
+                    param.addArgumentName(matcher.group(1));
+                    argRegex.append(Pattern.quote(queryParam.substring(appendPos,
+                            matcher.start())));
+                    argRegex.append("(.+?)?");
+                    appendPos = matcher.end();
+                }
+                if (appendPos < queryParam.length()) {
+                    argRegex.append(Pattern.quote(queryParam.substring(appendPos)));
+                }
+                // Save the regex with wildcards unquoted, and add the param to the map with its
+                // name as the key
+                param.setParamRegex(argRegex.toString().replace(".*", "\\E.*\\Q"));
+                mParamArgMap.put(paramName, param);
+            }
+        } else {
+            Matcher matcher = fillInPattern.matcher(uri);
+            int appendPos = 0;
+            // Track whether this is an exact deep link
+            boolean exactDeepLink = !uri.contains(".*");
+            while (matcher.find()) {
+                String argName = matcher.group(1);
+                mArguments.add(argName);
+                // Use Pattern.quote() to treat the input string as a literal
+                uriRegex.append(Pattern.quote(uri.substring(appendPos, matcher.start())));
+                uriRegex.append("(.+?)");
+                appendPos = matcher.end();
+                exactDeepLink = false;
+            }
+            if (appendPos < uri.length()) {
+                // Use Pattern.quote() to treat the input string as a literal
+                uriRegex.append(Pattern.quote(uri.substring(appendPos)));
+            }
+            mExactDeepLink = exactDeepLink;
         }
         // Since we've used Pattern.quote() above, we need to
         // specifically escape any .* instances to ensure
         // they are still treated as wildcards in our final regex
         String finalRegex = uriRegex.toString().replace(".*", "\\E.*\\Q");
         mPattern = Pattern.compile(finalRegex);
-        mExactDeepLink = exactDeepLink;
     }
 
     boolean matches(@NonNull Uri deepLink) {
@@ -88,25 +124,105 @@
             return null;
         }
         Bundle bundle = new Bundle();
-        int size = mArguments.size();
-        for (int index = 0; index < size; index++) {
-            String argumentName = mArguments.get(index);
-            String value = Uri.decode(matcher.group(index + 1));
-            NavArgument argument = arguments.get(argumentName);
-            if (argument != null) {
-                NavType type = argument.getType();
-                try {
-                    type.parseAndPut(bundle, argumentName, value);
-                } catch (IllegalArgumentException e) {
-                    // Failed to parse means this isn't a valid deep link
-                    // for the given URI - i.e., the URI contains a non-integer
-                    // value for an integer argument
+        if (mIsParameterizedQuery) {
+            // If there are query params that do not exists for this Deep Link we should throw
+            if (!mParamArgMap.keySet().containsAll(deepLink.getQueryParameterNames())) {
+                throw new IllegalArgumentException("Please ensure the given query parameters are a"
+                        + " subset of those in NavDeepLink " + this);
+            }
+            for (String paramName : mParamArgMap.keySet()) {
+                Matcher argMatcher = null;
+                ParamQuery storedParam = mParamArgMap.get(paramName);
+                String inputParams = deepLink.getQueryParameter(paramName);
+                if (inputParams != null) {
+                    // Match the input arguments with the saved regex
+                    argMatcher = Pattern.compile(storedParam.getParamRegex()).matcher(inputParams);
+                    if (!argMatcher.matches()) {
+                        return null;
+                    }
+                }
+                // Params could have multiple arguments, we need to handle them all
+                for (int index = 0; index < storedParam.size(); index++) {
+                    String value = null;
+                    if (argMatcher != null) {
+                        value = Uri.decode(argMatcher.group(index + 1));
+                    }
+                    String argName = storedParam.getArgumentName(index);
+                    NavArgument argument = arguments.get(argName);
+                    // Missing parameter so see if it has a default value or is Nullable
+                    if (argument != null
+                            && (value == null || value.replaceAll("[{}]", "").equals(argName))) {
+                        if (argument.getDefaultValue() != null) {
+                            value = argument.getDefaultValue().toString();
+                        } else if (argument.isNullable()) {
+                            value = "@null";
+                        }
+                    }
+                    if (parseArgument(bundle, argName, value, argument)) {
+                        return null;
+                    }
+                }
+            }
+        } else {
+            int size = mArguments.size();
+            for (int index = 0; index < size; index++) {
+                String argumentName = mArguments.get(index);
+                String value = Uri.decode(matcher.group(index + 1));
+                NavArgument argument = arguments.get(argumentName);
+                if (parseArgument(bundle, argumentName, value, argument)) {
                     return null;
                 }
-            } else {
-                bundle.putString(argumentName, value);
             }
         }
         return bundle;
     }
+
+    private boolean parseArgument(Bundle bundle, String name, String value, NavArgument argument) {
+        if (argument != null) {
+            NavType<?> type = argument.getType();
+            try {
+                type.parseAndPut(bundle, name, value);
+            } catch (IllegalArgumentException e) {
+                // Failed to parse means this isn't a valid deep link
+                // for the given URI - i.e., the URI contains a non-integer
+                // value for an integer argument
+                return true;
+            }
+        } else {
+            bundle.putString(name, value);
+        }
+        return false;
+    }
+
+    /**
+     * Used to maintain query parameters and the mArguments they match with.
+     */
+    private class ParamQuery {
+        private String mParamRegex;
+        private ArrayList<String> mArguments;
+
+        ParamQuery() {
+            mArguments = new ArrayList<>();
+        }
+
+        void setParamRegex(String paramRegex) {
+            this.mParamRegex = paramRegex;
+        }
+
+        String getParamRegex() {
+            return mParamRegex;
+        }
+
+        void addArgumentName(String name) {
+            mArguments.add(name);
+        }
+
+        String getArgumentName(int index) {
+            return mArguments.get(index);
+        }
+
+        public int size() {
+            return mArguments.size();
+        }
+    }
 }
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/NavDestination.java b/navigation/navigation-common/src/main/java/androidx/navigation/NavDestination.java
index 5e93b7a..4473455 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/NavDestination.java
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/NavDestination.java
@@ -161,6 +161,11 @@
      */
     @NonNull
     static String getDisplayName(@NonNull Context context, int id) {
+        // aapt-generated IDs have the high byte nonzero,
+        // so anything below that cannot be a valid resource id
+        if (id <= 0x00FFFFFF) {
+            return Integer.toString(id);
+        }
         try {
             return context.getResources().getResourceName(id);
         } catch (Resources.NotFoundException e) {
diff --git a/navigation/navigation-fragment-ktx/api/2.2.0-alpha02.txt b/navigation/navigation-fragment-ktx/api/2.2.0-alpha02.txt
new file mode 100644
index 0000000..3b93d62
--- /dev/null
+++ b/navigation/navigation-fragment-ktx/api/2.2.0-alpha02.txt
@@ -0,0 +1,51 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+  public final class NavGraphViewModelLazyKt {
+    ctor public NavGraphViewModelLazyKt();
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+  }
+
+}
+
+package androidx.navigation.fragment {
+
+  public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
+    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+    method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
+  }
+
+  public final class DialogFragmentNavigatorDestinationBuilderKt {
+    ctor public DialogFragmentNavigatorDestinationBuilderKt();
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id);
+    method 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,kotlin.Unit> builder);
+  }
+
+  public final class FragmentKt {
+    ctor public FragmentKt();
+    method public static androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment);
+  }
+
+  public final class FragmentNavArgsLazyKt {
+    ctor public FragmentNavArgsLazyKt();
+    method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args> navArgs(androidx.fragment.app.Fragment);
+  }
+
+  public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
+    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
+    method public androidx.navigation.fragment.FragmentNavigator.Destination build();
+  }
+
+  public final class FragmentNavigatorDestinationBuilderKt {
+    ctor public FragmentNavigatorDestinationBuilderKt();
+    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id);
+    method 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,kotlin.Unit> builder);
+  }
+
+  public final class FragmentNavigatorExtrasKt {
+    ctor public FragmentNavigatorExtrasKt();
+    method public static androidx.navigation.fragment.FragmentNavigator.Extras FragmentNavigatorExtras(kotlin.Pair<? extends android.view.View,java.lang.String>... sharedElements);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha02.txt b/navigation/navigation-fragment-ktx/api/res-2.2.0-alpha02.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha02.txt
copy to navigation/navigation-fragment-ktx/api/res-2.2.0-alpha02.txt
diff --git a/navigation/navigation-fragment-ktx/api/restricted_2.2.0-alpha02.txt b/navigation/navigation-fragment-ktx/api/restricted_2.2.0-alpha02.txt
new file mode 100644
index 0000000..3b93d62
--- /dev/null
+++ b/navigation/navigation-fragment-ktx/api/restricted_2.2.0-alpha02.txt
@@ -0,0 +1,51 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+  public final class NavGraphViewModelLazyKt {
+    ctor public NavGraphViewModelLazyKt();
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+  }
+
+}
+
+package androidx.navigation.fragment {
+
+  public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
+    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+    method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
+  }
+
+  public final class DialogFragmentNavigatorDestinationBuilderKt {
+    ctor public DialogFragmentNavigatorDestinationBuilderKt();
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id);
+    method 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,kotlin.Unit> builder);
+  }
+
+  public final class FragmentKt {
+    ctor public FragmentKt();
+    method public static androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment);
+  }
+
+  public final class FragmentNavArgsLazyKt {
+    ctor public FragmentNavArgsLazyKt();
+    method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args> navArgs(androidx.fragment.app.Fragment);
+  }
+
+  public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
+    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
+    method public androidx.navigation.fragment.FragmentNavigator.Destination build();
+  }
+
+  public final class FragmentNavigatorDestinationBuilderKt {
+    ctor public FragmentNavigatorDestinationBuilderKt();
+    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id);
+    method 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,kotlin.Unit> builder);
+  }
+
+  public final class FragmentNavigatorExtrasKt {
+    ctor public FragmentNavigatorExtrasKt();
+    method public static androidx.navigation.fragment.FragmentNavigator.Extras FragmentNavigatorExtras(kotlin.Pair<? extends android.view.View,java.lang.String>... sharedElements);
+  }
+
+}
+
diff --git a/navigation/navigation-fragment-ktx/src/main/java/androidx/navigation/NavGraphViewModelLazy.kt b/navigation/navigation-fragment-ktx/src/main/java/androidx/navigation/NavGraphViewModelLazy.kt
index 75e7122..51c7a2a 100644
--- a/navigation/navigation-fragment-ktx/src/main/java/androidx/navigation/NavGraphViewModelLazy.kt
+++ b/navigation/navigation-fragment-ktx/src/main/java/androidx/navigation/NavGraphViewModelLazy.kt
@@ -20,7 +20,6 @@
 import androidx.annotation.MainThread
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.createViewModelLazy
-import androidx.lifecycle.HasDefaultViewModelProviderFactory
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.ViewModelStore
@@ -39,7 +38,7 @@
  * factory returned by it will be used to create [ViewModel]:
  * ```
  * class MyFragment : Fragment() {
- *     val viewmodel: MainViewModel by navGraphViewModels(R.navigation.main) { myFactory }
+ *     val viewmodel: MainViewModel by navGraphViewModels(R.id.main) { myFactory }
  * }
  * ```
  *
@@ -53,14 +52,13 @@
     @IdRes navGraphId: Int,
     noinline factoryProducer: (() -> ViewModelProvider.Factory)? = null
 ): Lazy<VM> {
-    val viewModelStoreOwner by lazy {
-        findNavController().getViewModelStoreOwner(navGraphId)
+    val backStackEntry by lazy {
+        findNavController().getBackStackEntry(navGraphId)
     }
     val storeProducer: () -> ViewModelStore = {
-        viewModelStoreOwner.viewModelStore
+        backStackEntry.viewModelStore
     }
     return createViewModelLazy(VM::class, storeProducer, {
-        factoryProducer?.invoke() ?: (viewModelStoreOwner as HasDefaultViewModelProviderFactory)
-            .defaultViewModelProviderFactory
+        factoryProducer?.invoke() ?: backStackEntry.defaultViewModelProviderFactory
     })
 }
\ No newline at end of file
diff --git a/navigation/navigation-fragment/api/2.2.0-alpha02.txt b/navigation/navigation-fragment/api/2.2.0-alpha02.txt
new file mode 100644
index 0000000..fa67952
--- /dev/null
+++ b/navigation/navigation-fragment/api/2.2.0-alpha02.txt
@@ -0,0 +1,55 @@
+// Signature format: 3.0
+package androidx.navigation.fragment {
+
+  @androidx.navigation.Navigator.Name("dialog") public final class DialogFragmentNavigator extends androidx.navigation.Navigator<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
+    ctor public DialogFragmentNavigator(android.content.Context, androidx.fragment.app.FragmentManager);
+    method public androidx.navigation.fragment.DialogFragmentNavigator.Destination createDestination();
+    method public androidx.navigation.NavDestination? navigate(androidx.navigation.fragment.DialogFragmentNavigator.Destination, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+    method public boolean popBackStack();
+  }
+
+  @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.NavigatorProvider);
+    ctor public DialogFragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.DialogFragmentNavigator.Destination>);
+    method public final String getClassName();
+    method public final androidx.navigation.fragment.DialogFragmentNavigator.Destination setClassName(String);
+  }
+
+  @androidx.navigation.Navigator.Name("fragment") public class FragmentNavigator extends androidx.navigation.Navigator<androidx.navigation.fragment.FragmentNavigator.Destination> {
+    ctor public FragmentNavigator(android.content.Context, androidx.fragment.app.FragmentManager, int);
+    method public androidx.navigation.fragment.FragmentNavigator.Destination createDestination();
+    method @Deprecated public androidx.fragment.app.Fragment instantiateFragment(android.content.Context, androidx.fragment.app.FragmentManager, String, android.os.Bundle?);
+    method public androidx.navigation.NavDestination? navigate(androidx.navigation.fragment.FragmentNavigator.Destination, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+    method public boolean popBackStack();
+  }
+
+  @androidx.navigation.NavDestination.ClassType(Fragment.class) public static class FragmentNavigator.Destination extends androidx.navigation.NavDestination {
+    ctor public FragmentNavigator.Destination(androidx.navigation.NavigatorProvider);
+    ctor public FragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination>);
+    method public final String getClassName();
+    method public final androidx.navigation.fragment.FragmentNavigator.Destination setClassName(String);
+  }
+
+  public static final class FragmentNavigator.Extras implements androidx.navigation.Navigator.Extras {
+    method public java.util.Map<android.view.View!,java.lang.String!> getSharedElements();
+  }
+
+  public static final class FragmentNavigator.Extras.Builder {
+    ctor public FragmentNavigator.Extras.Builder();
+    method public androidx.navigation.fragment.FragmentNavigator.Extras.Builder addSharedElement(android.view.View, String);
+    method public androidx.navigation.fragment.FragmentNavigator.Extras.Builder addSharedElements(java.util.Map<android.view.View!,java.lang.String!>);
+    method public androidx.navigation.fragment.FragmentNavigator.Extras build();
+  }
+
+  public class NavHostFragment extends androidx.fragment.app.Fragment implements androidx.navigation.NavHost {
+    ctor public NavHostFragment();
+    method public static androidx.navigation.fragment.NavHostFragment create(@NavigationRes int);
+    method public static androidx.navigation.fragment.NavHostFragment create(@NavigationRes int, android.os.Bundle?);
+    method @Deprecated protected androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> createFragmentNavigator();
+    method public static androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment);
+    method public final androidx.navigation.NavController getNavController();
+    method @CallSuper protected void onCreateNavController(androidx.navigation.NavController);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha02.txt b/navigation/navigation-fragment/api/res-2.2.0-alpha02.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha02.txt
copy to navigation/navigation-fragment/api/res-2.2.0-alpha02.txt
diff --git a/navigation/navigation-fragment/api/restricted_2.2.0-alpha02.txt b/navigation/navigation-fragment/api/restricted_2.2.0-alpha02.txt
new file mode 100644
index 0000000..fa67952
--- /dev/null
+++ b/navigation/navigation-fragment/api/restricted_2.2.0-alpha02.txt
@@ -0,0 +1,55 @@
+// Signature format: 3.0
+package androidx.navigation.fragment {
+
+  @androidx.navigation.Navigator.Name("dialog") public final class DialogFragmentNavigator extends androidx.navigation.Navigator<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
+    ctor public DialogFragmentNavigator(android.content.Context, androidx.fragment.app.FragmentManager);
+    method public androidx.navigation.fragment.DialogFragmentNavigator.Destination createDestination();
+    method public androidx.navigation.NavDestination? navigate(androidx.navigation.fragment.DialogFragmentNavigator.Destination, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+    method public boolean popBackStack();
+  }
+
+  @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.NavigatorProvider);
+    ctor public DialogFragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.DialogFragmentNavigator.Destination>);
+    method public final String getClassName();
+    method public final androidx.navigation.fragment.DialogFragmentNavigator.Destination setClassName(String);
+  }
+
+  @androidx.navigation.Navigator.Name("fragment") public class FragmentNavigator extends androidx.navigation.Navigator<androidx.navigation.fragment.FragmentNavigator.Destination> {
+    ctor public FragmentNavigator(android.content.Context, androidx.fragment.app.FragmentManager, int);
+    method public androidx.navigation.fragment.FragmentNavigator.Destination createDestination();
+    method @Deprecated public androidx.fragment.app.Fragment instantiateFragment(android.content.Context, androidx.fragment.app.FragmentManager, String, android.os.Bundle?);
+    method public androidx.navigation.NavDestination? navigate(androidx.navigation.fragment.FragmentNavigator.Destination, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+    method public boolean popBackStack();
+  }
+
+  @androidx.navigation.NavDestination.ClassType(Fragment.class) public static class FragmentNavigator.Destination extends androidx.navigation.NavDestination {
+    ctor public FragmentNavigator.Destination(androidx.navigation.NavigatorProvider);
+    ctor public FragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination>);
+    method public final String getClassName();
+    method public final androidx.navigation.fragment.FragmentNavigator.Destination setClassName(String);
+  }
+
+  public static final class FragmentNavigator.Extras implements androidx.navigation.Navigator.Extras {
+    method public java.util.Map<android.view.View!,java.lang.String!> getSharedElements();
+  }
+
+  public static final class FragmentNavigator.Extras.Builder {
+    ctor public FragmentNavigator.Extras.Builder();
+    method public androidx.navigation.fragment.FragmentNavigator.Extras.Builder addSharedElement(android.view.View, String);
+    method public androidx.navigation.fragment.FragmentNavigator.Extras.Builder addSharedElements(java.util.Map<android.view.View!,java.lang.String!>);
+    method public androidx.navigation.fragment.FragmentNavigator.Extras build();
+  }
+
+  public class NavHostFragment extends androidx.fragment.app.Fragment implements androidx.navigation.NavHost {
+    ctor public NavHostFragment();
+    method public static androidx.navigation.fragment.NavHostFragment create(@NavigationRes int);
+    method public static androidx.navigation.fragment.NavHostFragment create(@NavigationRes int, android.os.Bundle?);
+    method @Deprecated protected androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> createFragmentNavigator();
+    method public static androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment);
+    method public final androidx.navigation.NavController getNavController();
+    method @CallSuper protected void onCreateNavController(androidx.navigation.NavController);
+  }
+
+}
+
diff --git a/navigation/navigation-runtime-ktx/api/2.2.0-alpha02.txt b/navigation/navigation-runtime-ktx/api/2.2.0-alpha02.txt
new file mode 100644
index 0000000..fa3dc07
--- /dev/null
+++ b/navigation/navigation-runtime-ktx/api/2.2.0-alpha02.txt
@@ -0,0 +1,60 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+  public final class ActivityKt {
+    ctor public ActivityKt();
+    method public static androidx.navigation.NavController findNavController(android.app.Activity, @IdRes int viewId);
+  }
+
+  public final class ActivityNavArgsLazyKt {
+    ctor public ActivityNavArgsLazyKt();
+    method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args> navArgs(android.app.Activity);
+  }
+
+  public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
+    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
+    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? p);
+    method public void setActivityClass(kotlin.reflect.KClass<? extends android.app.Activity>? p);
+    method public void setData(android.net.Uri? p);
+    method public void setDataPattern(String? p);
+    method public void setTargetPackage(String? p);
+    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 {
+    ctor public ActivityNavigatorDestinationBuilderKt();
+    method public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+  }
+
+  public final class ActivityNavigatorExtrasKt {
+    ctor public ActivityNavigatorExtrasKt();
+    method public static androidx.navigation.ActivityNavigator.Extras ActivityNavigatorExtras(androidx.core.app.ActivityOptionsCompat? activityOptions = null, int flags = 0);
+  }
+
+  public final class NavControllerKt {
+    ctor public NavControllerKt();
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, @IdRes int id = 0, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public final class NavHostKt {
+    ctor public NavHostKt();
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, @IdRes int id = 0, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public final class ViewKt {
+    ctor public ViewKt();
+    method public static androidx.navigation.NavController findNavController(android.view.View);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha02.txt b/navigation/navigation-runtime-ktx/api/res-2.2.0-alpha02.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha02.txt
copy to navigation/navigation-runtime-ktx/api/res-2.2.0-alpha02.txt
diff --git a/navigation/navigation-runtime-ktx/api/restricted_2.2.0-alpha02.txt b/navigation/navigation-runtime-ktx/api/restricted_2.2.0-alpha02.txt
new file mode 100644
index 0000000..fa3dc07
--- /dev/null
+++ b/navigation/navigation-runtime-ktx/api/restricted_2.2.0-alpha02.txt
@@ -0,0 +1,60 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+  public final class ActivityKt {
+    ctor public ActivityKt();
+    method public static androidx.navigation.NavController findNavController(android.app.Activity, @IdRes int viewId);
+  }
+
+  public final class ActivityNavArgsLazyKt {
+    ctor public ActivityNavArgsLazyKt();
+    method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args> navArgs(android.app.Activity);
+  }
+
+  public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
+    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
+    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? p);
+    method public void setActivityClass(kotlin.reflect.KClass<? extends android.app.Activity>? p);
+    method public void setData(android.net.Uri? p);
+    method public void setDataPattern(String? p);
+    method public void setTargetPackage(String? p);
+    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 {
+    ctor public ActivityNavigatorDestinationBuilderKt();
+    method public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+  }
+
+  public final class ActivityNavigatorExtrasKt {
+    ctor public ActivityNavigatorExtrasKt();
+    method public static androidx.navigation.ActivityNavigator.Extras ActivityNavigatorExtras(androidx.core.app.ActivityOptionsCompat? activityOptions = null, int flags = 0);
+  }
+
+  public final class NavControllerKt {
+    ctor public NavControllerKt();
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, @IdRes int id = 0, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public final class NavHostKt {
+    ctor public NavHostKt();
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, @IdRes int id = 0, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public final class ViewKt {
+    ctor public ViewKt();
+    method public static androidx.navigation.NavController findNavController(android.view.View);
+  }
+
+}
+
diff --git a/navigation/navigation-runtime/api/2.2.0-alpha02.ignore b/navigation/navigation-runtime/api/2.2.0-alpha02.ignore
new file mode 100644
index 0000000..1ca5fd9
--- /dev/null
+++ b/navigation/navigation-runtime/api/2.2.0-alpha02.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+RemovedDeprecatedMethod: androidx.navigation.NavController#getViewModelStore(int):
+    Removed deprecated method androidx.navigation.NavController.getViewModelStore(int)
diff --git a/navigation/navigation-runtime/api/2.2.0-alpha02.txt b/navigation/navigation-runtime/api/2.2.0-alpha02.txt
new file mode 100644
index 0000000..a62443f
--- /dev/null
+++ b/navigation/navigation-runtime/api/2.2.0-alpha02.txt
@@ -0,0 +1,127 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+  @androidx.navigation.Navigator.Name("activity") public class ActivityNavigator extends androidx.navigation.Navigator<androidx.navigation.ActivityNavigator.Destination> {
+    ctor public ActivityNavigator(android.content.Context);
+    method public static void applyPopAnimationsToPendingTransition(android.app.Activity);
+    method public androidx.navigation.ActivityNavigator.Destination createDestination();
+    method public androidx.navigation.NavDestination? navigate(androidx.navigation.ActivityNavigator.Destination, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+    method public boolean popBackStack();
+  }
+
+  @androidx.navigation.NavDestination.ClassType(Activity.class) public static class ActivityNavigator.Destination extends androidx.navigation.NavDestination {
+    ctor public ActivityNavigator.Destination(androidx.navigation.NavigatorProvider);
+    ctor public ActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination>);
+    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?);
+    method public final androidx.navigation.ActivityNavigator.Destination setComponentName(android.content.ComponentName?);
+    method public final androidx.navigation.ActivityNavigator.Destination setData(android.net.Uri?);
+    method public final androidx.navigation.ActivityNavigator.Destination setDataPattern(String?);
+    method public final androidx.navigation.ActivityNavigator.Destination setIntent(android.content.Intent?);
+    method public final androidx.navigation.ActivityNavigator.Destination setTargetPackage(String?);
+  }
+
+  public static final class ActivityNavigator.Extras implements androidx.navigation.Navigator.Extras {
+    method public androidx.core.app.ActivityOptionsCompat? getActivityOptions();
+    method public int getFlags();
+  }
+
+  public static final class ActivityNavigator.Extras.Builder {
+    ctor public ActivityNavigator.Extras.Builder();
+    method public androidx.navigation.ActivityNavigator.Extras.Builder addFlags(int);
+    method public androidx.navigation.ActivityNavigator.Extras build();
+    method public androidx.navigation.ActivityNavigator.Extras.Builder setActivityOptions(androidx.core.app.ActivityOptionsCompat);
+  }
+
+  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 androidx.lifecycle.Lifecycle getLifecycle();
+    method public androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+  }
+
+  public class NavController {
+    ctor public NavController(android.content.Context);
+    method public void addOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener);
+    method public androidx.navigation.NavDeepLinkBuilder createDeepLink();
+    method public androidx.navigation.NavBackStackEntry getBackStackEntry(@IdRes int);
+    method public androidx.navigation.NavDestination? getCurrentDestination();
+    method public androidx.navigation.NavGraph getGraph();
+    method public androidx.navigation.NavInflater getNavInflater();
+    method public androidx.navigation.NavigatorProvider getNavigatorProvider();
+    method public androidx.lifecycle.ViewModelStoreOwner getViewModelStoreOwner(@IdRes int);
+    method public boolean handleDeepLink(android.content.Intent?);
+    method public void navigate(@IdRes int);
+    method public void navigate(@IdRes int, android.os.Bundle?);
+    method public void navigate(@IdRes int, android.os.Bundle?, androidx.navigation.NavOptions?);
+    method public void navigate(@IdRes int, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+    method public void navigate(android.net.Uri);
+    method public void navigate(android.net.Uri, androidx.navigation.NavOptions?);
+    method public void navigate(android.net.Uri, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+    method public void navigate(androidx.navigation.NavDirections);
+    method public void navigate(androidx.navigation.NavDirections, androidx.navigation.NavOptions?);
+    method public void navigate(androidx.navigation.NavDirections, androidx.navigation.Navigator.Extras);
+    method public boolean navigateUp();
+    method public boolean popBackStack();
+    method public boolean popBackStack(@IdRes int, boolean);
+    method public void removeOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener);
+    method @CallSuper public void restoreState(android.os.Bundle?);
+    method @CallSuper public android.os.Bundle? saveState();
+    method @CallSuper public void setGraph(@NavigationRes int);
+    method @CallSuper public void setGraph(@NavigationRes int, android.os.Bundle?);
+    method @CallSuper public void setGraph(androidx.navigation.NavGraph);
+    method @CallSuper public void setGraph(androidx.navigation.NavGraph, android.os.Bundle?);
+    field public static final String KEY_DEEP_LINK_INTENT = "android-support-nav:controller:deepLinkIntent";
+  }
+
+  public static interface NavController.OnDestinationChangedListener {
+    method public void onDestinationChanged(androidx.navigation.NavController, androidx.navigation.NavDestination, android.os.Bundle?);
+  }
+
+  public final class NavDeepLinkBuilder {
+    ctor public NavDeepLinkBuilder(android.content.Context);
+    method public android.app.PendingIntent createPendingIntent();
+    method public androidx.core.app.TaskStackBuilder createTaskStackBuilder();
+    method public androidx.navigation.NavDeepLinkBuilder setArguments(android.os.Bundle?);
+    method public androidx.navigation.NavDeepLinkBuilder setComponentName(Class<? extends android.app.Activity>);
+    method public androidx.navigation.NavDeepLinkBuilder setComponentName(android.content.ComponentName);
+    method public androidx.navigation.NavDeepLinkBuilder setDestination(@IdRes int);
+    method public androidx.navigation.NavDeepLinkBuilder setGraph(@NavigationRes int);
+    method public androidx.navigation.NavDeepLinkBuilder setGraph(androidx.navigation.NavGraph);
+  }
+
+  public interface NavHost {
+    method public androidx.navigation.NavController getNavController();
+  }
+
+  public final class NavHostController extends androidx.navigation.NavController {
+    ctor public NavHostController(android.content.Context);
+    method public void enableOnBackPressed(boolean);
+    method public void setLifecycleOwner(androidx.lifecycle.LifecycleOwner);
+    method public void setOnBackPressedDispatcher(androidx.activity.OnBackPressedDispatcher);
+    method public void setViewModelStore(androidx.lifecycle.ViewModelStore);
+  }
+
+  public final class NavInflater {
+    ctor public NavInflater(android.content.Context, androidx.navigation.NavigatorProvider);
+    method public androidx.navigation.NavGraph inflate(@NavigationRes int);
+  }
+
+  public final class Navigation {
+    method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int);
+    method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int, android.os.Bundle?);
+    method public static android.view.View.OnClickListener createNavigateOnClickListener(androidx.navigation.NavDirections);
+    method public static androidx.navigation.NavController findNavController(android.app.Activity, @IdRes int);
+    method public static androidx.navigation.NavController findNavController(android.view.View);
+    method public static void setViewNavController(android.view.View, androidx.navigation.NavController?);
+  }
+
+}
+
diff --git a/navigation/navigation-runtime/api/current.txt b/navigation/navigation-runtime/api/current.txt
index 5db4937..a62443f 100644
--- a/navigation/navigation-runtime/api/current.txt
+++ b/navigation/navigation-runtime/api/current.txt
@@ -38,10 +38,20 @@
     method public androidx.navigation.ActivityNavigator.Extras.Builder setActivityOptions(androidx.core.app.ActivityOptionsCompat);
   }
 
+  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 androidx.lifecycle.Lifecycle getLifecycle();
+    method public androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+  }
+
   public class NavController {
     ctor public NavController(android.content.Context);
     method public void addOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener);
     method public androidx.navigation.NavDeepLinkBuilder createDeepLink();
+    method public androidx.navigation.NavBackStackEntry getBackStackEntry(@IdRes int);
     method public androidx.navigation.NavDestination? getCurrentDestination();
     method public androidx.navigation.NavGraph getGraph();
     method public androidx.navigation.NavInflater getNavInflater();
diff --git a/preference/ktx/api/res-1.1.0-alpha02.txt b/navigation/navigation-runtime/api/res-2.2.0-alpha02.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha02.txt
copy to navigation/navigation-runtime/api/res-2.2.0-alpha02.txt
diff --git a/navigation/navigation-runtime/api/restricted_2.2.0-alpha02.ignore b/navigation/navigation-runtime/api/restricted_2.2.0-alpha02.ignore
new file mode 100644
index 0000000..1ca5fd9
--- /dev/null
+++ b/navigation/navigation-runtime/api/restricted_2.2.0-alpha02.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+RemovedDeprecatedMethod: androidx.navigation.NavController#getViewModelStore(int):
+    Removed deprecated method androidx.navigation.NavController.getViewModelStore(int)
diff --git a/navigation/navigation-runtime/api/restricted_2.2.0-alpha02.txt b/navigation/navigation-runtime/api/restricted_2.2.0-alpha02.txt
new file mode 100644
index 0000000..a62443f
--- /dev/null
+++ b/navigation/navigation-runtime/api/restricted_2.2.0-alpha02.txt
@@ -0,0 +1,127 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+  @androidx.navigation.Navigator.Name("activity") public class ActivityNavigator extends androidx.navigation.Navigator<androidx.navigation.ActivityNavigator.Destination> {
+    ctor public ActivityNavigator(android.content.Context);
+    method public static void applyPopAnimationsToPendingTransition(android.app.Activity);
+    method public androidx.navigation.ActivityNavigator.Destination createDestination();
+    method public androidx.navigation.NavDestination? navigate(androidx.navigation.ActivityNavigator.Destination, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+    method public boolean popBackStack();
+  }
+
+  @androidx.navigation.NavDestination.ClassType(Activity.class) public static class ActivityNavigator.Destination extends androidx.navigation.NavDestination {
+    ctor public ActivityNavigator.Destination(androidx.navigation.NavigatorProvider);
+    ctor public ActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination>);
+    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?);
+    method public final androidx.navigation.ActivityNavigator.Destination setComponentName(android.content.ComponentName?);
+    method public final androidx.navigation.ActivityNavigator.Destination setData(android.net.Uri?);
+    method public final androidx.navigation.ActivityNavigator.Destination setDataPattern(String?);
+    method public final androidx.navigation.ActivityNavigator.Destination setIntent(android.content.Intent?);
+    method public final androidx.navigation.ActivityNavigator.Destination setTargetPackage(String?);
+  }
+
+  public static final class ActivityNavigator.Extras implements androidx.navigation.Navigator.Extras {
+    method public androidx.core.app.ActivityOptionsCompat? getActivityOptions();
+    method public int getFlags();
+  }
+
+  public static final class ActivityNavigator.Extras.Builder {
+    ctor public ActivityNavigator.Extras.Builder();
+    method public androidx.navigation.ActivityNavigator.Extras.Builder addFlags(int);
+    method public androidx.navigation.ActivityNavigator.Extras build();
+    method public androidx.navigation.ActivityNavigator.Extras.Builder setActivityOptions(androidx.core.app.ActivityOptionsCompat);
+  }
+
+  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 androidx.lifecycle.Lifecycle getLifecycle();
+    method public androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+  }
+
+  public class NavController {
+    ctor public NavController(android.content.Context);
+    method public void addOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener);
+    method public androidx.navigation.NavDeepLinkBuilder createDeepLink();
+    method public androidx.navigation.NavBackStackEntry getBackStackEntry(@IdRes int);
+    method public androidx.navigation.NavDestination? getCurrentDestination();
+    method public androidx.navigation.NavGraph getGraph();
+    method public androidx.navigation.NavInflater getNavInflater();
+    method public androidx.navigation.NavigatorProvider getNavigatorProvider();
+    method public androidx.lifecycle.ViewModelStoreOwner getViewModelStoreOwner(@IdRes int);
+    method public boolean handleDeepLink(android.content.Intent?);
+    method public void navigate(@IdRes int);
+    method public void navigate(@IdRes int, android.os.Bundle?);
+    method public void navigate(@IdRes int, android.os.Bundle?, androidx.navigation.NavOptions?);
+    method public void navigate(@IdRes int, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+    method public void navigate(android.net.Uri);
+    method public void navigate(android.net.Uri, androidx.navigation.NavOptions?);
+    method public void navigate(android.net.Uri, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+    method public void navigate(androidx.navigation.NavDirections);
+    method public void navigate(androidx.navigation.NavDirections, androidx.navigation.NavOptions?);
+    method public void navigate(androidx.navigation.NavDirections, androidx.navigation.Navigator.Extras);
+    method public boolean navigateUp();
+    method public boolean popBackStack();
+    method public boolean popBackStack(@IdRes int, boolean);
+    method public void removeOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener);
+    method @CallSuper public void restoreState(android.os.Bundle?);
+    method @CallSuper public android.os.Bundle? saveState();
+    method @CallSuper public void setGraph(@NavigationRes int);
+    method @CallSuper public void setGraph(@NavigationRes int, android.os.Bundle?);
+    method @CallSuper public void setGraph(androidx.navigation.NavGraph);
+    method @CallSuper public void setGraph(androidx.navigation.NavGraph, android.os.Bundle?);
+    field public static final String KEY_DEEP_LINK_INTENT = "android-support-nav:controller:deepLinkIntent";
+  }
+
+  public static interface NavController.OnDestinationChangedListener {
+    method public void onDestinationChanged(androidx.navigation.NavController, androidx.navigation.NavDestination, android.os.Bundle?);
+  }
+
+  public final class NavDeepLinkBuilder {
+    ctor public NavDeepLinkBuilder(android.content.Context);
+    method public android.app.PendingIntent createPendingIntent();
+    method public androidx.core.app.TaskStackBuilder createTaskStackBuilder();
+    method public androidx.navigation.NavDeepLinkBuilder setArguments(android.os.Bundle?);
+    method public androidx.navigation.NavDeepLinkBuilder setComponentName(Class<? extends android.app.Activity>);
+    method public androidx.navigation.NavDeepLinkBuilder setComponentName(android.content.ComponentName);
+    method public androidx.navigation.NavDeepLinkBuilder setDestination(@IdRes int);
+    method public androidx.navigation.NavDeepLinkBuilder setGraph(@NavigationRes int);
+    method public androidx.navigation.NavDeepLinkBuilder setGraph(androidx.navigation.NavGraph);
+  }
+
+  public interface NavHost {
+    method public androidx.navigation.NavController getNavController();
+  }
+
+  public final class NavHostController extends androidx.navigation.NavController {
+    ctor public NavHostController(android.content.Context);
+    method public void enableOnBackPressed(boolean);
+    method public void setLifecycleOwner(androidx.lifecycle.LifecycleOwner);
+    method public void setOnBackPressedDispatcher(androidx.activity.OnBackPressedDispatcher);
+    method public void setViewModelStore(androidx.lifecycle.ViewModelStore);
+  }
+
+  public final class NavInflater {
+    ctor public NavInflater(android.content.Context, androidx.navigation.NavigatorProvider);
+    method public androidx.navigation.NavGraph inflate(@NavigationRes int);
+  }
+
+  public final class Navigation {
+    method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int);
+    method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int, android.os.Bundle?);
+    method public static android.view.View.OnClickListener createNavigateOnClickListener(androidx.navigation.NavDirections);
+    method public static androidx.navigation.NavController findNavController(android.app.Activity, @IdRes int);
+    method public static androidx.navigation.NavController findNavController(android.view.View);
+    method public static void setViewNavController(android.view.View, androidx.navigation.NavController?);
+  }
+
+}
+
diff --git a/navigation/navigation-runtime/api/restricted_current.txt b/navigation/navigation-runtime/api/restricted_current.txt
index 5db4937..a62443f 100644
--- a/navigation/navigation-runtime/api/restricted_current.txt
+++ b/navigation/navigation-runtime/api/restricted_current.txt
@@ -38,10 +38,20 @@
     method public androidx.navigation.ActivityNavigator.Extras.Builder setActivityOptions(androidx.core.app.ActivityOptionsCompat);
   }
 
+  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 androidx.lifecycle.Lifecycle getLifecycle();
+    method public androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+  }
+
   public class NavController {
     ctor public NavController(android.content.Context);
     method public void addOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener);
     method public androidx.navigation.NavDeepLinkBuilder createDeepLink();
+    method public androidx.navigation.NavBackStackEntry getBackStackEntry(@IdRes int);
     method public androidx.navigation.NavDestination? getCurrentDestination();
     method public androidx.navigation.NavGraph getGraph();
     method public androidx.navigation.NavInflater getNavInflater();
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/FloatingWindowTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/FloatingWindowTest.kt
index 7baf710..ae5b762a 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/FloatingWindowTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/FloatingWindowTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.navigation
 
+import androidx.navigation.test.FloatingTestNavigator
 import androidx.navigation.test.R
 import androidx.navigation.testing.TestNavigator
 import androidx.test.core.app.ApplicationProvider
@@ -110,12 +111,3 @@
         return navController
     }
 }
-
-@Navigator.Name("dialog")
-class FloatingTestNavigator : TestNavigator() {
-    override fun createDestination(): Destination {
-        return FloatingDestination(this)
-    }
-
-    class FloatingDestination(navigator: TestNavigator) : Destination(navigator), FloatingWindow
-}
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryLifecycleTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryLifecycleTest.kt
new file mode 100644
index 0000000..88847fa
--- /dev/null
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryLifecycleTest.kt
@@ -0,0 +1,597 @@
+/*
+ * Copyright 2019 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.navigation
+
+import android.net.Uri
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleEventObserver
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.LifecycleRegistry
+import androidx.navigation.test.FloatingTestNavigator
+import androidx.navigation.test.R
+import androidx.navigation.test.dialog
+import androidx.navigation.testing.TestNavigator
+import androidx.navigation.testing.test
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.inOrder
+import org.mockito.Mockito.mock
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class NavBackStackEntryLifecycleTest {
+
+    /**
+     * Test that navigating between siblings correctly stops the previous sibling.
+     */
+    @Test
+    fun testLifecycle() {
+        val navController = createNavController()
+        val navGraph = navController.navigatorProvider.navigation(
+            id = 1,
+            startDestination = R.id.start_test
+        ) {
+            test(R.id.start_test)
+            test(R.id.second_test)
+        }
+        navController.graph = navGraph
+
+        val graphBackStackEntry = navController.getBackStackEntry(navGraph.id)
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        val startBackStackEntry = navController.getBackStackEntry(R.id.start_test)
+        assertWithMessage("The start destination should be resumed")
+            .that(startBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+
+        navController.navigate(R.id.second_test)
+
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The start destination should be set back to created after you navigate")
+            .that(startBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.CREATED)
+        val secondBackStackEntry = navController.getBackStackEntry(R.id.second_test)
+        assertWithMessage("The new destination should be resumed")
+            .that(secondBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+
+        navController.popBackStack()
+
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The start destination should be resumed after pop")
+            .that(startBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The popped destination should be destroyed")
+            .that(secondBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.DESTROYED)
+
+        // Pop the last destination off the stack
+        navController.popBackStack()
+
+        assertWithMessage("The parent graph should be destroyed after pop")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.DESTROYED)
+        assertWithMessage("The start destination should be destroyed after pop")
+            .that(startBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.DESTROYED)
+    }
+
+    /**
+     * Test that navigating from a sibling to a FloatingWindow sibling leaves the previous
+     * destination started.
+     */
+    @Test
+    fun testLifecycleWithDialog() {
+        val navController = createNavController()
+        val navGraph = navController.navigatorProvider.navigation(
+            id = 1,
+            startDestination = R.id.start_test
+        ) {
+            test(R.id.start_test)
+            dialog(R.id.second_test)
+        }
+        navController.graph = navGraph
+
+        val graphBackStackEntry = navController.getBackStackEntry(navGraph.id)
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        val startBackStackEntry = navController.getBackStackEntry(R.id.start_test)
+        assertWithMessage("The start destination should be resumed")
+            .that(startBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+
+        navController.navigate(R.id.second_test)
+
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The start destination should be started when a FloatingWindow is open")
+            .that(startBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.STARTED)
+        val secondBackStackEntry = navController.getBackStackEntry(R.id.second_test)
+        assertWithMessage("The new destination should be resumed")
+            .that(secondBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+
+        navController.popBackStack()
+
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The start destination should be resumed after pop")
+            .that(startBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The popped destination should be destroyed")
+            .that(secondBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.DESTROYED)
+
+        // Pop the last destination off the stack
+        navController.popBackStack()
+
+        assertWithMessage("The parent graph should be destroyed after pop")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.DESTROYED)
+        assertWithMessage("The start destination should be destroyed after pop")
+            .that(startBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.DESTROYED)
+    }
+
+    /**
+     * Test that navigating from within a nested navigation graph to one of the graph's
+     * siblings correctly stops both the previous destination and its graph.
+     */
+    @Test
+    fun testLifecycleNested() {
+        val navController = createNavController()
+        val navGraph = navController.navigatorProvider.navigation(
+            id = 1,
+            startDestination = R.id.nested
+        ) {
+            navigation(id = R.id.nested, startDestination = R.id.nested_test) {
+                test(R.id.nested_test)
+            }
+            test(R.id.second_test)
+        }
+        navController.graph = navGraph
+
+        val graphBackStackEntry = navController.getBackStackEntry(navGraph.id)
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        val nestedGraphBackStackEntry = navController.getBackStackEntry(R.id.nested)
+        assertWithMessage("The nested graph should be resumed when its child is resumed")
+            .that(nestedGraphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        val nestedBackStackEntry = navController.getBackStackEntry(R.id.nested_test)
+        assertWithMessage("The nested start destination should be resumed")
+            .that(nestedBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+
+        navController.navigate(R.id.second_test)
+
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The nested graph should be stopped when its children are stopped")
+            .that(nestedGraphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.CREATED)
+        assertWithMessage("The nested start destination should be stopped after navigate")
+            .that(nestedBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.CREATED)
+        val secondBackStackEntry = navController.getBackStackEntry(R.id.second_test)
+        assertWithMessage("The new destination should be resumed")
+            .that(secondBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+
+        navController.popBackStack()
+
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The nested graph should be resumed when its child is resumed")
+            .that(nestedGraphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The nested start destination should be resumed after pop")
+            .that(nestedBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The popped destination should be destroyed")
+            .that(secondBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.DESTROYED)
+    }
+
+    /**
+     * Test that navigating from within a nested navigation graph to one of the graph's
+     * FloatingWindow siblings correctly moves both the previous destination and its graph to
+     * started.
+     */
+    @Test
+    fun testLifecycleNestedWithDialog() {
+        val navController = createNavController()
+        val navGraph = navController.navigatorProvider.navigation(
+            id = 1,
+            startDestination = R.id.nested
+        ) {
+            navigation(id = R.id.nested, startDestination = R.id.nested_test) {
+                test(R.id.nested_test)
+            }
+            dialog(R.id.second_test)
+        }
+        navController.graph = navGraph
+
+        val graphBackStackEntry = navController.getBackStackEntry(navGraph.id)
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        val nestedGraphBackStackEntry = navController.getBackStackEntry(R.id.nested)
+        assertWithMessage("The nested graph should be resumed when its child is resumed")
+            .that(nestedGraphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        val nestedBackStackEntry = navController.getBackStackEntry(R.id.nested_test)
+        assertWithMessage("The nested start destination should be resumed")
+            .that(nestedBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+
+        navController.navigate(R.id.second_test)
+
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The nested graph should be started when its children are started")
+            .that(nestedGraphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.STARTED)
+        assertWithMessage("The nested start destination should be started when a " +
+                "FloatingWindow is open")
+            .that(nestedBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.STARTED)
+        val secondBackStackEntry = navController.getBackStackEntry(R.id.second_test)
+        assertWithMessage("The new destination should be resumed")
+            .that(secondBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+
+        navController.popBackStack()
+
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The nested graph should be resumed when its child is resumed")
+            .that(nestedGraphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The nested start destination should be resumed after pop")
+            .that(nestedBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The popped destination should be destroyed")
+            .that(secondBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.DESTROYED)
+    }
+
+    /**
+     * Test that navigating from within a nested navigation graph to one of the graph's
+     * siblings correctly stops both the previous destination and its graph.
+     */
+    @Test
+    fun testLifecycleNestedOrdering() {
+        val navController = createNavController()
+        val navGraph = navController.navigatorProvider.navigation(
+            id = 1,
+            startDestination = R.id.nested
+        ) {
+            navigation(id = R.id.nested, startDestination = R.id.nested_test) {
+                test(R.id.nested_test)
+            }
+            test(R.id.second_test)
+        }
+        navController.graph = navGraph
+
+        val graphBackStackEntry = navController.getBackStackEntry(navGraph.id)
+        val graphObserver = mock(LifecycleEventObserver::class.java)
+        graphBackStackEntry.lifecycle.addObserver(graphObserver)
+        val nestedGraphBackStackEntry = navController.getBackStackEntry(R.id.nested)
+        val nestedGraphObserver = mock(LifecycleEventObserver::class.java)
+        nestedGraphBackStackEntry.lifecycle.addObserver(nestedGraphObserver)
+        val nestedBackStackEntry = navController.getBackStackEntry(R.id.nested_test)
+        val nestedObserver = mock(LifecycleEventObserver::class.java)
+        nestedBackStackEntry.lifecycle.addObserver(nestedObserver)
+        val inOrder = inOrder(graphObserver, nestedGraphObserver, nestedObserver)
+        inOrder.verify(graphObserver).onStateChanged(
+            graphBackStackEntry, Lifecycle.Event.ON_CREATE)
+        inOrder.verify(graphObserver).onStateChanged(
+            graphBackStackEntry, Lifecycle.Event.ON_START)
+        inOrder.verify(graphObserver).onStateChanged(
+            graphBackStackEntry, Lifecycle.Event.ON_RESUME)
+
+        inOrder.verify(nestedGraphObserver).onStateChanged(
+            nestedGraphBackStackEntry, Lifecycle.Event.ON_CREATE)
+        inOrder.verify(nestedGraphObserver).onStateChanged(
+            nestedGraphBackStackEntry, Lifecycle.Event.ON_START)
+        inOrder.verify(nestedGraphObserver).onStateChanged(
+            nestedGraphBackStackEntry, Lifecycle.Event.ON_RESUME)
+
+        inOrder.verify(nestedObserver).onStateChanged(
+            nestedBackStackEntry, Lifecycle.Event.ON_CREATE)
+        inOrder.verify(nestedObserver).onStateChanged(
+            nestedBackStackEntry, Lifecycle.Event.ON_START)
+        inOrder.verify(nestedObserver).onStateChanged(
+            nestedBackStackEntry, Lifecycle.Event.ON_RESUME)
+
+        navController.navigate(R.id.second_test)
+
+        inOrder.verify(nestedObserver).onStateChanged(
+            nestedBackStackEntry, Lifecycle.Event.ON_PAUSE)
+        inOrder.verify(nestedObserver).onStateChanged(
+            nestedBackStackEntry, Lifecycle.Event.ON_STOP)
+
+        inOrder.verify(nestedGraphObserver).onStateChanged(
+            nestedGraphBackStackEntry, Lifecycle.Event.ON_PAUSE)
+        inOrder.verify(nestedGraphObserver).onStateChanged(
+            nestedGraphBackStackEntry, Lifecycle.Event.ON_STOP)
+
+        navController.popBackStack()
+
+        inOrder.verify(nestedGraphObserver).onStateChanged(
+            nestedGraphBackStackEntry, Lifecycle.Event.ON_START)
+        inOrder.verify(nestedGraphObserver).onStateChanged(
+            nestedGraphBackStackEntry, Lifecycle.Event.ON_RESUME)
+
+        inOrder.verify(nestedObserver).onStateChanged(
+            nestedBackStackEntry, Lifecycle.Event.ON_START)
+        inOrder.verify(nestedObserver).onStateChanged(
+            nestedBackStackEntry, Lifecycle.Event.ON_RESUME)
+
+        inOrder.verifyNoMoreInteractions()
+    }
+
+    /**
+     * Test that navigating from within a nested navigation graph to one of the graph's
+     * FloatingWindow siblings correctly moves both the previous destination and its graph to
+     * started.
+     */
+    @Test
+    fun testLifecycleNestedOrderingWithDialog() {
+        val navController = createNavController()
+        val navGraph = navController.navigatorProvider.navigation(
+            id = 1,
+            startDestination = R.id.nested
+        ) {
+            navigation(id = R.id.nested, startDestination = R.id.nested_test) {
+                test(R.id.nested_test)
+            }
+            dialog(R.id.second_test)
+        }
+        navController.graph = navGraph
+
+        val graphBackStackEntry = navController.getBackStackEntry(navGraph.id)
+        val graphObserver = mock(LifecycleEventObserver::class.java)
+        graphBackStackEntry.lifecycle.addObserver(graphObserver)
+        val nestedGraphBackStackEntry = navController.getBackStackEntry(R.id.nested)
+        val nestedGraphObserver = mock(LifecycleEventObserver::class.java)
+        nestedGraphBackStackEntry.lifecycle.addObserver(nestedGraphObserver)
+        val nestedBackStackEntry = navController.getBackStackEntry(R.id.nested_test)
+        val nestedObserver = mock(LifecycleEventObserver::class.java)
+        nestedBackStackEntry.lifecycle.addObserver(nestedObserver)
+        val inOrder = inOrder(graphObserver, nestedGraphObserver, nestedObserver)
+        inOrder.verify(graphObserver).onStateChanged(
+            graphBackStackEntry, Lifecycle.Event.ON_CREATE)
+        inOrder.verify(graphObserver).onStateChanged(
+            graphBackStackEntry, Lifecycle.Event.ON_START)
+        inOrder.verify(graphObserver).onStateChanged(
+            graphBackStackEntry, Lifecycle.Event.ON_RESUME)
+
+        inOrder.verify(nestedGraphObserver).onStateChanged(
+            nestedGraphBackStackEntry, Lifecycle.Event.ON_CREATE)
+        inOrder.verify(nestedGraphObserver).onStateChanged(
+            nestedGraphBackStackEntry, Lifecycle.Event.ON_START)
+        inOrder.verify(nestedGraphObserver).onStateChanged(
+            nestedGraphBackStackEntry, Lifecycle.Event.ON_RESUME)
+
+        inOrder.verify(nestedObserver).onStateChanged(
+            nestedBackStackEntry, Lifecycle.Event.ON_CREATE)
+        inOrder.verify(nestedObserver).onStateChanged(
+            nestedBackStackEntry, Lifecycle.Event.ON_START)
+        inOrder.verify(nestedObserver).onStateChanged(
+            nestedBackStackEntry, Lifecycle.Event.ON_RESUME)
+
+        navController.navigate(R.id.second_test)
+
+        inOrder.verify(nestedObserver).onStateChanged(
+            nestedBackStackEntry, Lifecycle.Event.ON_PAUSE)
+
+        inOrder.verify(nestedGraphObserver).onStateChanged(
+            nestedGraphBackStackEntry, Lifecycle.Event.ON_PAUSE)
+
+        navController.popBackStack()
+
+        inOrder.verify(nestedGraphObserver).onStateChanged(
+            nestedGraphBackStackEntry, Lifecycle.Event.ON_RESUME)
+
+        inOrder.verify(nestedObserver).onStateChanged(
+            nestedBackStackEntry, Lifecycle.Event.ON_RESUME)
+
+        inOrder.verifyNoMoreInteractions()
+    }
+
+    /**
+     * Test that navigating to a new instance of a graph leaves the previous instance in its
+     * current state.
+     */
+    @Test
+    fun testLifecycleNestedRepeated() {
+        val navController = createNavController()
+        val navGraph = navController.navigatorProvider.navigation(
+            id = 1,
+            startDestination = R.id.nested
+        ) {
+            navigation(id = R.id.nested, startDestination = R.id.nested_test) {
+                test(R.id.nested_test)
+            }
+            test(R.id.second_test)
+        }
+        navController.graph = navGraph
+
+        val graphBackStackEntry = navController.getBackStackEntry(navGraph.id)
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        val nestedGraphBackStackEntry = navController.getBackStackEntry(R.id.nested)
+        assertWithMessage("The nested graph should be resumed when its child is resumed")
+            .that(nestedGraphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        val nestedBackStackEntry = navController.getBackStackEntry(R.id.nested_test)
+        assertWithMessage("The nested start destination should be resumed")
+            .that(nestedBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+
+        navController.navigate(R.id.second_test)
+
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The nested graph should be stopped when its children are stopped")
+            .that(nestedGraphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.CREATED)
+        assertWithMessage("The nested start destination should be stopped after navigate")
+            .that(nestedBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.CREATED)
+        val secondBackStackEntry = navController.getBackStackEntry(R.id.second_test)
+        assertWithMessage("The new destination should be resumed")
+            .that(secondBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+
+        // Navigate to a new instance of the nested graph
+        navController.navigate(R.id.nested)
+
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The original nested graph should still be created")
+            .that(nestedGraphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.CREATED)
+        assertWithMessage("The original nested start destination should still be created")
+            .that(nestedBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.CREATED)
+        assertWithMessage("The intermediate destination should be set to created")
+            .that(secondBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.CREATED)
+        val newNestedGraphBackStackEntry = navController.getBackStackEntry(R.id.nested)
+        assertWithMessage("The new nested graph should be resumed when its child is resumed")
+            .that(newNestedGraphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        val newNestedBackStackEntry = navController.getBackStackEntry(R.id.nested_test)
+        assertWithMessage("The new nested start destination should be resumed")
+            .that(newNestedBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+    }
+
+    /**
+     * Test that navigating to a new instance of a graph via a deep link to a FloatingWindow
+     * destination leaves the previous instance in its current state.
+     */
+    @Test
+    fun testLifecycleNestedRepeatedWithDialog() {
+        val navController = createNavController()
+        val navGraph = navController.navigatorProvider.navigation(
+            id = 1,
+            startDestination = R.id.nested
+        ) {
+            navigation(id = R.id.nested, startDestination = R.id.nested_test) {
+                test(R.id.nested_test)
+                dialog(R.id.nested_second_test) {
+                    deepLink("test://test/")
+                }
+            }
+            test(R.id.second_test)
+        }
+        navController.graph = navGraph
+
+        val graphBackStackEntry = navController.getBackStackEntry(navGraph.id)
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        val nestedGraphBackStackEntry = navController.getBackStackEntry(R.id.nested)
+        assertWithMessage("The nested graph should be resumed when its child is resumed")
+            .that(nestedGraphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        val nestedBackStackEntry = navController.getBackStackEntry(R.id.nested_test)
+        assertWithMessage("The nested start destination should be resumed")
+            .that(nestedBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+
+        navController.navigate(R.id.second_test)
+
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The nested graph should be stopped when its children are stopped")
+            .that(nestedGraphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.CREATED)
+        assertWithMessage("The nested start destination should be stopped after navigate")
+            .that(nestedBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.CREATED)
+        val secondBackStackEntry = navController.getBackStackEntry(R.id.second_test)
+        assertWithMessage("The new destination should be resumed")
+            .that(secondBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+
+        // Navigate to a new instance of the nested graph using a deep link to a dialog
+        navController.navigate(Uri.parse("test://test/"))
+
+        assertWithMessage("The parent graph should be resumed when its child is resumed")
+            .that(graphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        assertWithMessage("The original nested graph should still be created")
+            .that(nestedGraphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.CREATED)
+        assertWithMessage("The original nested start destination should still be created")
+            .that(nestedBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.CREATED)
+        assertWithMessage("The intermediate destination should remain started when under a dialog")
+            .that(secondBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.STARTED)
+        val newNestedGraphBackStackEntry = navController.getBackStackEntry(R.id.nested)
+        assertWithMessage("The new nested graph should be resumed when its child is resumed")
+            .that(newNestedGraphBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+        val newNestedBackStackEntry = navController.getBackStackEntry(R.id.nested_second_test)
+        assertWithMessage("The new nested start destination should be resumed")
+            .that(newNestedBackStackEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.RESUMED)
+    }
+
+    private fun createNavController(
+        lifecycleOwner: LifecycleOwner = object : LifecycleOwner {
+            private val lifecycleRegistry = LifecycleRegistry(this).apply {
+                currentState = Lifecycle.State.RESUMED
+            }
+            override fun getLifecycle() = lifecycleRegistry
+        }
+    ): NavController {
+        val navController = NavHostController(ApplicationProvider.getApplicationContext())
+        navController.navigatorProvider.addNavigator(TestNavigator())
+        navController.navigatorProvider.addNavigator(FloatingTestNavigator())
+        navController.setLifecycleOwner(lifecycleOwner)
+        return navController
+    }
+}
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryTest.kt
new file mode 100644
index 0000000..ab84f8c
--- /dev/null
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryTest.kt
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2019 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.navigation
+
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.SavedStateHandle
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.ViewModelStore
+import androidx.navigation.test.R
+import androidx.navigation.testing.TestNavigator
+import androidx.navigation.testing.test
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Assert.fail
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class NavBackStackEntryTest {
+
+    @Test
+    fun testGetViewModelStoreOwner() {
+        val navController = createNavController()
+        navController.setViewModelStore(ViewModelStore())
+        val navGraph = navController.navigatorProvider.navigation(
+            id = 1,
+            startDestination = R.id.start_test
+        ) {
+            test(R.id.start_test)
+        }
+        navController.setGraph(navGraph, null)
+
+        val owner = navController.getViewModelStoreOwner(navGraph.id)
+        assertThat(owner).isNotNull()
+        val store = owner.viewModelStore
+        assertThat(store).isNotNull()
+    }
+
+    @Test
+    fun testGetViewModelStoreOwnerAndroidViewModel() {
+        val navController = createNavController()
+        navController.setViewModelStore(ViewModelStore())
+        val navGraph = navController.navigatorProvider.navigation(
+            id = 1,
+            startDestination = R.id.start_test
+        ) {
+            test(R.id.start_test)
+        }
+        navController.setGraph(navGraph, null)
+
+        val owner = navController.getViewModelStoreOwner(navGraph.id)
+        assertThat(owner).isNotNull()
+        val viewModelProvider = ViewModelProvider(owner)
+        val viewModel = viewModelProvider[TestAndroidViewModel::class.java]
+        assertThat(viewModel).isNotNull()
+    }
+
+    @Test
+    fun testGetViewModelStoreOwnerSavedStateViewModel() {
+        val hostStore = ViewModelStore()
+        val navController = createNavController()
+        navController.setViewModelStore(hostStore)
+        val navGraph = navController.navigatorProvider.navigation(
+            id = 1,
+            startDestination = R.id.start_test
+        ) {
+            test(R.id.start_test)
+        }
+        navController.setGraph(navGraph, null)
+
+        val owner = navController.getViewModelStoreOwner(navGraph.id)
+        assertThat(owner).isNotNull()
+        val viewModelProvider = ViewModelProvider(owner)
+        val viewModel = viewModelProvider[TestSavedStateViewModel::class.java]
+        assertThat(viewModel).isNotNull()
+        viewModel.savedStateHandle.set("test", "test")
+
+        val savedState = navController.saveState()
+        val restoredNavController = createNavController()
+        restoredNavController.setViewModelStore(hostStore)
+        restoredNavController.restoreState(savedState)
+        restoredNavController.graph = navGraph
+
+        val restoredOwner = navController.getViewModelStoreOwner(navGraph.id)
+        val restoredViewModel = ViewModelProvider(
+            restoredOwner)[TestSavedStateViewModel::class.java]
+        val restoredState: String? = restoredViewModel.savedStateHandle.get("test")
+        assertThat(restoredState).isEqualTo("test")
+    }
+
+    @Test
+    fun testSaveRestoreGetViewModelStoreOwner() {
+        val hostStore = ViewModelStore()
+        val navController = createNavController()
+        navController.setViewModelStore(hostStore)
+        val navGraph = navController.navigatorProvider.navigation(
+            id = 1,
+            startDestination = R.id.start_test
+        ) {
+            test(R.id.start_test)
+        }
+        navController.setGraph(navGraph, null)
+
+        val store = navController.getViewModelStoreOwner(navGraph.id).viewModelStore
+        assertThat(store).isNotNull()
+
+        val savedState = navController.saveState()
+        val restoredNavController = createNavController()
+        restoredNavController.setViewModelStore(hostStore)
+        restoredNavController.restoreState(savedState)
+        restoredNavController.graph = navGraph
+
+        assertWithMessage("Restored NavController should return the same ViewModelStore")
+            .that(restoredNavController.getViewModelStoreOwner(navGraph.id).viewModelStore)
+            .isSameInstanceAs(store)
+    }
+
+    @Test
+    fun testGetViewModelStoreOwnerNoGraph() {
+        val navController = createNavController()
+        navController.setViewModelStore(ViewModelStore())
+        val navGraphId = 1
+
+        try {
+            navController.getViewModelStoreOwner(navGraphId)
+            fail(
+                "Attempting to get ViewModelStoreOwner for navGraph not on back stack should " +
+                        "throw IllegalArgumentException"
+            )
+        } catch (e: IllegalArgumentException) {
+            assertThat(e)
+                .hasMessageThat().contains(
+                    "No destination with ID $navGraphId is on the NavController's back stack"
+                )
+        }
+    }
+
+    @Test
+    fun testGetViewModelStoreOwnerSameGraph() {
+        val navController = createNavController()
+        navController.setViewModelStore(ViewModelStore())
+        val provider = navController.navigatorProvider
+        val graph = provider.navigation(1, startDestination = 1) {
+            navigation(1, startDestination = 2) {
+                test(2)
+            }
+        }
+
+        navController.setGraph(graph, null)
+        val owner = navController.getViewModelStoreOwner(graph.id)
+        assertThat(owner).isNotNull()
+        val viewStore = owner.viewModelStore
+        assertThat(viewStore).isNotNull()
+
+        val sameGraphOwner = navController.getViewModelStoreOwner(graph.id)
+        assertThat(sameGraphOwner).isSameInstanceAs(owner)
+        assertThat(sameGraphOwner.viewModelStore).isSameInstanceAs(viewStore)
+    }
+
+    private fun createNavController(): NavController {
+        val navController = NavController(ApplicationProvider.getApplicationContext())
+        val navigator = TestNavigator()
+        navController.navigatorProvider.addNavigator(navigator)
+        return navController
+    }
+}
+
+class TestAndroidViewModel(application: Application) : AndroidViewModel(application)
+
+class TestSavedStateViewModel(val savedStateHandle: SavedStateHandle) : ViewModel()
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
index 297e3d8..454fbfd 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
@@ -16,17 +16,11 @@
 
 package androidx.navigation
 
-import android.app.Application
 import android.content.Context
 import android.net.Uri
 import android.os.Bundle
 import android.os.Parcel
 import android.os.Parcelable
-import androidx.lifecycle.AndroidViewModel
-import androidx.lifecycle.SavedStateHandle
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.ViewModelProvider
-import androidx.lifecycle.ViewModelStore
 import androidx.navigation.test.R
 import androidx.navigation.testing.TestNavigator
 import androidx.navigation.testing.test
@@ -876,145 +870,6 @@
         verifyNoMoreInteractions(onDestinationChangedListener)
     }
 
-    @Test
-    fun testGetViewModelStoreOwner() {
-        val navController = createNavController()
-        navController.setViewModelStore(ViewModelStore())
-        val navGraph = navController.navigatorProvider.navigation(
-            id = 1,
-            startDestination = R.id.start_test
-        ) {
-            test(R.id.start_test)
-        }
-        navController.setGraph(navGraph, null)
-
-        val owner = navController.getViewModelStoreOwner(navGraph.id)
-        assertThat(owner).isNotNull()
-        val store = owner.viewModelStore
-        assertThat(store).isNotNull()
-    }
-
-    @Test
-    fun testGetViewModelStoreOwnerAndroidViewModel() {
-        val navController = createNavController()
-        navController.setViewModelStore(ViewModelStore())
-        val navGraph = navController.navigatorProvider.navigation(
-            id = 1,
-            startDestination = R.id.start_test
-        ) {
-            test(R.id.start_test)
-        }
-        navController.setGraph(navGraph, null)
-
-        val owner = navController.getViewModelStoreOwner(navGraph.id)
-        assertThat(owner).isNotNull()
-        val viewModelProvider = ViewModelProvider(owner)
-        val viewModel = viewModelProvider[TestAndroidViewModel::class.java]
-        assertThat(viewModel).isNotNull()
-    }
-
-    @Test
-    fun testGetViewModelStoreOwnerSavedStateViewModel() {
-        val hostStore = ViewModelStore()
-        val navController = createNavController()
-        navController.setViewModelStore(hostStore)
-        val navGraph = navController.navigatorProvider.navigation(
-            id = 1,
-            startDestination = R.id.start_test
-        ) {
-            test(R.id.start_test)
-        }
-        navController.setGraph(navGraph, null)
-
-        val owner = navController.getViewModelStoreOwner(navGraph.id)
-        assertThat(owner).isNotNull()
-        val viewModelProvider = ViewModelProvider(owner)
-        val viewModel = viewModelProvider[TestSavedStateViewModel::class.java]
-        assertThat(viewModel).isNotNull()
-        viewModel.savedStateHandle.set("test", "test")
-
-        val savedState = navController.saveState()
-        val restoredNavController = createNavController()
-        restoredNavController.setViewModelStore(hostStore)
-        restoredNavController.restoreState(savedState)
-        restoredNavController.graph = navGraph
-
-        val restoredOwner = navController.getViewModelStoreOwner(navGraph.id)
-        val restoredViewModel = ViewModelProvider(
-            restoredOwner)[TestSavedStateViewModel::class.java]
-        val restoredState: String? = restoredViewModel.savedStateHandle.get("test")
-        assertThat(restoredState).isEqualTo("test")
-    }
-
-    @Test
-    fun testSaveRestoreGetViewModelStoreOwner() {
-        val hostStore = ViewModelStore()
-        val navController = createNavController()
-        navController.setViewModelStore(hostStore)
-        val navGraph = navController.navigatorProvider.navigation(
-            id = 1,
-            startDestination = R.id.start_test
-        ) {
-            test(R.id.start_test)
-        }
-        navController.setGraph(navGraph, null)
-
-        val store = navController.getViewModelStoreOwner(navGraph.id).viewModelStore
-        assertThat(store).isNotNull()
-
-        val savedState = navController.saveState()
-        val restoredNavController = createNavController()
-        restoredNavController.setViewModelStore(hostStore)
-        restoredNavController.restoreState(savedState)
-        restoredNavController.graph = navGraph
-
-        assertWithMessage("Restored NavController should return the same ViewModelStore")
-            .that(restoredNavController.getViewModelStoreOwner(navGraph.id).viewModelStore)
-            .isSameInstanceAs(store)
-    }
-
-    @Test
-    fun testGetViewModelStoreOwnerNoGraph() {
-        val navController = createNavController()
-        navController.setViewModelStore(ViewModelStore())
-        val navGraphId = 1
-
-        try {
-            navController.getViewModelStoreOwner(navGraphId)
-            fail(
-                "Attempting to get ViewModelStoreOwner for navGraph not on back stack should " +
-                        "throw IllegalArgumentException"
-            )
-        } catch (e: IllegalArgumentException) {
-            assertThat(e)
-                .hasMessageThat().contains(
-                    "No NavGraph with ID $navGraphId is on the NavController's back stack"
-                )
-        }
-    }
-
-    @Test
-    fun testGetViewModelStoreOwnerSameGraph() {
-        val navController = createNavController()
-        navController.setViewModelStore(ViewModelStore())
-        val provider = navController.navigatorProvider
-        val graph = provider.navigation(1, startDestination = 1) {
-            navigation(1, startDestination = 2) {
-                test(2)
-            }
-        }
-
-        navController.setGraph(graph, null)
-        val owner = navController.getViewModelStoreOwner(graph.id)
-        assertThat(owner).isNotNull()
-        val viewStore = owner.viewModelStore
-        assertThat(viewStore).isNotNull()
-
-        val sameGraphOwner = navController.getViewModelStoreOwner(graph.id)
-        assertThat(sameGraphOwner).isSameInstanceAs(owner)
-        assertThat(sameGraphOwner.viewModelStore).isSameInstanceAs(viewStore)
-    }
-
     private fun createNavController(): NavController {
         val navController = NavController(ApplicationProvider.getApplicationContext())
         val navigator = TestNavigator()
@@ -1023,10 +878,6 @@
     }
 }
 
-class TestAndroidViewModel(application: Application) : AndroidViewModel(application)
-
-class TestSavedStateViewModel(val savedStateHandle: SavedStateHandle) : ViewModel()
-
 /**
  * [TestNavigator] that helps with testing saving and restoring state.
  */
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/test/FloatingTestNavigator.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/test/FloatingTestNavigator.kt
new file mode 100644
index 0000000..5f2c038
--- /dev/null
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/test/FloatingTestNavigator.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2019 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("NOTHING_TO_INLINE")
+
+package androidx.navigation.test
+
+import androidx.annotation.IdRes
+import androidx.navigation.FloatingWindow
+import androidx.navigation.NavDestinationBuilder
+import androidx.navigation.NavDestinationDsl
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.Navigator
+import androidx.navigation.get
+import androidx.navigation.testing.TestNavigator
+
+@Navigator.Name("dialog")
+class FloatingTestNavigator : TestNavigator() {
+    override fun createDestination(): Destination {
+        return FloatingDestination(this)
+    }
+
+    class FloatingDestination(navigator: TestNavigator) : Destination(navigator),
+        FloatingWindow
+}
+
+/**
+ * Construct a new [TestNavigator.Destination] from a [FloatingTestNavigator].
+ */
+inline fun NavGraphBuilder.dialog(@IdRes id: Int) = dialog(id) {}
+
+/**
+ * Construct a new [TestNavigator.Destination] from a [FloatingTestNavigator].
+ */
+inline fun NavGraphBuilder.dialog(
+    @IdRes id: Int,
+    builder: FloatingTestNavigatorDestinationBuilder.() -> Unit
+) = destination(FloatingTestNavigatorDestinationBuilder(
+    provider[FloatingTestNavigator::class],
+    id
+).apply(builder))
+
+/**
+ * DSL for constructing a new [TestNavigator.Destination] from a [FloatingTestNavigator].
+ */
+@NavDestinationDsl
+class FloatingTestNavigatorDestinationBuilder(
+    navigator: FloatingTestNavigator,
+    @IdRes id: Int
+) : NavDestinationBuilder<TestNavigator.Destination>(navigator, id)
diff --git a/navigation/navigation-runtime/src/main/java/androidx/navigation/NavBackStackEntry.java b/navigation/navigation-runtime/src/main/java/androidx/navigation/NavBackStackEntry.java
index f226265..8a071ab 100644
--- a/navigation/navigation-runtime/src/main/java/androidx/navigation/NavBackStackEntry.java
+++ b/navigation/navigation-runtime/src/main/java/androidx/navigation/NavBackStackEntry.java
@@ -37,9 +37,13 @@
 import java.util.UUID;
 
 /**
- * Representation of an entry in the back stack of a {@link NavController}.
+ * Representation of an entry in the back stack of a {@link NavController}. The
+ * {@link Lifecycle}, {@link ViewModelStore}, and {@link SavedStateRegistry} provided via
+ * this object are valid for the lifetime of this destination on the back stack: when this
+ * destination is popped off the back stack, the lifecycle will be destroyed, state
+ * will no longer be saved, and ViewModels will be cleared.
  */
-final class NavBackStackEntry implements
+public final class NavBackStackEntry implements
         LifecycleOwner,
         ViewModelStoreOwner, HasDefaultViewModelProviderFactory,
         SavedStateRegistryOwner {
@@ -53,21 +57,23 @@
     // Internal unique name for this navBackStackEntry;
     @NonNull
     final UUID mId;
+    private Lifecycle.State mHostLifecycle = Lifecycle.State.CREATED;
+    private Lifecycle.State mMaxLifecycle = Lifecycle.State.RESUMED;
     private NavControllerViewModel mNavControllerViewModel;
     private ViewModelProvider.Factory mDefaultFactory;
 
     NavBackStackEntry(@NonNull Context context,
             @NonNull NavDestination destination, @Nullable Bundle args,
-            @Nullable LifecycleOwner navControllerLifecyleOwner,
+            @Nullable LifecycleOwner navControllerLifecycleOwner,
             @Nullable NavControllerViewModel navControllerViewModel) {
         this(context, destination, args,
-                navControllerLifecyleOwner, navControllerViewModel,
+                navControllerLifecycleOwner, navControllerViewModel,
                 UUID.randomUUID(), null);
     }
 
     NavBackStackEntry(@NonNull Context context,
             @NonNull NavDestination destination, @Nullable Bundle args,
-            @Nullable LifecycleOwner navControllerLifecyleOwner,
+            @Nullable LifecycleOwner navControllerLifecycleOwner,
             @Nullable NavControllerViewModel navControllerViewModel,
             @NonNull UUID uuid, @Nullable Bundle savedState) {
         mContext = context;
@@ -76,12 +82,10 @@
         mArgs = args;
         mNavControllerViewModel = navControllerViewModel;
         mSavedStateRegistryController.performRestore(savedState);
-        if (navControllerLifecyleOwner != null) {
-            mLifecycle.setCurrentState(navControllerLifecyleOwner.getLifecycle()
-                    .getCurrentState());
-        } else {
-            mLifecycle.setCurrentState(Lifecycle.State.CREATED);
+        if (navControllerLifecycleOwner != null) {
+            mHostLifecycle = navControllerLifecycleOwner.getLifecycle().getCurrentState();
         }
+        updateState();
     }
 
     /**
@@ -106,19 +110,58 @@
         mNavControllerViewModel = navControllerViewModel;
     }
 
+    /**
+     * {@inheritDoc}
+     * <p>
+     * If the {@link NavHost} has not called {@link NavHostController#setLifecycleOwner}, the
+     * Lifecycle will be capped at {@link Lifecycle.State#CREATED}.
+     */
     @NonNull
     @Override
     public Lifecycle getLifecycle() {
         return mLifecycle;
     }
 
-    void handleLifecycleEvent(Lifecycle.Event event) {
-        mLifecycle.handleLifecycleEvent(event);
+    void setMaxLifecycle(@NonNull Lifecycle.State maxState) {
+        mMaxLifecycle = maxState;
+        updateState();
     }
 
     @NonNull
+    Lifecycle.State getMaxLifecycle() {
+        return mMaxLifecycle;
+    }
+
+    void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
+        mHostLifecycle = getStateAfter(event);
+        updateState();
+    }
+
+    /**
+     * Update the state to be the lower of the two constraints:
+     */
+    private void updateState() {
+        if (mHostLifecycle.ordinal() < mMaxLifecycle.ordinal()) {
+            mLifecycle.setCurrentState(mHostLifecycle);
+        } else {
+            mLifecycle.setCurrentState(mMaxLifecycle);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @throws IllegalStateException if called before the {@link NavHost} has called
+     * {@link NavHostController#setViewModelStore}.
+     */
+    @NonNull
     @Override
     public ViewModelStore getViewModelStore() {
+        if (mNavControllerViewModel == null) {
+            throw new IllegalStateException("You must call setViewModelStore() on your "
+                    + "NavHostController before accessing "
+                    + "the ViewModelStore of a navigation graph.");
+        }
         return mNavControllerViewModel.getViewModelStore(mId);
     }
 
@@ -143,4 +186,24 @@
     void saveState(@NonNull Bundle outBundle) {
         mSavedStateRegistryController.performSave(outBundle);
     }
+
+    // Copied from LifecycleRegistry.getStateAfter()
+    @NonNull
+    private static Lifecycle.State getStateAfter(@NonNull Lifecycle.Event event) {
+        switch (event) {
+            case ON_CREATE:
+            case ON_STOP:
+                return Lifecycle.State.CREATED;
+            case ON_START:
+            case ON_PAUSE:
+                return Lifecycle.State.STARTED;
+            case ON_RESUME:
+                return Lifecycle.State.RESUMED;
+            case ON_DESTROY:
+                return Lifecycle.State.DESTROYED;
+            case ON_ANY:
+                break;
+        }
+        throw new IllegalArgumentException("Unexpected event value " + event);
+    }
 }
diff --git a/navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.java b/navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.java
index 9686153..4ab77ad 100644
--- a/navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.java
+++ b/navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.java
@@ -43,6 +43,7 @@
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Deque;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.concurrent.CopyOnWriteArrayList;
@@ -292,7 +293,7 @@
         for (Navigator<?> navigator : popOperations) {
             if (navigator.popBackStack()) {
                 NavBackStackEntry entry = mBackStack.removeLast();
-                entry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
+                entry.setMaxLifecycle(Lifecycle.State.DESTROYED);
                 if (mViewModel != null) {
                     mViewModel.clear(entry.mId);
                 }
@@ -377,6 +378,68 @@
             // Keep popping
         }
         if (!mBackStack.isEmpty()) {
+            // First determine what the current resumed destination is and, if and only if
+            // the current resumed destination is a FloatingWindow, what destination is
+            // underneath it that must remain started.
+            NavDestination nextResumed = mBackStack.peekLast().getDestination();
+            NavDestination nextStarted = null;
+            if (nextResumed instanceof FloatingWindow) {
+                // Find the next destination in the back stack as that destination
+                // should still be STARTED when the FloatingWindow destination is above it.
+                Iterator<NavBackStackEntry> iterator = mBackStack.descendingIterator();
+                while (iterator.hasNext()) {
+                    NavDestination destination = iterator.next().getDestination();
+                    if (!(destination instanceof NavGraph)
+                            && !(destination instanceof FloatingWindow)) {
+                        nextStarted = destination;
+                        break;
+                    }
+                }
+            }
+            // First iterate downward through the stack, applying downward Lifecycle
+            // transitions and capturing any upward Lifecycle transitions to apply afterwards.
+            // This ensures proper nesting where parent navigation graphs are started before
+            // their children and stopped only after their children are stopped.
+            HashMap<NavBackStackEntry, Lifecycle.State> upwardStateTransitions = new HashMap<>();
+            Iterator<NavBackStackEntry> iterator = mBackStack.descendingIterator();
+            while (iterator.hasNext()) {
+                NavBackStackEntry entry = iterator.next();
+                Lifecycle.State currentMaxLifecycle = entry.getMaxLifecycle();
+                NavDestination destination = entry.getDestination();
+                if (nextResumed != null && destination.getId() == nextResumed.getId()) {
+                    // Upward Lifecycle transitions need to be done afterwards so that
+                    // the parent navigation graph is resumed before their children
+                    if (currentMaxLifecycle != Lifecycle.State.RESUMED) {
+                        upwardStateTransitions.put(entry, Lifecycle.State.RESUMED);
+                    }
+                    nextResumed = nextResumed.getParent();
+                } else if (nextStarted != null && destination.getId() == nextStarted.getId()) {
+                    if (currentMaxLifecycle == Lifecycle.State.RESUMED) {
+                        // Downward transitions should be done immediately so children are
+                        // paused before their parent navigation graphs
+                        entry.setMaxLifecycle(Lifecycle.State.STARTED);
+                    } else if (currentMaxLifecycle != Lifecycle.State.STARTED) {
+                        // Upward Lifecycle transitions need to be done afterwards so that
+                        // the parent navigation graph is started before their children
+                        upwardStateTransitions.put(entry, Lifecycle.State.STARTED);
+                    }
+                    nextStarted = nextStarted.getParent();
+                } else {
+                    entry.setMaxLifecycle(Lifecycle.State.CREATED);
+                }
+            }
+            // Apply all upward Lifecycle transitions by iterating through the stack again,
+            // this time applying the new lifecycle to the parent navigation graphs first
+            iterator = mBackStack.iterator();
+            while (iterator.hasNext()) {
+                NavBackStackEntry entry = iterator.next();
+                Lifecycle.State newState = upwardStateTransitions.get(entry);
+                if (newState != null) {
+                    entry.setMaxLifecycle(newState);
+                }
+            }
+
+            // Now call all registered OnDestinationChangedListener instances
             NavBackStackEntry backStackEntry = mBackStack.peekLast();
             for (OnDestinationChangedListener listener :
                     mOnDestinationChangedListeners) {
@@ -1060,7 +1123,7 @@
     }
 
     /**
-     * Gets the {@link ViewModelStoreOwner} for a NavGraph.This can be passed to
+     * Gets the {@link ViewModelStoreOwner} for a NavGraph. This can be passed to
      * {@link androidx.lifecycle.ViewModelProvider} to retrieve a ViewModel that is scoped
      * to the navigation graph - it will be cleared when the navigation graph is popped off
      * the back stack.
@@ -1076,19 +1139,35 @@
             throw new IllegalStateException("You must call setViewModelStore() before calling "
                     + "getViewModelStoreOwner().");
         }
+        NavBackStackEntry lastFromBackStack = getBackStackEntry(navGraphId);
+        if (!(lastFromBackStack.getDestination() instanceof NavGraph)) {
+            throw new IllegalArgumentException("No NavGraph with ID " + navGraphId
+                    + " is on the NavController's back stack");
+        }
+        return lastFromBackStack;
+    }
+
+    /**
+     * Gets the topmost {@link NavBackStackEntry} for a destination id.
+     *
+     * @param destinationId ID of a destination that exists on the back stack
+     * @throws IllegalArgumentException if the destination is not on the back stack
+     */
+    @NonNull
+    public NavBackStackEntry getBackStackEntry(@IdRes int destinationId) {
         NavBackStackEntry lastFromBackStack = null;
         Iterator<NavBackStackEntry> iterator = mBackStack.descendingIterator();
         while (iterator.hasNext()) {
             NavBackStackEntry entry = iterator.next();
             NavDestination destination = entry.getDestination();
-            if (destination instanceof NavGraph && destination.getId() == navGraphId) {
+            if (destination.getId() == destinationId) {
                 lastFromBackStack = entry;
                 break;
             }
         }
         if (lastFromBackStack == null) {
-            throw new IllegalArgumentException("No NavGraph with ID " + navGraphId + " is on the "
-                    + "NavController's back stack");
+            throw new IllegalArgumentException("No destination with ID " + destinationId
+                    + " is on the NavController's back stack");
         }
         return lastFromBackStack;
     }
diff --git a/navigation/navigation-safe-args-gradle-plugin/build.gradle b/navigation/navigation-safe-args-gradle-plugin/build.gradle
index f492bdf..d308d30 100644
--- a/navigation/navigation-safe-args-gradle-plugin/build.gradle
+++ b/navigation/navigation-safe-args-gradle-plugin/build.gradle
@@ -38,8 +38,8 @@
 }
 
 dependencies {
-    compile(SAFE_ARGS_ANDROID_GRADLE_PLUGIN)
-    compile(SAFE_ARGS_KOTLIN_GRADLE_PLUGIN)
+    compile(ANDROID_GRADLE_PLUGIN)
+    compile(KOTLIN_GRADLE_PLUGIN)
     compile project(":navigation:navigation-safe-args-generator")
     compile gradleApi()
     compile(GSON)
@@ -53,7 +53,7 @@
     inputs.property("buildToolsVersion", SupportConfig.BUILD_TOOLS_VERSION)
     inputs.property("minSdkVersion", SupportConfig.DEFAULT_MIN_SDK_VERSION)
     inputs.property("debugKeystore", debugKeystore)
-    inputs.property("navigationCommon", SAFE_ARGS_NAVIGATION_COMMON)
+    inputs.property("navigationCommon", NAVIGATION_COMMON)
     inputs.property("kotlinStdlib", KOTLIN_STDLIB)
     outputs.dir(generatedResources)
     doLast {
@@ -65,7 +65,7 @@
             writer.write("buildToolsVersion=$SupportConfig.BUILD_TOOLS_VERSION\n")
             writer.write("minSdkVersion=$SupportConfig.DEFAULT_MIN_SDK_VERSION\n")
             writer.write("debugKeystore=$debugKeystore\n")
-            writer.write("navigationCommon=$SAFE_ARGS_NAVIGATION_COMMON\n")
+            writer.write("navigationCommon=$NAVIGATION_COMMON\n")
             writer.write("kotlinStdlib=$KOTLIN_STDLIB\n")
         }
     }
diff --git a/navigation/navigation-ui-ktx/api/2.2.0-alpha02.txt b/navigation/navigation-ui-ktx/api/2.2.0-alpha02.txt
new file mode 100644
index 0000000..d20eb8f
--- /dev/null
+++ b/navigation/navigation-ui-ktx/api/2.2.0-alpha02.txt
@@ -0,0 +1,51 @@
+// Signature format: 3.0
+package androidx.navigation.ui {
+
+  public final class ActivityKt {
+    ctor public 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, androidx.navigation.ui.AppBarConfiguration configuration = AppBarConfiguration(navController.graph));
+  }
+
+  public final class AppBarConfigurationKt {
+    ctor public AppBarConfigurationKt();
+    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(androidx.navigation.NavGraph navGraph, androidx.drawerlayout.widget.DrawerLayout? drawerLayout = null, kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener = { false });
+    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(android.view.Menu topLevelMenu, androidx.drawerlayout.widget.DrawerLayout? drawerLayout = null, kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener = { false });
+    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(java.util.Set<java.lang.Integer> topLevelDestinationIds, androidx.drawerlayout.widget.DrawerLayout? drawerLayout = null, kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener = { false });
+  }
+
+  public final class BottomNavigationViewKt {
+    ctor public BottomNavigationViewKt();
+    method public static void setupWithNavController(com.google.android.material.bottomnavigation.BottomNavigationView, androidx.navigation.NavController navController);
+  }
+
+  public final class CollapsingToolbarLayoutKt {
+    ctor public 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, androidx.navigation.ui.AppBarConfiguration configuration = AppBarConfiguration(navController.graph));
+  }
+
+  public final class MenuItemKt {
+    ctor public MenuItemKt();
+    method public static boolean onNavDestinationSelected(android.view.MenuItem, androidx.navigation.NavController navController);
+  }
+
+  public final class NavControllerKt {
+    ctor public NavControllerKt();
+    method public static boolean navigateUp(androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+    method public static boolean navigateUp(androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration appBarConfiguration);
+  }
+
+  public final class NavigationViewKt {
+    ctor public NavigationViewKt();
+    method public static void setupWithNavController(com.google.android.material.navigation.NavigationView, androidx.navigation.NavController navController);
+  }
+
+  public final class ToolbarKt {
+    ctor public 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, androidx.navigation.ui.AppBarConfiguration configuration = AppBarConfiguration(navController.graph));
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha02.txt b/navigation/navigation-ui-ktx/api/res-2.2.0-alpha02.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha02.txt
copy to navigation/navigation-ui-ktx/api/res-2.2.0-alpha02.txt
diff --git a/navigation/navigation-ui-ktx/api/restricted_2.2.0-alpha02.txt b/navigation/navigation-ui-ktx/api/restricted_2.2.0-alpha02.txt
new file mode 100644
index 0000000..d20eb8f
--- /dev/null
+++ b/navigation/navigation-ui-ktx/api/restricted_2.2.0-alpha02.txt
@@ -0,0 +1,51 @@
+// Signature format: 3.0
+package androidx.navigation.ui {
+
+  public final class ActivityKt {
+    ctor public 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, androidx.navigation.ui.AppBarConfiguration configuration = AppBarConfiguration(navController.graph));
+  }
+
+  public final class AppBarConfigurationKt {
+    ctor public AppBarConfigurationKt();
+    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(androidx.navigation.NavGraph navGraph, androidx.drawerlayout.widget.DrawerLayout? drawerLayout = null, kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener = { false });
+    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(android.view.Menu topLevelMenu, androidx.drawerlayout.widget.DrawerLayout? drawerLayout = null, kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener = { false });
+    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(java.util.Set<java.lang.Integer> topLevelDestinationIds, androidx.drawerlayout.widget.DrawerLayout? drawerLayout = null, kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener = { false });
+  }
+
+  public final class BottomNavigationViewKt {
+    ctor public BottomNavigationViewKt();
+    method public static void setupWithNavController(com.google.android.material.bottomnavigation.BottomNavigationView, androidx.navigation.NavController navController);
+  }
+
+  public final class CollapsingToolbarLayoutKt {
+    ctor public 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, androidx.navigation.ui.AppBarConfiguration configuration = AppBarConfiguration(navController.graph));
+  }
+
+  public final class MenuItemKt {
+    ctor public MenuItemKt();
+    method public static boolean onNavDestinationSelected(android.view.MenuItem, androidx.navigation.NavController navController);
+  }
+
+  public final class NavControllerKt {
+    ctor public NavControllerKt();
+    method public static boolean navigateUp(androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+    method public static boolean navigateUp(androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration appBarConfiguration);
+  }
+
+  public final class NavigationViewKt {
+    ctor public NavigationViewKt();
+    method public static void setupWithNavController(com.google.android.material.navigation.NavigationView, androidx.navigation.NavController navController);
+  }
+
+  public final class ToolbarKt {
+    ctor public 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, androidx.navigation.ui.AppBarConfiguration configuration = AppBarConfiguration(navController.graph));
+  }
+
+}
+
diff --git a/navigation/navigation-ui/api/2.2.0-alpha02.txt b/navigation/navigation-ui/api/2.2.0-alpha02.txt
new file mode 100644
index 0000000..555b85b
--- /dev/null
+++ b/navigation/navigation-ui/api/2.2.0-alpha02.txt
@@ -0,0 +1,42 @@
+// Signature format: 3.0
+package androidx.navigation.ui {
+
+  public final class AppBarConfiguration {
+    method public androidx.drawerlayout.widget.DrawerLayout? getDrawerLayout();
+    method public androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? getFallbackOnNavigateUpListener();
+    method public java.util.Set<java.lang.Integer!> getTopLevelDestinations();
+  }
+
+  public static final class AppBarConfiguration.Builder {
+    ctor public AppBarConfiguration.Builder(androidx.navigation.NavGraph);
+    ctor public AppBarConfiguration.Builder(android.view.Menu);
+    ctor public AppBarConfiguration.Builder(int...);
+    ctor public AppBarConfiguration.Builder(java.util.Set<java.lang.Integer!>);
+    method public androidx.navigation.ui.AppBarConfiguration build();
+    method public androidx.navigation.ui.AppBarConfiguration.Builder setDrawerLayout(androidx.drawerlayout.widget.DrawerLayout?);
+    method public androidx.navigation.ui.AppBarConfiguration.Builder setFallbackOnNavigateUpListener(androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener?);
+  }
+
+  public static interface AppBarConfiguration.OnNavigateUpListener {
+    method public boolean onNavigateUp();
+  }
+
+  public final class NavigationUI {
+    method public static boolean navigateUp(androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout?);
+    method public static boolean navigateUp(androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+    method public static boolean onNavDestinationSelected(android.view.MenuItem, androidx.navigation.NavController);
+    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController);
+    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout?);
+    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController);
+    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout?);
+    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController);
+    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout?);
+    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+    method public static void setupWithNavController(com.google.android.material.navigation.NavigationView, androidx.navigation.NavController);
+    method public static void setupWithNavController(com.google.android.material.bottomnavigation.BottomNavigationView, androidx.navigation.NavController);
+  }
+
+}
+
diff --git a/preference/ktx/api/res-1.1.0-alpha02.txt b/navigation/navigation-ui/api/res-2.2.0-alpha02.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha02.txt
copy to navigation/navigation-ui/api/res-2.2.0-alpha02.txt
diff --git a/navigation/navigation-ui/api/restricted_2.2.0-alpha02.txt b/navigation/navigation-ui/api/restricted_2.2.0-alpha02.txt
new file mode 100644
index 0000000..555b85b
--- /dev/null
+++ b/navigation/navigation-ui/api/restricted_2.2.0-alpha02.txt
@@ -0,0 +1,42 @@
+// Signature format: 3.0
+package androidx.navigation.ui {
+
+  public final class AppBarConfiguration {
+    method public androidx.drawerlayout.widget.DrawerLayout? getDrawerLayout();
+    method public androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? getFallbackOnNavigateUpListener();
+    method public java.util.Set<java.lang.Integer!> getTopLevelDestinations();
+  }
+
+  public static final class AppBarConfiguration.Builder {
+    ctor public AppBarConfiguration.Builder(androidx.navigation.NavGraph);
+    ctor public AppBarConfiguration.Builder(android.view.Menu);
+    ctor public AppBarConfiguration.Builder(int...);
+    ctor public AppBarConfiguration.Builder(java.util.Set<java.lang.Integer!>);
+    method public androidx.navigation.ui.AppBarConfiguration build();
+    method public androidx.navigation.ui.AppBarConfiguration.Builder setDrawerLayout(androidx.drawerlayout.widget.DrawerLayout?);
+    method public androidx.navigation.ui.AppBarConfiguration.Builder setFallbackOnNavigateUpListener(androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener?);
+  }
+
+  public static interface AppBarConfiguration.OnNavigateUpListener {
+    method public boolean onNavigateUp();
+  }
+
+  public final class NavigationUI {
+    method public static boolean navigateUp(androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout?);
+    method public static boolean navigateUp(androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+    method public static boolean onNavDestinationSelected(android.view.MenuItem, androidx.navigation.NavController);
+    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController);
+    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout?);
+    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController);
+    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout?);
+    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController);
+    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout?);
+    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+    method public static void setupWithNavController(com.google.android.material.navigation.NavigationView, androidx.navigation.NavController);
+    method public static void setupWithNavController(com.google.android.material.bottomnavigation.BottomNavigationView, androidx.navigation.NavController);
+  }
+
+}
+
diff --git a/navigation/navigation-ui/src/main/res/anim/nav_default_enter_anim.xml b/navigation/navigation-ui/src/main/res/anim/nav_default_enter_anim.xml
index bfbcf88..63a9894 100644
--- a/navigation/navigation-ui/src/main/res/anim/nav_default_enter_anim.xml
+++ b/navigation/navigation-ui/src/main/res/anim/nav_default_enter_anim.xml
@@ -17,6 +17,7 @@
 
 <set xmlns:android="http://schemas.android.com/apk/res/android">
     <alpha
+        android:interpolator="@android:anim/decelerate_interpolator"
         android:duration="@integer/config_navAnimTime"
         android:fromAlpha="0.0"
         android:toAlpha="1.0"/>
diff --git a/navigation/navigation-ui/src/main/res/anim/nav_default_exit_anim.xml b/navigation/navigation-ui/src/main/res/anim/nav_default_exit_anim.xml
index 13c3028..0031439 100644
--- a/navigation/navigation-ui/src/main/res/anim/nav_default_exit_anim.xml
+++ b/navigation/navigation-ui/src/main/res/anim/nav_default_exit_anim.xml
@@ -17,6 +17,7 @@
 
 <set xmlns:android="http://schemas.android.com/apk/res/android">
     <alpha
+        android:interpolator="@android:anim/accelerate_interpolator"
         android:duration="@integer/config_navAnimTime"
         android:fromAlpha="1.0"
         android:toAlpha="0.0"/>
diff --git a/navigation/navigation-ui/src/main/res/anim/nav_default_pop_enter_anim.xml b/navigation/navigation-ui/src/main/res/anim/nav_default_pop_enter_anim.xml
index bfbcf88..63a9894 100644
--- a/navigation/navigation-ui/src/main/res/anim/nav_default_pop_enter_anim.xml
+++ b/navigation/navigation-ui/src/main/res/anim/nav_default_pop_enter_anim.xml
@@ -17,6 +17,7 @@
 
 <set xmlns:android="http://schemas.android.com/apk/res/android">
     <alpha
+        android:interpolator="@android:anim/decelerate_interpolator"
         android:duration="@integer/config_navAnimTime"
         android:fromAlpha="0.0"
         android:toAlpha="1.0"/>
diff --git a/navigation/navigation-ui/src/main/res/anim/nav_default_pop_exit_anim.xml b/navigation/navigation-ui/src/main/res/anim/nav_default_pop_exit_anim.xml
index 13c3028..0031439 100644
--- a/navigation/navigation-ui/src/main/res/anim/nav_default_pop_exit_anim.xml
+++ b/navigation/navigation-ui/src/main/res/anim/nav_default_pop_exit_anim.xml
@@ -17,6 +17,7 @@
 
 <set xmlns:android="http://schemas.android.com/apk/res/android">
     <alpha
+        android:interpolator="@android:anim/accelerate_interpolator"
         android:duration="@integer/config_navAnimTime"
         android:fromAlpha="1.0"
         android:toAlpha="0.0"/>
diff --git a/navigation/navigation-ui/src/main/res/values/integers.xml b/navigation/navigation-ui/src/main/res/values/integers.xml
index 0092538..bf6b9c8 100644
--- a/navigation/navigation-ui/src/main/res/values/integers.xml
+++ b/navigation/navigation-ui/src/main/res/values/integers.xml
@@ -16,5 +16,5 @@
   -->
 
 <resources>
-    <integer name="config_navAnimTime">220</integer>
+    <integer name="config_navAnimTime">500</integer>
 </resources>
diff --git a/paging/common/api/3.0.0-alpha01.txt b/paging/common/api/3.0.0-alpha01.txt
index 0d44da6..fc77d4c 100644
--- a/paging/common/api/3.0.0-alpha01.txt
+++ b/paging/common/api/3.0.0-alpha01.txt
@@ -181,9 +181,11 @@
     method public suspend Object buildAsync(kotlin.coroutines.Continuation<? super androidx.paging.PagedList<Value>> p);
     method public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback);
     method public androidx.paging.PagedList.Builder<Key,Value> setCoroutineScope(kotlinx.coroutines.CoroutineScope coroutineScope);
-    method public androidx.paging.PagedList.Builder<Key,Value> setFetchExecutor(java.util.concurrent.Executor fetchExecutor);
+    method public androidx.paging.PagedList.Builder<Key,Value> setFetchDispatcher(kotlinx.coroutines.CoroutineDispatcher fetchDispatcher);
+    method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setFetchExecutor(java.util.concurrent.Executor fetchExecutor);
     method public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key? initialKey);
-    method public androidx.paging.PagedList.Builder<Key,Value> setNotifyExecutor(java.util.concurrent.Executor notifyExecutor);
+    method public androidx.paging.PagedList.Builder<Key,Value> setNotifyDispatcher(kotlinx.coroutines.CoroutineDispatcher notifyDispatcher);
+    method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setNotifyExecutor(java.util.concurrent.Executor notifyExecutor);
   }
 
   public abstract static class PagedList.Callback {
@@ -239,14 +241,14 @@
   public abstract class PagedSource<Key, Value> {
     ctor public PagedSource();
     method public final boolean getInvalid();
-    method public abstract androidx.paging.PagedSource.KeyProvider<Key,Value> getKeyProvider();
+    method public androidx.paging.PagedSource.KeyProvider<Key,Value> getKeyProvider();
     method public void invalidate();
-    method public abstract boolean isRetryableError(Throwable error);
+    method public boolean isRetryableError(Throwable error);
     method public abstract suspend Object load(androidx.paging.PagedSource.LoadParams<Key> params, kotlin.coroutines.Continuation<? super androidx.paging.PagedSource.LoadResult<Key,Value>> p);
     method public final void registerInvalidatedCallback(kotlin.jvm.functions.Function0<kotlin.Unit> onInvalidatedCallback);
     method public final void unregisterInvalidatedCallback(kotlin.jvm.functions.Function0<kotlin.Unit> onInvalidatedCallback);
     property public final boolean invalid;
-    property public abstract androidx.paging.PagedSource.KeyProvider<Key,Value> keyProvider;
+    property public androidx.paging.PagedSource.KeyProvider<Key,Value> keyProvider;
   }
 
   public abstract static sealed class PagedSource.KeyProvider<Key, Value> {
@@ -261,8 +263,8 @@
     ctor public PagedSource.KeyProvider.PageKey();
   }
 
-  public static final class PagedSource.KeyProvider.Positional<Value> extends androidx.paging.PagedSource.KeyProvider<java.lang.Integer,Value> {
-    ctor public PagedSource.KeyProvider.Positional();
+  public static final class PagedSource.KeyProvider.Positional extends androidx.paging.PagedSource.KeyProvider<java.lang.Integer,java.lang.Object> {
+    field public static final androidx.paging.PagedSource.KeyProvider.Positional! INSTANCE;
   }
 
   public static final class PagedSource.LoadParams<Key> {
@@ -281,19 +283,17 @@
   }
 
   public static final class PagedSource.LoadResult<Key, Value> {
-    ctor public PagedSource.LoadResult(@IntRange(from=null) int itemsBefore, @IntRange(from=null) int itemsAfter, Key? nextKey, Key? prevKey, java.util.List<? extends Value> data, int offset);
-    method public int component1();
+    ctor public PagedSource.LoadResult(java.util.List<? extends Value> data, @IntRange(from=null) int itemsBefore, @IntRange(from=null) int itemsAfter, Key? nextKey, Key? prevKey);
+    method public java.util.List<Value> component1();
     method public int component2();
-    method public Key? component3();
+    method public int component3();
     method public Key? component4();
-    method public java.util.List<Value> component5();
-    method public int component6();
-    method public androidx.paging.PagedSource.LoadResult<Key,Value> copy(int itemsBefore, int itemsAfter, Key? nextKey, Key? prevKey, java.util.List<? extends Value> data, int offset);
+    method public Key? component5();
+    method public androidx.paging.PagedSource.LoadResult<Key,Value> copy(java.util.List<? extends Value> data, int itemsBefore, int itemsAfter, Key? nextKey, Key? prevKey);
     method public java.util.List<Value> getData();
     method public int getItemsAfter();
     method public int getItemsBefore();
     method public Key? getNextKey();
-    method public int getOffset();
     method public Key? getPrevKey();
     field public static final int COUNT_UNDEFINED = -1; // 0xffffffff
     field public static final androidx.paging.PagedSource.LoadResult.Companion! Companion;
diff --git a/paging/common/api/api_lint.ignore b/paging/common/api/api_lint.ignore
index 678d58d..455d188 100644
--- a/paging/common/api/api_lint.ignore
+++ b/paging/common/api/api_lint.ignore
@@ -23,6 +23,12 @@
     Parameter p references hidden type class androidx.paging.PositionalDataSource.InitialResult.
 
 
+MissingNullability: androidx.paging.PagedSource.KeyProvider.Positional#INSTANCE:
+    Missing nullability on field `INSTANCE` in class `class androidx.paging.PagedSource.KeyProvider.Positional`
+MissingNullability: androidx.paging.PagedSource.LoadResult#Companion:
+    Missing nullability on field `Companion` in class `class androidx.paging.PagedSource.LoadResult`
+
+
 RegistrationName: androidx.paging.DataSource#addInvalidatedCallback(androidx.paging.DataSource.InvalidatedCallback):
     Callback methods should be named register/unregister; was addInvalidatedCallback
 RegistrationName: androidx.paging.DataSource#addInvalidatedCallback(kotlin.jvm.functions.Function0<kotlin.Unit>):
diff --git a/paging/common/api/current.txt b/paging/common/api/current.txt
index 0d44da6..fc77d4c 100644
--- a/paging/common/api/current.txt
+++ b/paging/common/api/current.txt
@@ -181,9 +181,11 @@
     method public suspend Object buildAsync(kotlin.coroutines.Continuation<? super androidx.paging.PagedList<Value>> p);
     method public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback);
     method public androidx.paging.PagedList.Builder<Key,Value> setCoroutineScope(kotlinx.coroutines.CoroutineScope coroutineScope);
-    method public androidx.paging.PagedList.Builder<Key,Value> setFetchExecutor(java.util.concurrent.Executor fetchExecutor);
+    method public androidx.paging.PagedList.Builder<Key,Value> setFetchDispatcher(kotlinx.coroutines.CoroutineDispatcher fetchDispatcher);
+    method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setFetchExecutor(java.util.concurrent.Executor fetchExecutor);
     method public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key? initialKey);
-    method public androidx.paging.PagedList.Builder<Key,Value> setNotifyExecutor(java.util.concurrent.Executor notifyExecutor);
+    method public androidx.paging.PagedList.Builder<Key,Value> setNotifyDispatcher(kotlinx.coroutines.CoroutineDispatcher notifyDispatcher);
+    method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setNotifyExecutor(java.util.concurrent.Executor notifyExecutor);
   }
 
   public abstract static class PagedList.Callback {
@@ -239,14 +241,14 @@
   public abstract class PagedSource<Key, Value> {
     ctor public PagedSource();
     method public final boolean getInvalid();
-    method public abstract androidx.paging.PagedSource.KeyProvider<Key,Value> getKeyProvider();
+    method public androidx.paging.PagedSource.KeyProvider<Key,Value> getKeyProvider();
     method public void invalidate();
-    method public abstract boolean isRetryableError(Throwable error);
+    method public boolean isRetryableError(Throwable error);
     method public abstract suspend Object load(androidx.paging.PagedSource.LoadParams<Key> params, kotlin.coroutines.Continuation<? super androidx.paging.PagedSource.LoadResult<Key,Value>> p);
     method public final void registerInvalidatedCallback(kotlin.jvm.functions.Function0<kotlin.Unit> onInvalidatedCallback);
     method public final void unregisterInvalidatedCallback(kotlin.jvm.functions.Function0<kotlin.Unit> onInvalidatedCallback);
     property public final boolean invalid;
-    property public abstract androidx.paging.PagedSource.KeyProvider<Key,Value> keyProvider;
+    property public androidx.paging.PagedSource.KeyProvider<Key,Value> keyProvider;
   }
 
   public abstract static sealed class PagedSource.KeyProvider<Key, Value> {
@@ -261,8 +263,8 @@
     ctor public PagedSource.KeyProvider.PageKey();
   }
 
-  public static final class PagedSource.KeyProvider.Positional<Value> extends androidx.paging.PagedSource.KeyProvider<java.lang.Integer,Value> {
-    ctor public PagedSource.KeyProvider.Positional();
+  public static final class PagedSource.KeyProvider.Positional extends androidx.paging.PagedSource.KeyProvider<java.lang.Integer,java.lang.Object> {
+    field public static final androidx.paging.PagedSource.KeyProvider.Positional! INSTANCE;
   }
 
   public static final class PagedSource.LoadParams<Key> {
@@ -281,19 +283,17 @@
   }
 
   public static final class PagedSource.LoadResult<Key, Value> {
-    ctor public PagedSource.LoadResult(@IntRange(from=null) int itemsBefore, @IntRange(from=null) int itemsAfter, Key? nextKey, Key? prevKey, java.util.List<? extends Value> data, int offset);
-    method public int component1();
+    ctor public PagedSource.LoadResult(java.util.List<? extends Value> data, @IntRange(from=null) int itemsBefore, @IntRange(from=null) int itemsAfter, Key? nextKey, Key? prevKey);
+    method public java.util.List<Value> component1();
     method public int component2();
-    method public Key? component3();
+    method public int component3();
     method public Key? component4();
-    method public java.util.List<Value> component5();
-    method public int component6();
-    method public androidx.paging.PagedSource.LoadResult<Key,Value> copy(int itemsBefore, int itemsAfter, Key? nextKey, Key? prevKey, java.util.List<? extends Value> data, int offset);
+    method public Key? component5();
+    method public androidx.paging.PagedSource.LoadResult<Key,Value> copy(java.util.List<? extends Value> data, int itemsBefore, int itemsAfter, Key? nextKey, Key? prevKey);
     method public java.util.List<Value> getData();
     method public int getItemsAfter();
     method public int getItemsBefore();
     method public Key? getNextKey();
-    method public int getOffset();
     method public Key? getPrevKey();
     field public static final int COUNT_UNDEFINED = -1; // 0xffffffff
     field public static final androidx.paging.PagedSource.LoadResult.Companion! Companion;
diff --git a/paging/common/api/restricted_3.0.0-alpha01.txt b/paging/common/api/restricted_3.0.0-alpha01.txt
index 73c6e1a..b3bd226 100644
--- a/paging/common/api/restricted_3.0.0-alpha01.txt
+++ b/paging/common/api/restricted_3.0.0-alpha01.txt
@@ -140,9 +140,10 @@
   }
 
   public abstract class PagedList<T> extends java.util.AbstractList<T> {
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public PagedList(kotlinx.coroutines.CoroutineScope coroutineScope, androidx.paging.PagedSource<?,T> pagedSource, androidx.paging.PagedStorage<T> storage, kotlinx.coroutines.CoroutineDispatcher notifyDispatcher, kotlinx.coroutines.CoroutineDispatcher backgroundDispatcher, androidx.paging.PagedList.BoundaryCallback<T>? boundaryCallback, androidx.paging.PagedList.Config config);
     method public void addWeakCallback(java.util.List<? extends T>? previousSnapshot, androidx.paging.PagedList.Callback callback);
     method public void addWeakLoadStateListener(kotlin.jvm.functions.Function3<? super androidx.paging.PagedList.LoadType,? super androidx.paging.PagedList.LoadState,? super java.lang.Throwable,kotlin.Unit> listener);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public static final suspend <K, T> Object create(androidx.paging.PagedSource<K,T> p, kotlinx.coroutines.CoroutineScope pagedSource, java.util.concurrent.Executor coroutineScope, java.util.concurrent.Executor notifyExecutor, java.util.concurrent.Executor fetchExecutor, androidx.paging.PagedList.BoundaryCallback<T>? initialLoadExecutor, androidx.paging.PagedList.Config boundaryCallback, K? config, kotlin.coroutines.Continuation<? super androidx.paging.PagedList<T>> key);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public static final suspend <K, T> Object create(androidx.paging.PagedSource<K,T> p, kotlinx.coroutines.CoroutineScope pagedSource, kotlinx.coroutines.CoroutineDispatcher coroutineScope, kotlinx.coroutines.CoroutineDispatcher notifyDispatcher, kotlinx.coroutines.CoroutineDispatcher fetchDispatcher, androidx.paging.PagedList.BoundaryCallback<T>? initialFetchDispatcher, androidx.paging.PagedList.Config boundaryCallback, K? config, kotlin.coroutines.Continuation<? super androidx.paging.PagedList<T>> key);
     method public abstract void detach();
     method public T? get(int index);
     method public androidx.paging.PagedList.Config getConfig();
@@ -188,9 +189,11 @@
     method public suspend Object buildAsync(kotlin.coroutines.Continuation<? super androidx.paging.PagedList<Value>> p);
     method public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback);
     method public androidx.paging.PagedList.Builder<Key,Value> setCoroutineScope(kotlinx.coroutines.CoroutineScope coroutineScope);
-    method public androidx.paging.PagedList.Builder<Key,Value> setFetchExecutor(java.util.concurrent.Executor fetchExecutor);
+    method public androidx.paging.PagedList.Builder<Key,Value> setFetchDispatcher(kotlinx.coroutines.CoroutineDispatcher fetchDispatcher);
+    method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setFetchExecutor(java.util.concurrent.Executor fetchExecutor);
     method public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key? initialKey);
-    method public androidx.paging.PagedList.Builder<Key,Value> setNotifyExecutor(java.util.concurrent.Executor notifyExecutor);
+    method public androidx.paging.PagedList.Builder<Key,Value> setNotifyDispatcher(kotlinx.coroutines.CoroutineDispatcher notifyDispatcher);
+    method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setNotifyExecutor(java.util.concurrent.Executor notifyExecutor);
   }
 
   public abstract static class PagedList.Callback {
@@ -201,7 +204,7 @@
   }
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public static final class PagedList.Companion {
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public suspend <K, T> Object create(androidx.paging.PagedSource<K,T> pagedSource, kotlinx.coroutines.CoroutineScope coroutineScope, java.util.concurrent.Executor notifyExecutor, java.util.concurrent.Executor fetchExecutor, java.util.concurrent.Executor initialLoadExecutor, androidx.paging.PagedList.BoundaryCallback<T>? boundaryCallback, androidx.paging.PagedList.Config config, K? key, kotlin.coroutines.Continuation<? super androidx.paging.PagedList<T>> p);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public suspend <K, T> Object create(androidx.paging.PagedSource<K,T> pagedSource, kotlinx.coroutines.CoroutineScope coroutineScope, kotlinx.coroutines.CoroutineDispatcher notifyDispatcher, kotlinx.coroutines.CoroutineDispatcher fetchDispatcher, kotlinx.coroutines.CoroutineDispatcher initialFetchDispatcher, androidx.paging.PagedList.BoundaryCallback<T>? boundaryCallback, androidx.paging.PagedList.Config config, K? key, kotlin.coroutines.Continuation<? super androidx.paging.PagedList<T>> p);
   }
 
   public static final class PagedList.Config {
@@ -262,14 +265,14 @@
   public abstract class PagedSource<Key, Value> {
     ctor public PagedSource();
     method public final boolean getInvalid();
-    method public abstract androidx.paging.PagedSource.KeyProvider<Key,Value> getKeyProvider();
+    method public androidx.paging.PagedSource.KeyProvider<Key,Value> getKeyProvider();
     method public void invalidate();
-    method public abstract boolean isRetryableError(Throwable error);
+    method public boolean isRetryableError(Throwable error);
     method public abstract suspend Object load(androidx.paging.PagedSource.LoadParams<Key> params, kotlin.coroutines.Continuation<? super androidx.paging.PagedSource.LoadResult<Key,Value>> p);
     method public final void registerInvalidatedCallback(kotlin.jvm.functions.Function0<kotlin.Unit> onInvalidatedCallback);
     method public final void unregisterInvalidatedCallback(kotlin.jvm.functions.Function0<kotlin.Unit> onInvalidatedCallback);
     property public final boolean invalid;
-    property public abstract androidx.paging.PagedSource.KeyProvider<Key,Value> keyProvider;
+    property public androidx.paging.PagedSource.KeyProvider<Key,Value> keyProvider;
   }
 
   public abstract static sealed class PagedSource.KeyProvider<Key, Value> {
@@ -284,8 +287,8 @@
     ctor public PagedSource.KeyProvider.PageKey();
   }
 
-  public static final class PagedSource.KeyProvider.Positional<Value> extends androidx.paging.PagedSource.KeyProvider<java.lang.Integer,Value> {
-    ctor public PagedSource.KeyProvider.Positional();
+  public static final class PagedSource.KeyProvider.Positional extends androidx.paging.PagedSource.KeyProvider<java.lang.Integer,java.lang.Object> {
+    field public static final androidx.paging.PagedSource.KeyProvider.Positional! INSTANCE;
   }
 
   public static final class PagedSource.LoadParams<Key> {
@@ -304,19 +307,17 @@
   }
 
   public static final class PagedSource.LoadResult<Key, Value> {
-    ctor public PagedSource.LoadResult(@IntRange(from=null) int itemsBefore, @IntRange(from=null) int itemsAfter, Key? nextKey, Key? prevKey, java.util.List<? extends Value> data, int offset);
-    method public int component1();
+    ctor public PagedSource.LoadResult(java.util.List<? extends Value> data, @IntRange(from=null) int itemsBefore, @IntRange(from=null) int itemsAfter, Key? nextKey, Key? prevKey);
+    method public java.util.List<Value> component1();
     method public int component2();
-    method public Key? component3();
+    method public int component3();
     method public Key? component4();
-    method public java.util.List<Value> component5();
-    method public int component6();
-    method public androidx.paging.PagedSource.LoadResult<Key,Value> copy(int itemsBefore, int itemsAfter, Key? nextKey, Key? prevKey, java.util.List<? extends Value> data, int offset);
+    method public Key? component5();
+    method public androidx.paging.PagedSource.LoadResult<Key,Value> copy(java.util.List<? extends Value> data, int itemsBefore, int itemsAfter, Key? nextKey, Key? prevKey);
     method public java.util.List<Value> getData();
     method public int getItemsAfter();
     method public int getItemsBefore();
     method public Key? getNextKey();
-    method public int getOffset();
     method public Key? getPrevKey();
     field public static final int COUNT_UNDEFINED = -1; // 0xffffffff
     field public static final androidx.paging.PagedSource.LoadResult.Companion! Companion;
@@ -337,8 +338,6 @@
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final class PagedSourceWrapper<Key, Value> extends androidx.paging.PagedSource<Key,Value> {
     ctor public PagedSourceWrapper(internal androidx.paging.DataSource<Key,Value> dataSource);
-    method public androidx.paging.PagedSource.KeyProvider<Key,Value> getKeyProvider();
-    method public boolean isRetryableError(Throwable error);
     method public suspend Object load(androidx.paging.PagedSource.LoadParams<Key> params, kotlin.coroutines.Continuation<? super androidx.paging.PagedSource.LoadResult<Key,Value>> p);
     property public androidx.paging.PagedSource.KeyProvider<Key,Value> keyProvider;
   }
diff --git a/paging/common/api/restricted_current.txt b/paging/common/api/restricted_current.txt
index 73c6e1a..b3bd226 100644
--- a/paging/common/api/restricted_current.txt
+++ b/paging/common/api/restricted_current.txt
@@ -140,9 +140,10 @@
   }
 
   public abstract class PagedList<T> extends java.util.AbstractList<T> {
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public PagedList(kotlinx.coroutines.CoroutineScope coroutineScope, androidx.paging.PagedSource<?,T> pagedSource, androidx.paging.PagedStorage<T> storage, kotlinx.coroutines.CoroutineDispatcher notifyDispatcher, kotlinx.coroutines.CoroutineDispatcher backgroundDispatcher, androidx.paging.PagedList.BoundaryCallback<T>? boundaryCallback, androidx.paging.PagedList.Config config);
     method public void addWeakCallback(java.util.List<? extends T>? previousSnapshot, androidx.paging.PagedList.Callback callback);
     method public void addWeakLoadStateListener(kotlin.jvm.functions.Function3<? super androidx.paging.PagedList.LoadType,? super androidx.paging.PagedList.LoadState,? super java.lang.Throwable,kotlin.Unit> listener);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public static final suspend <K, T> Object create(androidx.paging.PagedSource<K,T> p, kotlinx.coroutines.CoroutineScope pagedSource, java.util.concurrent.Executor coroutineScope, java.util.concurrent.Executor notifyExecutor, java.util.concurrent.Executor fetchExecutor, androidx.paging.PagedList.BoundaryCallback<T>? initialLoadExecutor, androidx.paging.PagedList.Config boundaryCallback, K? config, kotlin.coroutines.Continuation<? super androidx.paging.PagedList<T>> key);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public static final suspend <K, T> Object create(androidx.paging.PagedSource<K,T> p, kotlinx.coroutines.CoroutineScope pagedSource, kotlinx.coroutines.CoroutineDispatcher coroutineScope, kotlinx.coroutines.CoroutineDispatcher notifyDispatcher, kotlinx.coroutines.CoroutineDispatcher fetchDispatcher, androidx.paging.PagedList.BoundaryCallback<T>? initialFetchDispatcher, androidx.paging.PagedList.Config boundaryCallback, K? config, kotlin.coroutines.Continuation<? super androidx.paging.PagedList<T>> key);
     method public abstract void detach();
     method public T? get(int index);
     method public androidx.paging.PagedList.Config getConfig();
@@ -188,9 +189,11 @@
     method public suspend Object buildAsync(kotlin.coroutines.Continuation<? super androidx.paging.PagedList<Value>> p);
     method public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback);
     method public androidx.paging.PagedList.Builder<Key,Value> setCoroutineScope(kotlinx.coroutines.CoroutineScope coroutineScope);
-    method public androidx.paging.PagedList.Builder<Key,Value> setFetchExecutor(java.util.concurrent.Executor fetchExecutor);
+    method public androidx.paging.PagedList.Builder<Key,Value> setFetchDispatcher(kotlinx.coroutines.CoroutineDispatcher fetchDispatcher);
+    method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setFetchExecutor(java.util.concurrent.Executor fetchExecutor);
     method public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key? initialKey);
-    method public androidx.paging.PagedList.Builder<Key,Value> setNotifyExecutor(java.util.concurrent.Executor notifyExecutor);
+    method public androidx.paging.PagedList.Builder<Key,Value> setNotifyDispatcher(kotlinx.coroutines.CoroutineDispatcher notifyDispatcher);
+    method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setNotifyExecutor(java.util.concurrent.Executor notifyExecutor);
   }
 
   public abstract static class PagedList.Callback {
@@ -201,7 +204,7 @@
   }
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public static final class PagedList.Companion {
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public suspend <K, T> Object create(androidx.paging.PagedSource<K,T> pagedSource, kotlinx.coroutines.CoroutineScope coroutineScope, java.util.concurrent.Executor notifyExecutor, java.util.concurrent.Executor fetchExecutor, java.util.concurrent.Executor initialLoadExecutor, androidx.paging.PagedList.BoundaryCallback<T>? boundaryCallback, androidx.paging.PagedList.Config config, K? key, kotlin.coroutines.Continuation<? super androidx.paging.PagedList<T>> p);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public suspend <K, T> Object create(androidx.paging.PagedSource<K,T> pagedSource, kotlinx.coroutines.CoroutineScope coroutineScope, kotlinx.coroutines.CoroutineDispatcher notifyDispatcher, kotlinx.coroutines.CoroutineDispatcher fetchDispatcher, kotlinx.coroutines.CoroutineDispatcher initialFetchDispatcher, androidx.paging.PagedList.BoundaryCallback<T>? boundaryCallback, androidx.paging.PagedList.Config config, K? key, kotlin.coroutines.Continuation<? super androidx.paging.PagedList<T>> p);
   }
 
   public static final class PagedList.Config {
@@ -262,14 +265,14 @@
   public abstract class PagedSource<Key, Value> {
     ctor public PagedSource();
     method public final boolean getInvalid();
-    method public abstract androidx.paging.PagedSource.KeyProvider<Key,Value> getKeyProvider();
+    method public androidx.paging.PagedSource.KeyProvider<Key,Value> getKeyProvider();
     method public void invalidate();
-    method public abstract boolean isRetryableError(Throwable error);
+    method public boolean isRetryableError(Throwable error);
     method public abstract suspend Object load(androidx.paging.PagedSource.LoadParams<Key> params, kotlin.coroutines.Continuation<? super androidx.paging.PagedSource.LoadResult<Key,Value>> p);
     method public final void registerInvalidatedCallback(kotlin.jvm.functions.Function0<kotlin.Unit> onInvalidatedCallback);
     method public final void unregisterInvalidatedCallback(kotlin.jvm.functions.Function0<kotlin.Unit> onInvalidatedCallback);
     property public final boolean invalid;
-    property public abstract androidx.paging.PagedSource.KeyProvider<Key,Value> keyProvider;
+    property public androidx.paging.PagedSource.KeyProvider<Key,Value> keyProvider;
   }
 
   public abstract static sealed class PagedSource.KeyProvider<Key, Value> {
@@ -284,8 +287,8 @@
     ctor public PagedSource.KeyProvider.PageKey();
   }
 
-  public static final class PagedSource.KeyProvider.Positional<Value> extends androidx.paging.PagedSource.KeyProvider<java.lang.Integer,Value> {
-    ctor public PagedSource.KeyProvider.Positional();
+  public static final class PagedSource.KeyProvider.Positional extends androidx.paging.PagedSource.KeyProvider<java.lang.Integer,java.lang.Object> {
+    field public static final androidx.paging.PagedSource.KeyProvider.Positional! INSTANCE;
   }
 
   public static final class PagedSource.LoadParams<Key> {
@@ -304,19 +307,17 @@
   }
 
   public static final class PagedSource.LoadResult<Key, Value> {
-    ctor public PagedSource.LoadResult(@IntRange(from=null) int itemsBefore, @IntRange(from=null) int itemsAfter, Key? nextKey, Key? prevKey, java.util.List<? extends Value> data, int offset);
-    method public int component1();
+    ctor public PagedSource.LoadResult(java.util.List<? extends Value> data, @IntRange(from=null) int itemsBefore, @IntRange(from=null) int itemsAfter, Key? nextKey, Key? prevKey);
+    method public java.util.List<Value> component1();
     method public int component2();
-    method public Key? component3();
+    method public int component3();
     method public Key? component4();
-    method public java.util.List<Value> component5();
-    method public int component6();
-    method public androidx.paging.PagedSource.LoadResult<Key,Value> copy(int itemsBefore, int itemsAfter, Key? nextKey, Key? prevKey, java.util.List<? extends Value> data, int offset);
+    method public Key? component5();
+    method public androidx.paging.PagedSource.LoadResult<Key,Value> copy(java.util.List<? extends Value> data, int itemsBefore, int itemsAfter, Key? nextKey, Key? prevKey);
     method public java.util.List<Value> getData();
     method public int getItemsAfter();
     method public int getItemsBefore();
     method public Key? getNextKey();
-    method public int getOffset();
     method public Key? getPrevKey();
     field public static final int COUNT_UNDEFINED = -1; // 0xffffffff
     field public static final androidx.paging.PagedSource.LoadResult.Companion! Companion;
@@ -337,8 +338,6 @@
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final class PagedSourceWrapper<Key, Value> extends androidx.paging.PagedSource<Key,Value> {
     ctor public PagedSourceWrapper(internal androidx.paging.DataSource<Key,Value> dataSource);
-    method public androidx.paging.PagedSource.KeyProvider<Key,Value> getKeyProvider();
-    method public boolean isRetryableError(Throwable error);
     method public suspend Object load(androidx.paging.PagedSource.LoadParams<Key> params, kotlin.coroutines.Continuation<? super androidx.paging.PagedSource.LoadResult<Key,Value>> p);
     property public androidx.paging.PagedSource.KeyProvider<Key,Value> keyProvider;
   }
diff --git a/paging/common/build.gradle b/paging/common/build.gradle
index 3920cb8..e6075be 100644
--- a/paging/common/build.gradle
+++ b/paging/common/build.gradle
@@ -32,7 +32,7 @@
     compile("androidx.annotation:annotation:1.1.0")
     compile(ARCH_CORE_COMMON)
     api(KOTLIN_STDLIB)
-    api(KOTLIN_COROUTINES)
+    api(KOTLIN_COROUTINES_CORE)
 
     testCompile(JUNIT)
     testCompile(MOCKITO_CORE)
@@ -40,6 +40,7 @@
         exclude group: 'org.mockito' // to keep control on the mockito version
     }
     testImplementation project(':internal-testutils-common')
+    testImplementation project(':internal-testutils-ktx')
     testImplementation(KOTLIN_TEST_COMMON)
     testImplementation(TRUTH)
 }
diff --git a/paging/common/src/main/kotlin/androidx/paging/ContiguousPagedList.kt b/paging/common/src/main/kotlin/androidx/paging/ContiguousPagedList.kt
index 1cde4c0..8fc3eac 100644
--- a/paging/common/src/main/kotlin/androidx/paging/ContiguousPagedList.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/ContiguousPagedList.kt
@@ -20,8 +20,8 @@
 import androidx.annotation.RestrictTo
 import androidx.paging.PagedSource.KeyProvider
 import androidx.paging.PagedSource.LoadResult.Companion.COUNT_UNDEFINED
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
-import java.util.concurrent.Executor
 
 /**
  * @hide
@@ -30,17 +30,18 @@
 open class ContiguousPagedList<K : Any, V : Any>(
     pagedSource: PagedSource<K, V>,
     coroutineScope: CoroutineScope,
-    mainThreadExecutor: Executor,
-    backgroundThreadExecutor: Executor,
+    notifyDispatcher: CoroutineDispatcher,
+    backgroundDispatcher: CoroutineDispatcher,
     boundaryCallback: BoundaryCallback<V>?,
     config: Config,
     initialResult: PagedSource.LoadResult<K, V>,
     lastLoad: Int
 ) : PagedList<V>(
+    coroutineScope,
     pagedSource,
     PagedStorage<V>(),
-    mainThreadExecutor,
-    backgroundThreadExecutor,
+    notifyDispatcher,
+    backgroundDispatcher,
     boundaryCallback,
     config
 ), PagedStorage.Callback, Pager.PageConsumer<V> {
@@ -74,8 +75,8 @@
         coroutineScope,
         config,
         pagedSource,
-        mainThreadExecutor,
-        backgroundThreadExecutor,
+        notifyDispatcher,
+        backgroundDispatcher,
         this,
         initialResult,
         storage
@@ -208,7 +209,7 @@
                 if (initialResult.itemsBefore != COUNT_UNDEFINED) initialResult.itemsBefore else 0,
                 initialResult.data,
                 if (initialResult.itemsAfter != COUNT_UNDEFINED) initialResult.itemsAfter else 0,
-                initialResult.offset,
+                0,
                 this
             )
         } else {
@@ -218,7 +219,7 @@
                 0,
                 initialResult.data,
                 0,
-                initialResult.itemsBefore + initialResult.offset,
+                if (initialResult.itemsBefore != COUNT_UNDEFINED) initialResult.itemsBefore else 0,
                 this
             )
         }
@@ -314,7 +315,10 @@
     @MainThread
     override fun onInitialized(count: Int) {
         notifyInserted(0, count)
-        // simple heuristic to decide if, when dropping pages, we should replace with placeholders
+        // Simple heuristic to decide if, when dropping pages, we should replace with placeholders.
+        // If we're not presenting placeholders at initialization time, we won't add them when
+        // we drop a page. Note that we don't use config.enablePlaceholders, since the
+        // PagedSource may have opted not to load any.
         replacePagesWithNulls = storage.leadingNullCount > 0 || storage.trailingNullCount > 0
     }
 
diff --git a/paging/common/src/main/kotlin/androidx/paging/DataSource.kt b/paging/common/src/main/kotlin/androidx/paging/DataSource.kt
index 5330acb..f3740f3 100644
--- a/paging/common/src/main/kotlin/androidx/paging/DataSource.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/DataSource.kt
@@ -472,7 +472,7 @@
             }
             if (data.isEmpty() && (leadingNulls != 0 || trailingNulls != 0)) {
                 throw IllegalArgumentException(
-                    "Initial result cannot be empty if items are" + " present in data set."
+                    "Initial result cannot be empty if items are present in data set."
                 )
             }
             if (trailingNulls < 0) {
@@ -522,12 +522,11 @@
          */
         @Suppress("UNCHECKED_CAST") // Guaranteed to be the correct Key type.
         internal fun <Key : Any> toLoadResult() = PagedSource.LoadResult(
-            if (counted) leadingNulls else COUNT_UNDEFINED,
+            data,
+            if (counted) leadingNulls else offset,
             if (counted) trailingNulls else COUNT_UNDEFINED,
             nextKey as Key?,
-            prevKey as Key?,
-            data,
-            offset
+            prevKey as Key?
         )
 
         override fun equals(other: Any?) = when (other) {
diff --git a/paging/common/src/main/kotlin/androidx/paging/InitialPagedList.kt b/paging/common/src/main/kotlin/androidx/paging/InitialPagedList.kt
index 4aa8792..7407055 100644
--- a/paging/common/src/main/kotlin/androidx/paging/InitialPagedList.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/InitialPagedList.kt
@@ -17,7 +17,7 @@
 package androidx.paging
 
 import androidx.annotation.RestrictTo
-import androidx.paging.futures.DirectExecutor
+import androidx.paging.futures.DirectDispatcher
 import kotlinx.coroutines.CoroutineScope
 
 /**
@@ -37,8 +37,8 @@
 ) : ContiguousPagedList<K, V>(
     pagedSource,
     coroutineScope,
-    DirectExecutor,
-    DirectExecutor,
+    DirectDispatcher,
+    DirectDispatcher,
     null,
     config,
     PagedSource.LoadResult.empty(),
diff --git a/paging/common/src/main/kotlin/androidx/paging/PagedList.kt b/paging/common/src/main/kotlin/androidx/paging/PagedList.kt
index 6d56579..c0bde0e 100644
--- a/paging/common/src/main/kotlin/androidx/paging/PagedList.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/PagedList.kt
@@ -28,10 +28,13 @@
 import androidx.paging.PagedList.LoadState
 import androidx.paging.PagedList.LoadType
 import androidx.paging.PagedSource.KeyProvider
-import androidx.paging.futures.DirectExecutor
+import androidx.paging.futures.DirectDispatcher
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.asCoroutineDispatcher
+import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.withContext
 import java.lang.ref.WeakReference
@@ -45,10 +48,11 @@
  *
  * Used to observe the [LoadState] of any [LoadType] (REFRESH/START/END). For UI purposes (swipe
  * refresh, loading spinner, retry button), this is typically done by registering a
- * [LoadStateListener] with the [PagedListAdapter] or [AsyncPagedListDiffer].
+ * [LoadStateListener] with the [androidx.paging.PagedListAdapter] or
+ * [androidx.paging.AsyncPagedListDiffer].
  *
- * These calls will be dispatched on the executor defined by [Builder.setNotifyExecutor], which is
- * generally the main/UI thread.
+ * These calls will be dispatched on the executor defined by [PagedList.Builder.setNotifyExecutor],
+ * which is generally the main/UI thread.
  *
  * Called when the LoadState has changed - whether the refresh, prepend, or append is idle, loading,
  * or has an error.
@@ -156,10 +160,10 @@
          * thread,posting updates to the main thread.
          *
          * @param pagedSource [PagedSource] providing data to the [PagedList]
-         * @param notifyExecutor Thread tat will use and consume data from the [PagedList].
-         * Generally, this is the UI/main thread.
-         * @param fetchExecutor Data loading will be done via this executor - should be a background
-         * thread.
+         * @param notifyDispatcher [CoroutineDispatcher] that will use and consume data from the
+         * [PagedList]. Generally, this is the UI/main thread.
+         * @param fetchDispatcher Data loading jobs will be dispatched to this
+         * [CoroutineDispatcher] - should be a background thread.
          * @param boundaryCallback Optional boundary callback to attach to the list.
          * @param config [PagedList.Config], which defines how the [PagedList] will load data.
          * @param K Key type that indicates to the [PagedSource] what data to load.
@@ -175,9 +179,9 @@
         suspend fun <K : Any, T : Any> create(
             pagedSource: PagedSource<K, T>,
             coroutineScope: CoroutineScope,
-            notifyExecutor: Executor,
-            fetchExecutor: Executor,
-            initialLoadExecutor: Executor,
+            notifyDispatcher: CoroutineDispatcher,
+            fetchDispatcher: CoroutineDispatcher,
+            initialFetchDispatcher: CoroutineDispatcher,
             boundaryCallback: BoundaryCallback<T>?,
             config: Config,
             key: K?
@@ -195,15 +199,15 @@
                 config.pageSize
             )
 
-            val initialResult = withContext(initialLoadExecutor.asCoroutineDispatcher()) {
+            val initialResult = withContext(initialFetchDispatcher) {
                 pagedSource.load(params)
             }
 
             return ContiguousPagedList(
                 pagedSource,
                 coroutineScope,
-                notifyExecutor,
-                fetchExecutor,
+                notifyDispatcher,
+                fetchDispatcher,
                 boundaryCallback,
                 config,
                 initialResult,
@@ -270,7 +274,7 @@
         /**
          * Loading hit a retryable error.
          *
-         * @see .retry
+         * @see retry
          */
         RETRYABLE_ERROR
     }
@@ -278,7 +282,7 @@
     /**
      * Builder class for [PagedList].
      *
-     * [PagedSource], [Config], main thread and background executor must all be provided.
+     * [pagedSource], [config], [notifyDispatcher] and [fetchDispatcher] must all be provided.
      *
      * A [PagedList] queries initial data from its [PagedSource] during construction, to avoid empty
      * PagedLists being presented to the UI when possible. It's preferred to present initial data,
@@ -295,8 +299,8 @@
         private val pagedSource: PagedSource<Key, Value>
         private val config: Config
         private var coroutineScope: CoroutineScope = GlobalScope
-        private var notifyExecutor: Executor? = null
-        private var fetchExecutor: Executor? = null
+        private var notifyDispatcher: CoroutineDispatcher? = null
+        private var fetchDispatcher: CoroutineDispatcher? = null
         private var boundaryCallback: BoundaryCallback<Value>? = null
         private var initialKey: Key? = null
 
@@ -378,18 +382,37 @@
         }
 
         /**
-         * The executor defining where page loading updates are dispatched.
+         * The [Executor] defining where page loading updates are dispatched.
          *
-         * @param notifyExecutor Executor that receives [PagedList] updates, and where [Callback]
+         * @param notifyExecutor [Executor] that receives [PagedList] updates, and where [Callback]
          * calls are dispatched. Generally, this is the ui/main thread.
          * @return this
          */
+        @Deprecated(
+            message = "Passing an executor will cause it get wrapped as a CoroutineDispatcher, " +
+                    "consider passing a CoroutineDispatcher directly",
+            replaceWith = ReplaceWith(
+                "setNotifyDispatcher(fetchExecutor.asCoroutineDispatcher())",
+                "kotlinx.coroutines.asCoroutineDispatcher"
+            )
+        )
         fun setNotifyExecutor(notifyExecutor: Executor) = apply {
-            this.notifyExecutor = notifyExecutor
+            this.notifyDispatcher = notifyExecutor.asCoroutineDispatcher()
         }
 
         /**
-         * The executor used to fetch additional pages from the [PagedSource].
+         * The [CoroutineDispatcher] defining where page loading updates are dispatched.
+         *
+         * @param notifyDispatcher [CoroutineDispatcher] that receives [PagedList] updates, and where
+         * [Callback] calls are dispatched. Generally, this is the ui/main thread.
+         * @return this
+         */
+        fun setNotifyDispatcher(notifyDispatcher: CoroutineDispatcher) = apply {
+            this.notifyDispatcher = notifyDispatcher
+        }
+
+        /**
+         * The [Executor] used to fetch additional pages from the [PagedSource].
          *
          * Does not affect initial load, which will be done immediately on whichever thread the
          * [PagedList] is created on.
@@ -398,8 +421,30 @@
          * thread pool for e.g. I/O or network loading.
          * @return this
          */
+        @Deprecated(
+            message = "Passing an executor will cause it get wrapped as a CoroutineDispatcher, " +
+                    "consider passing a CoroutineDispatcher directly",
+            replaceWith = ReplaceWith(
+                "setFetchDispatcher(fetchExecutor.asCoroutineDispatcher())",
+                "kotlinx.coroutines.asCoroutineDispatcher"
+            )
+        )
         fun setFetchExecutor(fetchExecutor: Executor) = apply {
-            this.fetchExecutor = fetchExecutor
+            this.fetchDispatcher = fetchExecutor.asCoroutineDispatcher()
+        }
+
+        /**
+         * The [CoroutineDispatcher] used to fetch additional pages from the [PagedSource].
+         *
+         * Does not affect initial load, which will be done immediately on whichever thread the
+         * [PagedList] is created on.
+         *
+         * @param fetchDispatcher [CoroutineDispatcher] used to fetch from [PagedSource]s,
+         * generally a background thread pool for e.g. I/O or network loading.
+         * @return this
+         */
+        fun setFetchDispatcher(fetchDispatcher: CoroutineDispatcher) = apply {
+            this.fetchDispatcher = fetchDispatcher
         }
 
         /**
@@ -444,25 +489,18 @@
          * the [PagedList] will be immediately [detached][PagedList.isDetached], and you can retry
          * construction (including setting a new [PagedSource]).
          *
-         * @throws IllegalArgumentException if [notifyExecutor] or [fetchExecutor] are not set.
+         * @throws IllegalArgumentException if [notifyDispatcher] or [fetchDispatcher] are not set.
          *
          * @return The newly constructed [PagedList]
          */
         @WorkerThread
         @Deprecated(
-            "This method has no means of handling errors encountered during initial load, and" +
-                    " blocks on the initial load result. Use {@link #buildAsync()} instead."
+            message = "This method has no means of handling errors encountered during initial " +
+                    "load, and blocks on the initial load result.",
+            replaceWith = ReplaceWith("buildAsync()")
         )
-        fun build(): PagedList<Value> {
-            // TODO: define defaults, once they can be used in module without android dependency
-            if (notifyExecutor == null) {
-                throw IllegalArgumentException("MainThreadExecutor required")
-            }
-            if (fetchExecutor == null) {
-                throw IllegalArgumentException("BackgroundThreadExecutor required")
-            }
-
-            return runBlocking { create(DirectExecutor) }
+        fun build(): PagedList<Value> = runBlocking {
+            create(DirectDispatcher)
         }
 
         /**
@@ -472,41 +510,35 @@
          * [PagedSource.LoadType.INITIAL], and return a [PagedList] once it completes, triggering
          * [loadStateListeners].
          *
-         * @throws IllegalArgumentException if [notifyExecutor] or [fetchExecutor] are not set.
+         * @throws IllegalArgumentException if [notifyDispatcher] or [fetchDispatcher] are not set.
          *
          * @return The newly constructed [PagedList]
          */
-        @Suppress("unused")
+        @Suppress("unused") // Public API
         suspend fun buildAsync(): PagedList<Value> {
-            // TODO: define defaults, once they can be used in module without android dependency
-            if (notifyExecutor == null) {
-                throw IllegalArgumentException("MainThreadExecutor required")
-            }
-            if (fetchExecutor == null) {
-                throw IllegalArgumentException("BackgroundThreadExecutor required")
-            }
-
-            return create(fetchExecutor!!)
+            return create(fetchDispatcher ?: Dispatchers.IO)
         }
 
-        private suspend fun create(initialFetchExecutor: Executor): PagedList<Value> =
-            create(
+        private suspend fun create(initialFetchDispatcher: CoroutineDispatcher): PagedList<Value> {
+            return create(
                 pagedSource,
                 coroutineScope,
-                notifyExecutor!!,
-                fetchExecutor!!,
-                initialFetchExecutor,
+                notifyDispatcher ?: Dispatchers.Main,
+                fetchDispatcher ?: Dispatchers.IO,
+                initialFetchDispatcher,
                 boundaryCallback,
                 config,
                 initialKey
             )
+        }
     }
 
     /**
      * Callback signaling when content is loaded into the list.
      *
      * Can be used to listen to items being paged in and out. These calls will be dispatched on
-     * the executor defined by [Builder.setNotifyExecutor], which is generally the main/UI thread.
+     * the dispatcher defined by [Builder.setNotifyDispatcher], which is generally the main/UI
+     * thread.
      */
     abstract class Callback {
         /**
@@ -924,19 +956,21 @@
     /**
      * @hide
      */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     constructor(
+        coroutineScope: CoroutineScope,
         pagedSource: PagedSource<*, T>,
         storage: PagedStorage<T>,
-        mainThreadExecutor: Executor,
-        backgroundThreadExecutor: Executor,
+        notifyDispatcher: CoroutineDispatcher,
+        backgroundDispatcher: CoroutineDispatcher,
         boundaryCallback: BoundaryCallback<T>?,
         config: Config
     ) : super() {
+        this.coroutineScope = coroutineScope
         this.pagedSource = pagedSource
         this.storage = storage
-        this.mainThreadExecutor = mainThreadExecutor
-        this.backgroundThreadExecutor = backgroundThreadExecutor
+        this.notifyDispatcher = notifyDispatcher
+        this.backgroundDispatcher = backgroundDispatcher
         this.boundaryCallback = boundaryCallback
         this.config = config
         this.callbacks = ArrayList()
@@ -952,8 +986,9 @@
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) // protected otherwise
     fun getStorage() = storage
 
-    internal val mainThreadExecutor: Executor
-    internal val backgroundThreadExecutor: Executor
+    internal val notifyDispatcher: CoroutineDispatcher
+    internal val backgroundDispatcher: CoroutineDispatcher
+
     internal val boundaryCallback: BoundaryCallback<T>?
 
     internal var refreshRetryCallback: Runnable? = null
@@ -978,6 +1013,8 @@
      */
     open val config: Config
 
+    internal val coroutineScope: CoroutineScope
+
     private val callbacks: MutableList<WeakReference<Callback>>
 
     private val loadStateListeners: MutableList<WeakReference<LoadStateListener>>
@@ -1012,7 +1049,10 @@
      * @throws IllegalStateException if this [PagedList] was instantiated without a
      * [PagedSourceWrapper] wrapping a backing [DataSource]
      */
-    @Deprecated("DataSource is deprecated and has been replaced by PagedSource")
+    @Deprecated(
+        message = "DataSource is deprecated and has been replaced by PagedSource",
+        replaceWith = ReplaceWith("pagedSource")
+    )
     val dataSource: DataSource<*, T>
         get() {
             if (pagedSource is PagedSourceWrapper) return pagedSource.dataSource
@@ -1219,7 +1259,7 @@
 
         if (deferEmpty || deferBegin || deferEnd) {
             // Post to the main thread, since we may be on creation thread currently
-            mainThreadExecutor.execute {
+            coroutineScope.launch(notifyDispatcher) {
                 // on is dispatched immediately, since items won't be accessed
 
                 if (deferEmpty) {
@@ -1258,7 +1298,9 @@
             boundaryCallbackEndDeferred = false
         }
         if (post) {
-            mainThreadExecutor.execute { dispatchBoundaryCallbacks(dispatchBegin, dispatchEnd) }
+            coroutineScope.launch(notifyDispatcher) {
+                dispatchBoundaryCallbacks(dispatchBegin, dispatchEnd)
+            }
         } else {
             dispatchBoundaryCallbacks(dispatchBegin, dispatchEnd)
         }
@@ -1409,8 +1451,8 @@
  * @param Value Type of items held and loaded by the [PagedList].
  * @param dataSource [DataSource] the [PagedList] will load from.
  * @param config Config that defines how the [PagedList] loads data from its [DataSource].
- * @param notifyExecutor Executor that receives [PagedList] updates, and where [PagedList.Callback]
- * calls are dispatched. Generally, this is the UI/main thread.
+ * @param notifyExecutor [Executor] that receives [PagedList] updates, and where
+ * [PagedList.Callback] calls are dispatched. Generally, this is the UI/main thread.
  * @param fetchExecutor [Executor] used to fetch from [DataSource]s, generally a background thread
  * pool for e.g. I/O or network loading.
  * @param boundaryCallback [PagedList.BoundaryCallback] for listening to out-of-data events.
diff --git a/paging/common/src/main/kotlin/androidx/paging/PagedListConfig.kt b/paging/common/src/main/kotlin/androidx/paging/PagedListConfig.kt
index 47676e2..06a2157 100644
--- a/paging/common/src/main/kotlin/androidx/paging/PagedListConfig.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/PagedListConfig.kt
@@ -16,23 +16,26 @@
 
 package androidx.paging
 
+import androidx.paging.PagedList.Config.Builder.Companion.DEFAULT_INITIAL_PAGE_MULTIPLIER
+import androidx.paging.PagedList.Config.Companion.MAX_SIZE_UNBOUNDED
+
 /**
  * Constructs a [PagedList.Config], convenience for [PagedList.Config.Builder].
  *
- * @param pageSize Number of items loaded at once from the DataSource.
+ * @param pageSize Number of items loaded at once from the [DataSource].
  * @param prefetchDistance Distance the PagedList should prefetch.
  * @param enablePlaceholders False if null placeholders should be disabled.
  * @param initialLoadSizeHint Number of items to load while initializing the PagedList.
  * @param maxSize Maximum number of items to keep in memory, or
- *                [PagedList.Config.MAX_SIZE_UNBOUNDED] to disable page dropping.
+ * [PagedList.Config.MAX_SIZE_UNBOUNDED] to disable page dropping.
  */
 @Suppress("FunctionName")
 fun Config(
     pageSize: Int,
     prefetchDistance: Int = pageSize,
     enablePlaceholders: Boolean = true,
-    initialLoadSizeHint: Int = pageSize * PagedList.Config.Builder.DEFAULT_INITIAL_PAGE_MULTIPLIER,
-    maxSize: Int = PagedList.Config.MAX_SIZE_UNBOUNDED
+    initialLoadSizeHint: Int = pageSize * DEFAULT_INITIAL_PAGE_MULTIPLIER,
+    maxSize: Int = MAX_SIZE_UNBOUNDED
 ): PagedList.Config {
     return PagedList.Config.Builder()
         .setPageSize(pageSize)
diff --git a/paging/common/src/main/kotlin/androidx/paging/PagedSource.kt b/paging/common/src/main/kotlin/androidx/paging/PagedSource.kt
index 90542b1..38feb36 100644
--- a/paging/common/src/main/kotlin/androidx/paging/PagedSource.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/PagedSource.kt
@@ -134,6 +134,10 @@
      */
     data class LoadResult<Key : Any, Value : Any>(
         /**
+         * Loaded data
+         */
+        val data: List<Value>,
+        /**
          * Optional count of items before the loaded data.
          */
         @IntRange(from = COUNT_UNDEFINED.toLong())
@@ -150,19 +154,7 @@
         /**
          * Key for previous page - ignored unless you're using [KeyProvider.PageKey]
          */
-        val prevKey: Key? = null,
-        /**
-         * Loaded data
-         */
-        val data: List<Value>,
-        /**
-         * Only one of [itemsBefore] or [offset] should be used. This is a temporary placeholder
-         * shadowing [DataSource.BaseResult.offset] which simply forwards the params to backing
-         * implementations of [PagedSource].
-         *
-         * TODO: Investigate refactoring this out of the API now that tiling has been removed.
-         */
-        val offset: Int
+        val prevKey: Key? = null
     ) {
         internal val counted = itemsBefore != COUNT_UNDEFINED && itemsAfter != COUNT_UNDEFINED
 
@@ -170,7 +162,7 @@
             const val COUNT_UNDEFINED = -1
 
             @Suppress("MemberVisibilityCanBePrivate") // Prevent synthetic accessor generation.
-            internal val EMPTY = LoadResult(0, 0, null, null, emptyList(), 0)
+            internal val EMPTY = LoadResult(emptyList(), 0, 0, null, null)
 
             @Suppress("UNCHECKED_CAST") // Can safely ignore, since the list is empty.
             internal fun <Key : Any, Value : Any> empty() = EMPTY as LoadResult<Key, Value>
@@ -185,15 +177,21 @@
      * * [ItemKey] Data in the last item in the page is used to load the next. Ideal for DB
      * pagination; offers granular continuation after [invalidate].
      */
-    sealed class KeyProvider<Key : Any, Value : Any> {
-        class Positional<Value : Any> : KeyProvider<Int, Value>()
+    sealed class KeyProvider<Key : Any, in Value : Any> {
+        object Positional : KeyProvider<Int, Any>()
         class PageKey<Key : Any, Value : Any> : KeyProvider<Key, Value>()
         abstract class ItemKey<Key : Any, Value : Any> : KeyProvider<Key, Value>() {
             abstract fun getKey(item: Value): Key
         }
+
+        internal companion object {
+            val pageKeyGlobal = PageKey<Any, Any>()
+            @Suppress("UNCHECKED_CAST")
+            fun <Key : Any, Value : Any> PageKeyGlobal() = pageKeyGlobal as PageKey<Key, Value>
+        }
     }
 
-    abstract val keyProvider: KeyProvider<Key, Value>
+    open val keyProvider: KeyProvider<Key, Value> = KeyProvider.PageKeyGlobal()
 
     private val onInvalidatedCallbacks = CopyOnWriteArrayList<() -> Unit>()
 
@@ -256,5 +254,5 @@
      * @param error Throwable returned from an attempted load from this [PagedSource].
      * @return `false` if the observed error should never be retried, `true` otherwise.
      */
-    abstract fun isRetryableError(error: Throwable): Boolean
+    open fun isRetryableError(error: Throwable): Boolean = true
 }
diff --git a/paging/common/src/main/kotlin/androidx/paging/PagedSourceWrapper.kt b/paging/common/src/main/kotlin/androidx/paging/PagedSourceWrapper.kt
index 38c7a8d..c6bb7a7 100644
--- a/paging/common/src/main/kotlin/androidx/paging/PagedSourceWrapper.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/PagedSourceWrapper.kt
@@ -33,12 +33,10 @@
         dataSource.addInvalidatedCallback { invalidate() }
     }
 
-    override val keyProvider: KeyProvider<Key, Value> = when (dataSource.type) {
-        DataSource.KeyType.POSITIONAL -> {
-            @Suppress("UNCHECKED_CAST") // Guaranteed to be the correct key type.
-            KeyProvider.Positional<Value>() as KeyProvider<Key, Value>
-        }
-        DataSource.KeyType.PAGE_KEYED -> KeyProvider.PageKey()
+    @Suppress("UNCHECKED_CAST")
+    override val keyProvider = when (dataSource.type) {
+        DataSource.KeyType.POSITIONAL -> KeyProvider.Positional as KeyProvider<Key, Value>
+        DataSource.KeyType.PAGE_KEYED -> KeyProvider.PageKeyGlobal()
         DataSource.KeyType.ITEM_KEYED -> object : KeyProvider.ItemKey<Key, Value>() {
             override fun getKey(item: Value) = dataSource.getKeyInternal(item)
         }
diff --git a/paging/common/src/main/kotlin/androidx/paging/Pager.kt b/paging/common/src/main/kotlin/androidx/paging/Pager.kt
index ca811d1..cf42fd4 100644
--- a/paging/common/src/main/kotlin/androidx/paging/Pager.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/Pager.kt
@@ -18,21 +18,23 @@
 
 import androidx.paging.PagedList.LoadState
 import androidx.paging.PagedList.LoadType
+import androidx.paging.PagedSource.KeyProvider
+import androidx.paging.PagedSource.LoadParams
+import androidx.paging.PagedSource.LoadResult
 import androidx.paging.PagedSource.LoadResult.Companion.COUNT_UNDEFINED
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.asCoroutineDispatcher
 import kotlinx.coroutines.launch
-import java.util.concurrent.Executor
 import java.util.concurrent.atomic.AtomicBoolean
 
 internal class Pager<K : Any, V : Any>(
     private val pagedListScope: CoroutineScope,
     val config: PagedList.Config,
     val source: PagedSource<K, V>,
-    val notifyExecutor: Executor,
-    private val fetchExecutor: Executor,
+    private val notifyDispatcher: CoroutineDispatcher,
+    private val fetchDispatcher: CoroutineDispatcher,
     val pageConsumer: PageConsumer<V>,
-    result: PagedSource.LoadResult<K, V>,
+    result: LoadResult<K, V>,
     private val adjacentProvider: AdjacentProvider<V> = SimpleAdjacentProvider()
 ) {
     private val totalCount: Int
@@ -54,16 +56,16 @@
         this.adjacentProvider.onPageResultResolution(LoadType.REFRESH, result)
         totalCount = when (result.counted) {
             // only one of leadingNulls / offset may be used
-            true -> result.itemsBefore + result.offset + result.data.size + result.itemsAfter
+            true -> result.itemsBefore + result.data.size + result.itemsAfter
             else -> COUNT_UNDEFINED
         }
     }
 
-    private fun listenTo(type: LoadType, future: suspend () -> PagedSource.LoadResult<K, V>) {
+    private fun scheduleLoad(type: LoadType, params: LoadParams<K>) {
         // Listen on the BG thread if the paged source is invalid, since it can be expensive.
-        pagedListScope.launch(fetchExecutor.asCoroutineDispatcher()) {
+        pagedListScope.launch(fetchDispatcher) {
             try {
-                val value = future()
+                val value = source.load(params)
 
                 // if invalid, drop result on the floor
                 if (source.invalid) {
@@ -72,43 +74,18 @@
                 }
 
                 // Source has been verified to be valid after producing data, so sent data to UI
-                launch(notifyExecutor.asCoroutineDispatcher()) {
+                launch(notifyDispatcher) {
                     onLoadSuccess(type, value)
                 }
             } catch (throwable: Throwable) {
-                launch(notifyExecutor.asCoroutineDispatcher()) {
+                launch(notifyDispatcher) {
                     onLoadError(type, throwable)
                 }
             }
         }
     }
 
-    internal interface PageConsumer<V : Any> {
-        /**
-         * @return `true` if we need to fetch more
-         */
-        fun onPageResult(type: LoadType, pageResult: PagedSource.LoadResult<*, V>): Boolean
-
-        fun onStateChanged(type: LoadType, state: LoadState, error: Throwable?)
-    }
-
-    internal interface AdjacentProvider<V : Any> {
-        val firstLoadedItem: V?
-        val lastLoadedItem: V?
-        val firstLoadedItemIndex: Int
-        val lastLoadedItemIndex: Int
-
-        /**
-         * Notify the [AdjacentProvider] of new loaded data, to update first/last item/index.
-         *
-         * NOTE: this data may not be committed (e.g. it may be dropped due to max size). Up to the
-         * implementation of the AdjacentProvider to handle this (generally by ignoring this call if
-         * dropping is supported).
-         */
-        fun onPageResultResolution(type: LoadType, result: PagedSource.LoadResult<*, V>)
-    }
-
-    private fun onLoadSuccess(type: LoadType, value: PagedSource.LoadResult<K, V>) {
+    private fun onLoadSuccess(type: LoadType, value: LoadResult<K, V>) {
         if (isDetached) return // abort!
 
         adjacentProvider.onPageResultResolution(type, value)
@@ -166,63 +143,57 @@
 
     private fun schedulePrepend() {
         if (!canPrepend()) {
-            onLoadSuccess(LoadType.START, PagedSource.LoadResult.empty())
+            onLoadSuccess(LoadType.START, LoadResult.empty())
             return
         }
 
         val key = when (val keyProvider = source.keyProvider) {
-            is PagedSource.KeyProvider.Positional -> {
+            is KeyProvider.Positional -> {
                 @Suppress("UNCHECKED_CAST")
                 (adjacentProvider.firstLoadedItemIndex - 1) as K
             }
-            is PagedSource.KeyProvider.PageKey -> prevKey
-            is PagedSource.KeyProvider.ItemKey -> keyProvider.getKey(
-                adjacentProvider.firstLoadedItem!!
-            )
+            is KeyProvider.PageKey -> prevKey
+            is KeyProvider.ItemKey -> keyProvider.getKey(adjacentProvider.firstLoadedItem!!)
         }
 
         loadStateManager.setState(LoadType.START, LoadState.LOADING, null)
-        listenTo(LoadType.START) {
-            source.load(
-                PagedSource.LoadParams(
-                    PagedSource.LoadType.START,
-                    key,
-                    config.pageSize,
-                    config.enablePlaceholders,
-                    config.pageSize
-                )
-            )
-        }
+
+        val loadParams = LoadParams(
+            PagedSource.LoadType.START,
+            key,
+            config.pageSize,
+            config.enablePlaceholders,
+            config.pageSize
+        )
+        scheduleLoad(LoadType.START, loadParams)
     }
 
     private fun scheduleAppend() {
         if (!canAppend()) {
-            onLoadSuccess(LoadType.END, PagedSource.LoadResult.empty())
+            onLoadSuccess(LoadType.END, LoadResult.empty())
             return
         }
 
         val key = when (val keyProvider = source.keyProvider) {
-            is PagedSource.KeyProvider.Positional ->
+            is KeyProvider.Positional -> {
                 @Suppress("UNCHECKED_CAST")
                 (adjacentProvider.lastLoadedItemIndex + 1) as K
-            is PagedSource.KeyProvider.PageKey -> nextKey
-            is PagedSource.KeyProvider.ItemKey -> keyProvider.getKey(
+            }
+            is KeyProvider.PageKey -> nextKey
+            is KeyProvider.ItemKey -> keyProvider.getKey(
                 adjacentProvider.lastLoadedItem!!
             )
         }
 
         loadStateManager.setState(LoadType.END, LoadState.LOADING, null)
-        listenTo(LoadType.END) {
-            source.load(
-                PagedSource.LoadParams(
-                    PagedSource.LoadType.END,
-                    key,
-                    config.pageSize,
-                    config.enablePlaceholders,
-                    config.pageSize
-                )
-            )
-        }
+        val loadParams = LoadParams(
+            PagedSource.LoadType.END,
+            key,
+            config.pageSize,
+            config.enablePlaceholders,
+            config.pageSize
+        )
+        scheduleLoad(LoadType.END, loadParams)
     }
 
     fun retry() {
@@ -232,6 +203,31 @@
 
     fun detach() = detached.set(true)
 
+    internal interface PageConsumer<V : Any> {
+        /**
+         * @return `true` if we need to fetch more
+         */
+        fun onPageResult(type: LoadType, pageResult: LoadResult<*, V>): Boolean
+
+        fun onStateChanged(type: LoadType, state: LoadState, error: Throwable?)
+    }
+
+    internal interface AdjacentProvider<V : Any> {
+        val firstLoadedItem: V?
+        val lastLoadedItem: V?
+        val firstLoadedItemIndex: Int
+        val lastLoadedItemIndex: Int
+
+        /**
+         * Notify the [AdjacentProvider] of new loaded data, to update first/last item/index.
+         *
+         * NOTE: this data may not be committed (e.g. it may be dropped due to max size). Up to the
+         * implementation of the AdjacentProvider to handle this (generally by ignoring this call if
+         * dropping is supported).
+         */
+        fun onPageResultResolution(type: LoadType, result: LoadResult<*, V>)
+    }
+
     internal class SimpleAdjacentProvider<V : Any> : AdjacentProvider<V> {
         override var firstLoadedItemIndex: Int = 0
             private set
@@ -246,7 +242,7 @@
         private var leadingUnloadedCount: Int = 0
         private var trailingUnloadedCount: Int = 0
 
-        override fun onPageResultResolution(type: LoadType, result: PagedSource.LoadResult<*, V>) {
+        override fun onPageResultResolution(type: LoadType, result: LoadResult<*, V>) {
             if (result.data.isEmpty()) return
 
             if (type == LoadType.START) {
@@ -262,7 +258,7 @@
                     trailingUnloadedCount -= result.data.size
                 }
             } else {
-                firstLoadedItemIndex = result.itemsBefore + result.offset
+                firstLoadedItemIndex = result.itemsBefore
                 lastLoadedItemIndex = firstLoadedItemIndex + result.data.size - 1
                 firstLoadedItem = result.data[0]
                 lastLoadedItem = result.data.last()
diff --git a/paging/common/src/main/kotlin/androidx/paging/SnapshotPagedList.kt b/paging/common/src/main/kotlin/androidx/paging/SnapshotPagedList.kt
index 5688543..a0b556b 100644
--- a/paging/common/src/main/kotlin/androidx/paging/SnapshotPagedList.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/SnapshotPagedList.kt
@@ -17,10 +17,11 @@
 package androidx.paging
 
 internal class SnapshotPagedList<T : Any>(private val pagedList: PagedList<T>) : PagedList<T>(
+    pagedList.coroutineScope,
     pagedList.pagedSource,
     pagedList.storage.snapshot(),
-    pagedList.mainThreadExecutor,
-    pagedList.backgroundThreadExecutor,
+    pagedList.notifyDispatcher,
+    pagedList.backgroundDispatcher,
     null,
     pagedList.config
 ) {
diff --git a/paging/common/src/main/kotlin/androidx/paging/futures/DirectDispatcher.kt b/paging/common/src/main/kotlin/androidx/paging/futures/DirectDispatcher.kt
new file mode 100644
index 0000000..436f49a
--- /dev/null
+++ b/paging/common/src/main/kotlin/androidx/paging/futures/DirectDispatcher.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2019 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.paging.futures
+
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlin.coroutines.CoroutineContext
+
+/**
+ * [CoroutineDispatcher] which immediately runs new jobs on the current thread.
+ */
+internal object DirectDispatcher : CoroutineDispatcher() {
+    override fun dispatch(context: CoroutineContext, block: Runnable) {
+        block.run()
+    }
+}
diff --git a/paging/common/src/test/kotlin/androidx/paging/ContiguousPagedListTest.kt b/paging/common/src/test/kotlin/androidx/paging/ContiguousPagedListTest.kt
index c548b73..03934fe 100644
--- a/paging/common/src/test/kotlin/androidx/paging/ContiguousPagedListTest.kt
+++ b/paging/common/src/test/kotlin/androidx/paging/ContiguousPagedListTest.kt
@@ -20,8 +20,8 @@
 import androidx.paging.PagedList.LoadState.IDLE
 import androidx.paging.PagedList.LoadState.LOADING
 import androidx.paging.PagedList.LoadState.RETRYABLE_ERROR
-import androidx.paging.futures.DirectExecutor
-import androidx.testutils.TestExecutor
+import androidx.paging.futures.DirectDispatcher
+import androidx.testutils.TestDispatcher
 import com.nhaarman.mockitokotlin2.mock
 import com.nhaarman.mockitokotlin2.reset
 import com.nhaarman.mockitokotlin2.verify
@@ -39,8 +39,8 @@
 
 @RunWith(Parameterized::class)
 class ContiguousPagedListTest(private val placeholdersEnabled: Boolean) {
-    private val mainThread = TestExecutor()
-    private val backgroundThread = TestExecutor()
+    private val mainThread = TestDispatcher()
+    private val backgroundThread = TestDispatcher()
 
     private class Item(position: Int) {
         val pos: Int = position
@@ -84,25 +84,24 @@
             return when {
                 result == null -> throw Exception()
                 placeholdersEnabled -> LoadResult(
-                    itemsBefore = start,
-                    itemsAfter = listData.size - result.size - start,
                     data = result,
-                    offset = start
+                    itemsBefore = start,
+                    itemsAfter = listData.size - result.size - start
                 )
-                else -> LoadResult(data = result, offset = 0)
+                else -> LoadResult(result)
             }
         }
 
         private fun loadAfter(params: LoadParams<Int>): LoadResult<Int, Item> {
             val result = getClampedRange(params.key!! + 1, params.key!! + 1 + params.loadSize)
                 ?: throw Exception()
-            return LoadResult(data = result, offset = 0)
+            return LoadResult(result)
         }
 
         private fun loadBefore(params: LoadParams<Int>): LoadResult<Int, Item> {
             val result =
                 getClampedRange(params.key!! - params.loadSize, params.key!!) ?: throw Exception()
-            return LoadResult(data = result, offset = 0)
+            return LoadResult(result)
         }
 
         private fun getClampedRange(startInc: Int, endExc: Int): List<Item>? {
@@ -179,7 +178,7 @@
                 GlobalScope,
                 mainThread,
                 backgroundThread,
-                DirectExecutor,
+                DirectDispatcher,
                 boundaryCallback,
                 PagedList.Config.Builder()
                     .setPageSize(pageSize)
@@ -212,9 +211,9 @@
             PagedList.create(
                 PagedSourceWrapper(ItemDataSource()),
                 GlobalScope,
-                FailExecutor(),
-                DirectExecutor,
-                DirectExecutor,
+                FailDispatcher(),
+                DirectDispatcher,
+                DirectDispatcher,
                 null,
                 PagedList.Config.Builder().setPageSize(10).build(),
                 null
@@ -902,11 +901,10 @@
     }
 
     private fun drain() {
-        var executed: Boolean
-        do {
-            executed = backgroundThread.executeAll()
-            executed = mainThread.executeAll() || executed
-        } while (executed)
+        while (backgroundThread.queue.isNotEmpty() || mainThread.queue.isNotEmpty()) {
+            backgroundThread.executeAll()
+            mainThread.executeAll()
+        }
     }
 
     companion object {
diff --git a/paging/common/src/test/kotlin/androidx/paging/FailDispatcher.kt b/paging/common/src/test/kotlin/androidx/paging/FailDispatcher.kt
new file mode 100644
index 0000000..9e41203
--- /dev/null
+++ b/paging/common/src/test/kotlin/androidx/paging/FailDispatcher.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 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.paging
+
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Runnable
+import org.junit.Assert.fail
+import kotlin.coroutines.CoroutineContext
+
+class FailDispatcher(
+    val string: String = "Executor expected to be unused"
+) : CoroutineDispatcher() {
+    override fun dispatch(context: CoroutineContext, block: Runnable) {
+        fail(string)
+    }
+}
diff --git a/paging/common/src/test/kotlin/androidx/paging/FailExecutor.kt b/paging/common/src/test/kotlin/androidx/paging/FailExecutor.kt
deleted file mode 100644
index 1c2b0d5..0000000
--- a/paging/common/src/test/kotlin/androidx/paging/FailExecutor.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2017 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.paging
-
-import org.junit.Assert.fail
-import java.util.concurrent.Executor
-
-class FailExecutor(val string: String = "Executor expected to be unused") : Executor {
-    override fun execute(runnable: Runnable?) {
-        fail(string)
-    }
-}
diff --git a/paging/common/src/test/kotlin/androidx/paging/ItemKeyedDataSourceTest.kt b/paging/common/src/test/kotlin/androidx/paging/ItemKeyedDataSourceTest.kt
index 4068366..36a6381 100644
--- a/paging/common/src/test/kotlin/androidx/paging/ItemKeyedDataSourceTest.kt
+++ b/paging/common/src/test/kotlin/androidx/paging/ItemKeyedDataSourceTest.kt
@@ -17,6 +17,7 @@
 package androidx.paging
 
 import androidx.paging.futures.DirectExecutor
+import androidx.paging.futures.DirectDispatcher
 import com.nhaarman.mockitokotlin2.capture
 import com.nhaarman.mockitokotlin2.mock
 import kotlinx.coroutines.GlobalScope
@@ -291,9 +292,9 @@
             PagedList.create(
                 PagedSourceWrapper(dataSource),
                 GlobalScope,
-                FailExecutor(),
-                DirectExecutor,
-                DirectExecutor,
+                FailDispatcher(),
+                DirectDispatcher,
+                DirectDispatcher,
                 null,
                 PagedList.Config.Builder()
                     .setPageSize(10)
diff --git a/paging/common/src/test/kotlin/androidx/paging/PageKeyedDataSourceTest.kt b/paging/common/src/test/kotlin/androidx/paging/PageKeyedDataSourceTest.kt
index af58970..11b7cda 100644
--- a/paging/common/src/test/kotlin/androidx/paging/PageKeyedDataSourceTest.kt
+++ b/paging/common/src/test/kotlin/androidx/paging/PageKeyedDataSourceTest.kt
@@ -16,11 +16,10 @@
 
 package androidx.paging
 
-import androidx.paging.futures.DirectExecutor
-import androidx.testutils.TestExecutor
+import androidx.paging.futures.DirectDispatcher
+import androidx.testutils.TestDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.asCoroutineDispatcher
 import kotlinx.coroutines.async
 import kotlinx.coroutines.runBlocking
 import org.junit.Assert.assertEquals
@@ -39,8 +38,8 @@
 
 @RunWith(JUnit4::class)
 class PageKeyedDataSourceTest {
-    private val mainThread = TestExecutor()
-    private val backgroundThread = TestExecutor()
+    private val mainThread = TestDispatcher()
+    private val backgroundThread = TestDispatcher()
 
     internal data class Item(val name: String)
 
@@ -94,7 +93,7 @@
     fun loadFullVerify() {
         // validate paging entire ItemDataSource results in full, correctly ordered data
         val testCoroutineScope = CoroutineScope(EmptyCoroutineContext)
-        val pagedListJob = testCoroutineScope.async(backgroundThread.asCoroutineDispatcher()) {
+        val pagedListJob = testCoroutineScope.async(backgroundThread) {
             PagedList.create(
                 PagedSourceWrapper(ItemDataSource()),
                 testCoroutineScope,
@@ -160,9 +159,9 @@
             PagedList.create(
                 PagedSourceWrapper(dataSource),
                 GlobalScope,
-                FailExecutor(),
-                DirectExecutor,
-                DirectExecutor,
+                FailDispatcher(),
+                DirectDispatcher,
+                DirectDispatcher,
                 null,
                 PagedList.Config.Builder()
                     .setPageSize(10)
@@ -260,16 +259,16 @@
         @Suppress("UNCHECKED_CAST")
         val boundaryCallback =
             mock(PagedList.BoundaryCallback::class.java) as PagedList.BoundaryCallback<String>
-        val executor = TestExecutor()
+        val dispatcher = TestDispatcher()
 
         val testCoroutineScope = CoroutineScope(EmptyCoroutineContext)
-        val pagedListJob = testCoroutineScope.async(executor.asCoroutineDispatcher()) {
+        val pagedListJob = testCoroutineScope.async(dispatcher) {
             PagedList.create(
                 PagedSourceWrapper(dataSource),
                 testCoroutineScope,
-                executor,
-                executor,
-                executor,
+                dispatcher,
+                dispatcher,
+                dispatcher,
                 boundaryCallback,
                 PagedList.Config.Builder()
                     .setPageSize(10)
@@ -278,14 +277,14 @@
             )
         }
 
-        executor.executeAll()
+        dispatcher.executeAll()
 
         val pagedList = runBlocking { pagedListJob.await() }
         pagedList.loadAround(0)
 
         verifyZeroInteractions(boundaryCallback)
 
-        executor.executeAll()
+        dispatcher.executeAll()
 
         // verify boundary callbacks are triggered
         verify(boundaryCallback).onItemAtFrontLoaded("A")
@@ -322,16 +321,16 @@
         @Suppress("UNCHECKED_CAST")
         val boundaryCallback =
             mock(PagedList.BoundaryCallback::class.java) as PagedList.BoundaryCallback<String>
-        val executor = TestExecutor()
+        val dispatcher = TestDispatcher()
 
         val testCoroutineScope = CoroutineScope(EmptyCoroutineContext)
-        val pagedListJob = testCoroutineScope.async(executor.asCoroutineDispatcher()) {
+        val pagedListJob = testCoroutineScope.async(dispatcher) {
             PagedList.create(
                 PagedSourceWrapper(dataSource),
                 testCoroutineScope,
-                executor,
-                executor,
-                executor,
+                dispatcher,
+                dispatcher,
+                dispatcher,
                 boundaryCallback,
                 PagedList.Config.Builder()
                     .setPageSize(10)
@@ -339,14 +338,14 @@
                 ""
             )
         }
-        executor.executeAll()
+        dispatcher.executeAll()
         val pagedList = runBlocking { pagedListJob.await() }
 
         pagedList.loadAround(0)
 
         verifyZeroInteractions(boundaryCallback)
 
-        executor.executeAll()
+        dispatcher.executeAll()
 
         // verify boundary callbacks are triggered
         verify(boundaryCallback).onItemAtFrontLoaded("B")
@@ -516,7 +515,6 @@
         private const val INIT_KEY: String = "key 2"
         private val PAGE_MAP: Map<String, Page>
         private val ITEM_LIST: List<Item>
-        private val EXCEPTION = Exception()
 
         init {
             val map = HashMap<String, Page>()
@@ -537,10 +535,9 @@
     }
 
     private fun drain() {
-        var executed: Boolean
-        do {
-            executed = backgroundThread.executeAll()
-            executed = mainThread.executeAll() || executed
-        } while (executed)
+        while (backgroundThread.queue.isNotEmpty() || mainThread.queue.isNotEmpty()) {
+            backgroundThread.executeAll()
+            mainThread.executeAll()
+        }
     }
 }
diff --git a/paging/common/src/test/kotlin/androidx/paging/PagedListConfigBuilderTest.kt b/paging/common/src/test/kotlin/androidx/paging/PagedListConfigBuilderTest.kt
index f162572..05faea4 100644
--- a/paging/common/src/test/kotlin/androidx/paging/PagedListConfigBuilderTest.kt
+++ b/paging/common/src/test/kotlin/androidx/paging/PagedListConfigBuilderTest.kt
@@ -26,8 +26,8 @@
     @Test
     fun defaults() {
         val config = PagedList.Config.Builder()
-                .setPageSize(10)
-                .build()
+            .setPageSize(10)
+            .build()
         Assert.assertEquals(10, config.pageSize)
         Assert.assertEquals(30, config.initialLoadSizeHint)
         Assert.assertEquals(true, config.enablePlaceholders)
@@ -38,18 +38,18 @@
     @Test(expected = IllegalArgumentException::class)
     fun maxSizeTooSmall() {
         PagedList.Config.Builder()
-                .setPageSize(20)
-                .setPrefetchDistance(15)
-                .setMaxSize(49)
-                .build()
+            .setPageSize(20)
+            .setPrefetchDistance(15)
+            .setMaxSize(49)
+            .build()
     }
 
     @Test
     fun maxSizeAccepted() {
         PagedList.Config.Builder()
-                .setPageSize(20)
-                .setPrefetchDistance(15)
-                .setMaxSize(50)
-                .build()
+            .setPageSize(20)
+            .setPrefetchDistance(15)
+            .setMaxSize(50)
+            .build()
     }
 }
diff --git a/paging/common/src/test/kotlin/androidx/paging/PagedListTest.kt b/paging/common/src/test/kotlin/androidx/paging/PagedListTest.kt
index 4cad7b8..eba29cb 100644
--- a/paging/common/src/test/kotlin/androidx/paging/PagedListTest.kt
+++ b/paging/common/src/test/kotlin/androidx/paging/PagedListTest.kt
@@ -16,10 +16,10 @@
 
 package androidx.paging
 
-import androidx.paging.futures.DirectExecutor
+import androidx.paging.futures.DirectDispatcher
+import androidx.testutils.TestDispatcher
 import androidx.testutils.TestExecutor
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.asCoroutineDispatcher
 import kotlinx.coroutines.async
 import kotlinx.coroutines.runBlocking
 import org.junit.Assert.assertEquals
@@ -36,15 +36,14 @@
         private val config = Config(10)
 
         private val pagedSource = object : PagedSource<Int, String>() {
-            override val keyProvider = KeyProvider.Positional<String>()
+            override val keyProvider = KeyProvider.Positional
 
             override suspend fun load(params: LoadParams<Int>): LoadResult<Int, String> =
                 when (params.loadType) {
                     LoadType.INITIAL -> LoadResult(
-                        0,
-                        0,
                         data = listOf("a"),
-                        offset = 0
+                        itemsBefore = 0,
+                        itemsAfter = 0
                     )
                     else -> throw NotImplementedError("Test should fail if we get here")
                 }
@@ -54,15 +53,15 @@
     }
 
     private val testCoroutineScope = CoroutineScope(EmptyCoroutineContext)
-    private val mainThread = TestExecutor()
-    private val backgroundThread = TestExecutor()
+    private val mainThread = TestDispatcher()
+    private val backgroundThread = TestDispatcher()
 
     @Test
-    fun createLegacy() = runBlocking {
+    fun createLegacy() {
         @Suppress("DEPRECATION")
         val pagedList = PagedList.Builder(ListDataSource(ITEMS), 100)
-            .setNotifyExecutor(mainThread)
-            .setFetchExecutor(backgroundThread)
+            .setNotifyExecutor(TestExecutor())
+            .setFetchExecutor(TestExecutor())
             .build()
         // if build succeeds without flushing an executor, success!
         assertEquals(ITEMS, pagedList)
@@ -76,7 +75,7 @@
             .build()
         var success = false
 
-        val job = testCoroutineScope.async(backgroundThread.asCoroutineDispatcher()) {
+        val job = testCoroutineScope.async(backgroundThread) {
             val pagedList = PagedList.create(
                 PagedSourceWrapper(ListDataSource(ITEMS)),
                 testCoroutineScope,
@@ -101,7 +100,7 @@
     @Test
     fun createAsyncThrow() {
         val pagedSource = object : PagedSource<Int, String>() {
-            override val keyProvider = KeyProvider.Positional<String>()
+            override val keyProvider = KeyProvider.Positional
 
             override suspend fun load(params: LoadParams<Int>): LoadResult<Int, String> {
                 throw Exception()
@@ -116,7 +115,7 @@
             .build()
         var success = false
         assertFails {
-            val job = testCoroutineScope.async(backgroundThread.asCoroutineDispatcher()) {
+            val job = testCoroutineScope.async(backgroundThread) {
                 PagedList.create(
                     pagedSource,
                     testCoroutineScope,
@@ -140,8 +139,8 @@
     @Test
     fun defaults() = runBlocking {
         val pagedList = PagedList.Builder(pagedSource, config)
-            .setNotifyExecutor(DirectExecutor)
-            .setFetchExecutor(DirectExecutor)
+            .setNotifyDispatcher(DirectDispatcher)
+            .setFetchDispatcher(DirectDispatcher)
             .buildAsync()
 
         assertEquals(pagedSource, pagedList.pagedSource)
diff --git a/paging/common/src/test/kotlin/androidx/paging/PagedSourceTest.kt b/paging/common/src/test/kotlin/androidx/paging/PagedSourceTest.kt
index 3ef86fb..438fdae 100644
--- a/paging/common/src/test/kotlin/androidx/paging/PagedSourceTest.kt
+++ b/paging/common/src/test/kotlin/androidx/paging/PagedSourceTest.kt
@@ -22,11 +22,13 @@
 import androidx.paging.PagedSource.LoadType
 import kotlinx.coroutines.runBlocking
 import org.junit.Assert.assertEquals
+import org.junit.Assert.assertSame
 import org.junit.Assert.assertTrue
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
 import kotlin.test.assertFailsWith
+import kotlin.test.fail
 
 @RunWith(JUnit4::class)
 class PagedSourceTest {
@@ -229,6 +231,23 @@
         }
     }
 
+    @Test
+    fun defaultKeyProviderInstance() {
+        fun pagedSource(): PagedSource<Int, String> {
+            return object : PagedSource<Int, String>() {
+                override suspend fun load(params: LoadParams<Int>): LoadResult<Int, String> {
+                    fail("load not expected")
+                }
+            }
+        }
+
+        val source = pagedSource()
+        // assert calling method doesn't allocate new
+        assertSame(source.keyProvider, source.keyProvider)
+        // assert reused across instances
+        assertSame(source.keyProvider, pagedSource().keyProvider)
+    }
+
     internal data class Key(val name: String, val id: Int)
 
     internal data class Item(
@@ -271,13 +290,12 @@
             return if (params.placeholdersEnabled && counted) {
                 val data = items.subList(start, endExclusive)
                 LoadResult(
-                    itemsBefore = start,
-                    itemsAfter = items.size - data.size - start,
                     data = data,
-                    offset = start
+                    itemsBefore = start,
+                    itemsAfter = items.size - data.size - start
                 )
             } else {
-                LoadResult(data = items.subList(start, endExclusive), offset = 0)
+                LoadResult(items.subList(start, endExclusive))
             }
         }
 
@@ -290,7 +308,7 @@
             val start = findFirstIndexAfter(params.key!!)
             val endExclusive = minOf(start + params.loadSize, items.size)
 
-            return LoadResult(data = items.subList(start, endExclusive), offset = 0)
+            return LoadResult(items.subList(start, endExclusive))
         }
 
         private fun loadBefore(params: LoadParams<Key>): LoadResult<Key, Item> {
@@ -303,7 +321,7 @@
             val endExclusive = maxOf(0, firstIndexBefore + 1)
             val start = maxOf(0, firstIndexBefore - params.loadSize + 1)
 
-            return LoadResult(data = items.subList(start, endExclusive), offset = 0)
+            return LoadResult(items.subList(start, endExclusive))
         }
 
         private fun findFirstIndexAfter(key: Key): Int {
diff --git a/paging/common/src/test/kotlin/androidx/paging/PagerTest.kt b/paging/common/src/test/kotlin/androidx/paging/PagerTest.kt
index 67238ac..643b175 100644
--- a/paging/common/src/test/kotlin/androidx/paging/PagerTest.kt
+++ b/paging/common/src/test/kotlin/androidx/paging/PagerTest.kt
@@ -21,7 +21,8 @@
 import androidx.paging.PagedList.LoadState.LOADING
 import androidx.paging.PagedList.LoadType.END
 import androidx.paging.PagedList.LoadType.START
-import androidx.paging.futures.DirectExecutor
+import androidx.paging.PagedSource.LoadResult
+import androidx.paging.futures.DirectDispatcher
 import androidx.testutils.TestExecutor
 import kotlinx.coroutines.GlobalScope
 import org.junit.Assert.assertEquals
@@ -69,7 +70,7 @@
 
     private data class Result(
         val type: PagedList.LoadType,
-        val pageResult: PagedSource.LoadResult<*, String>
+        val pageResult: LoadResult<*, String>
     )
 
     private data class StateChange(
@@ -97,7 +98,7 @@
 
         override fun onPageResult(
             type: PagedList.LoadType,
-            pageResult: PagedSource.LoadResult<*, String>
+            pageResult: LoadResult<*, String>
         ): Boolean {
             results.add(Result(type, pageResult))
             return false
@@ -112,19 +113,28 @@
         }
     }
 
-    private fun createPager(consumer: MockConsumer, start: Int = 0, end: Int = 10) = Pager(
-        GlobalScope,
-        PagedList.Config(2, 2, true, 10, PagedList.Config.MAX_SIZE_UNBOUNDED),
-        PagedSourceWrapper(ImmediateListDataSource(data)),
-        DirectExecutor,
-        DirectExecutor,
-        consumer,
-        PositionalDataSource.InitialResult(
-            data.subList(start, end),
-            start,
-            data.size
-        ).toLoadResult()
-    )
+    private fun createPager(
+        consumer: MockConsumer,
+        start: Int = 0,
+        end: Int = 10
+    ): Pager<Int, String> {
+        val initialData = data.subList(start, end)
+        val initialResult = LoadResult<Int, String>(
+            data = initialData,
+            itemsBefore = start,
+            itemsAfter = data.size - initialData.size - start
+        )
+
+        return Pager(
+            GlobalScope,
+            PagedList.Config(2, 2, true, 10, PagedList.Config.MAX_SIZE_UNBOUNDED),
+            PagedSourceWrapper(ImmediateListDataSource(data)),
+            DirectDispatcher,
+            DirectDispatcher,
+            consumer,
+            initialResult
+        )
+    }
 
     @Test
     fun simplePagerAppend() {
@@ -138,9 +148,8 @@
 
         assertTrue(consumer.takeResults().isEmpty())
         assertEquals(
-            consumer.takeStateChanges(), listOf(
-                StateChange(END, PagedList.LoadState.LOADING)
-            )
+            consumer.takeStateChanges(),
+            listOf(StateChange(END, LOADING))
         )
 
         testExecutor.executeAll()
@@ -243,7 +252,7 @@
         // Pager triggers an immediate empty response here, so we don't need to flush the executor
         assertEquals(
             listOf(
-                Result(END, PagedSource.LoadResult.empty<Int, String>())
+                Result(END, LoadResult.empty<Int, String>())
             ), consumer.takeResults()
         )
         assertEquals(
@@ -263,7 +272,7 @@
         // Pager triggers an immediate empty response here, so we don't need to flush the executor
         assertEquals(
             listOf(
-                Result(START, PagedSource.LoadResult.empty<Int, String>())
+                Result(START, LoadResult.empty<Int, String>())
             ), consumer.takeResults()
         )
         assertEquals(
diff --git a/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/custom/ItemDataSource.kt b/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/custom/ItemDataSource.kt
index 44b20ff..857c84d 100644
--- a/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/custom/ItemDataSource.kt
+++ b/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/custom/ItemDataSource.kt
@@ -28,7 +28,7 @@
  * Sample data source with artificial data.
  */
 internal class ItemDataSource : PagedSource<Int, Item>() {
-    override val keyProvider = KeyProvider.Positional<Item>()
+    override val keyProvider = KeyProvider.Positional
 
     override suspend fun load(params: LoadParams<Int>) = when (params.loadType) {
         LoadType.INITIAL -> loadInitial(params)
@@ -106,15 +106,14 @@
         val loadSize = minOf(COUNT - position, params.loadSize)
         val data = loadRangeInternal(position, loadSize)
         return LoadResult(
-            itemsBefore = position,
-            itemsAfter = COUNT - data.size - position,
             data = data,
-            offset = 0
+            itemsBefore = position,
+            itemsAfter = COUNT - data.size - position
         )
     }
 
     private fun loadRange(params: LoadParams<Int>): LoadResult<Int, Item> {
         val data = loadRangeInternal(params.key ?: 0, params.loadSize)
-        return LoadResult(data = data, offset = 0)
+        return LoadResult(data)
     }
 }
diff --git a/paging/runtime/api/3.0.0-alpha01.txt b/paging/runtime/api/3.0.0-alpha01.txt
index f035ad8..6822061 100644
--- a/paging/runtime/api/3.0.0-alpha01.txt
+++ b/paging/runtime/api/3.0.0-alpha01.txt
@@ -43,8 +43,8 @@
     ctor public LivePagedListKt();
     method @Deprecated public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(androidx.paging.DataSource.Factory<Key,Value>, androidx.paging.PagedList.Config config, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, java.util.concurrent.Executor fetchExecutor = ArchTaskExecutor.getIOThreadExecutor());
     method @Deprecated public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(androidx.paging.DataSource.Factory<Key,Value>, int pageSize, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, java.util.concurrent.Executor fetchExecutor = ArchTaskExecutor.getIOThreadExecutor());
-    method public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(kotlin.jvm.functions.Function0<? extends androidx.paging.PagedSource<Key,Value>>, androidx.paging.PagedList.Config config, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, java.util.concurrent.Executor fetchExecutor = ArchTaskExecutor.getIOThreadExecutor());
-    method public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(kotlin.jvm.functions.Function0<? extends androidx.paging.PagedSource<Key,Value>>, int pageSize, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, java.util.concurrent.Executor fetchExecutor = ArchTaskExecutor.getIOThreadExecutor());
+    method public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(kotlin.jvm.functions.Function0<? extends androidx.paging.PagedSource<Key,Value>>, androidx.paging.PagedList.Config config, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, kotlinx.coroutines.CoroutineScope coroutineScope = GlobalScope, kotlinx.coroutines.CoroutineDispatcher fetchDispatcher = Dispatchers.IO);
+    method public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(kotlin.jvm.functions.Function0<? extends androidx.paging.PagedSource<Key,Value>>, int pageSize, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, kotlinx.coroutines.CoroutineScope coroutineScope = GlobalScope, kotlinx.coroutines.CoroutineDispatcher fetchDispatcher = Dispatchers.IO);
   }
 
   public abstract class PagedListAdapter<T, VH extends androidx.recyclerview.widget.RecyclerView.ViewHolder> extends androidx.recyclerview.widget.RecyclerView.Adapter<VH> {
diff --git a/paging/runtime/api/current.txt b/paging/runtime/api/current.txt
index f035ad8..6822061 100644
--- a/paging/runtime/api/current.txt
+++ b/paging/runtime/api/current.txt
@@ -43,8 +43,8 @@
     ctor public LivePagedListKt();
     method @Deprecated public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(androidx.paging.DataSource.Factory<Key,Value>, androidx.paging.PagedList.Config config, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, java.util.concurrent.Executor fetchExecutor = ArchTaskExecutor.getIOThreadExecutor());
     method @Deprecated public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(androidx.paging.DataSource.Factory<Key,Value>, int pageSize, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, java.util.concurrent.Executor fetchExecutor = ArchTaskExecutor.getIOThreadExecutor());
-    method public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(kotlin.jvm.functions.Function0<? extends androidx.paging.PagedSource<Key,Value>>, androidx.paging.PagedList.Config config, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, java.util.concurrent.Executor fetchExecutor = ArchTaskExecutor.getIOThreadExecutor());
-    method public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(kotlin.jvm.functions.Function0<? extends androidx.paging.PagedSource<Key,Value>>, int pageSize, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, java.util.concurrent.Executor fetchExecutor = ArchTaskExecutor.getIOThreadExecutor());
+    method public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(kotlin.jvm.functions.Function0<? extends androidx.paging.PagedSource<Key,Value>>, androidx.paging.PagedList.Config config, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, kotlinx.coroutines.CoroutineScope coroutineScope = GlobalScope, kotlinx.coroutines.CoroutineDispatcher fetchDispatcher = Dispatchers.IO);
+    method public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(kotlin.jvm.functions.Function0<? extends androidx.paging.PagedSource<Key,Value>>, int pageSize, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, kotlinx.coroutines.CoroutineScope coroutineScope = GlobalScope, kotlinx.coroutines.CoroutineDispatcher fetchDispatcher = Dispatchers.IO);
   }
 
   public abstract class PagedListAdapter<T, VH extends androidx.recyclerview.widget.RecyclerView.ViewHolder> extends androidx.recyclerview.widget.RecyclerView.Adapter<VH> {
diff --git a/paging/runtime/api/restricted_3.0.0-alpha01.txt b/paging/runtime/api/restricted_3.0.0-alpha01.txt
index f035ad8..6822061 100644
--- a/paging/runtime/api/restricted_3.0.0-alpha01.txt
+++ b/paging/runtime/api/restricted_3.0.0-alpha01.txt
@@ -43,8 +43,8 @@
     ctor public LivePagedListKt();
     method @Deprecated public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(androidx.paging.DataSource.Factory<Key,Value>, androidx.paging.PagedList.Config config, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, java.util.concurrent.Executor fetchExecutor = ArchTaskExecutor.getIOThreadExecutor());
     method @Deprecated public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(androidx.paging.DataSource.Factory<Key,Value>, int pageSize, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, java.util.concurrent.Executor fetchExecutor = ArchTaskExecutor.getIOThreadExecutor());
-    method public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(kotlin.jvm.functions.Function0<? extends androidx.paging.PagedSource<Key,Value>>, androidx.paging.PagedList.Config config, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, java.util.concurrent.Executor fetchExecutor = ArchTaskExecutor.getIOThreadExecutor());
-    method public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(kotlin.jvm.functions.Function0<? extends androidx.paging.PagedSource<Key,Value>>, int pageSize, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, java.util.concurrent.Executor fetchExecutor = ArchTaskExecutor.getIOThreadExecutor());
+    method public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(kotlin.jvm.functions.Function0<? extends androidx.paging.PagedSource<Key,Value>>, androidx.paging.PagedList.Config config, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, kotlinx.coroutines.CoroutineScope coroutineScope = GlobalScope, kotlinx.coroutines.CoroutineDispatcher fetchDispatcher = Dispatchers.IO);
+    method public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(kotlin.jvm.functions.Function0<? extends androidx.paging.PagedSource<Key,Value>>, int pageSize, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, kotlinx.coroutines.CoroutineScope coroutineScope = GlobalScope, kotlinx.coroutines.CoroutineDispatcher fetchDispatcher = Dispatchers.IO);
   }
 
   public abstract class PagedListAdapter<T, VH extends androidx.recyclerview.widget.RecyclerView.ViewHolder> extends androidx.recyclerview.widget.RecyclerView.Adapter<VH> {
diff --git a/paging/runtime/api/restricted_current.txt b/paging/runtime/api/restricted_current.txt
index f035ad8..6822061 100644
--- a/paging/runtime/api/restricted_current.txt
+++ b/paging/runtime/api/restricted_current.txt
@@ -43,8 +43,8 @@
     ctor public LivePagedListKt();
     method @Deprecated public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(androidx.paging.DataSource.Factory<Key,Value>, androidx.paging.PagedList.Config config, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, java.util.concurrent.Executor fetchExecutor = ArchTaskExecutor.getIOThreadExecutor());
     method @Deprecated public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(androidx.paging.DataSource.Factory<Key,Value>, int pageSize, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, java.util.concurrent.Executor fetchExecutor = ArchTaskExecutor.getIOThreadExecutor());
-    method public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(kotlin.jvm.functions.Function0<? extends androidx.paging.PagedSource<Key,Value>>, androidx.paging.PagedList.Config config, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, java.util.concurrent.Executor fetchExecutor = ArchTaskExecutor.getIOThreadExecutor());
-    method public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(kotlin.jvm.functions.Function0<? extends androidx.paging.PagedSource<Key,Value>>, int pageSize, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, java.util.concurrent.Executor fetchExecutor = ArchTaskExecutor.getIOThreadExecutor());
+    method public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(kotlin.jvm.functions.Function0<? extends androidx.paging.PagedSource<Key,Value>>, androidx.paging.PagedList.Config config, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, kotlinx.coroutines.CoroutineScope coroutineScope = GlobalScope, kotlinx.coroutines.CoroutineDispatcher fetchDispatcher = Dispatchers.IO);
+    method public static <Key, Value> androidx.lifecycle.LiveData<androidx.paging.PagedList<Value>> toLiveData(kotlin.jvm.functions.Function0<? extends androidx.paging.PagedSource<Key,Value>>, int pageSize, Key? initialLoadKey = null, androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback = null, kotlinx.coroutines.CoroutineScope coroutineScope = GlobalScope, kotlinx.coroutines.CoroutineDispatcher fetchDispatcher = Dispatchers.IO);
   }
 
   public abstract class PagedListAdapter<T, VH extends androidx.recyclerview.widget.RecyclerView.ViewHolder> extends androidx.recyclerview.widget.RecyclerView.Adapter<VH> {
diff --git a/paging/runtime/build.gradle b/paging/runtime/build.gradle
index 71033f7..e3719d7 100644
--- a/paging/runtime/build.gradle
+++ b/paging/runtime/build.gradle
@@ -18,7 +18,6 @@
 import androidx.build.AndroidXExtension
 import androidx.build.LibraryGroups
 import androidx.build.LibraryVersions
-import androidx.build.AndroidXExtension
 import androidx.build.Publish
 
 import static androidx.build.dependencies.DependenciesKt.*
@@ -42,16 +41,20 @@
     api(KOTLIN_COROUTINES)
 
     androidTestImplementation project(':internal-testutils-common')
-    androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
+    androidTestImplementation project(':internal-testutils-ktx'), {
+        exclude group: 'com.google.truth'
+    }
     androidTestImplementation(ANDROIDX_TEST_CORE)
+    androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
     androidTestImplementation(ANDROIDX_TEST_RUNNER)
     androidTestImplementation(ARCH_CORE_TESTING)
-    androidTestImplementation(ESPRESSO_CORE)
+    androidTestImplementation(KOTLIN_COROUTINES_TEST)
     androidTestImplementation(JUNIT)
     androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
     androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
     androidTestImplementation MOCKITO_KOTLIN, {
         exclude group: 'org.mockito' // to keep control on the mockito version
+        exclude group: 'net.bytebuddy'
     }
 }
 
diff --git a/paging/runtime/src/androidTest/java/androidx/paging/LivePagedListBuilderTest.kt b/paging/runtime/src/androidTest/java/androidx/paging/LivePagedListBuilderTest.kt
index d10028a..c8e43b1 100644
--- a/paging/runtime/src/androidTest/java/androidx/paging/LivePagedListBuilderTest.kt
+++ b/paging/runtime/src/androidTest/java/androidx/paging/LivePagedListBuilderTest.kt
@@ -27,7 +27,13 @@
 import androidx.paging.PagedList.LoadState.RETRYABLE_ERROR
 import androidx.paging.PagedList.LoadType.REFRESH
 import androidx.test.filters.SmallTest
+import androidx.testutils.TestDispatcher
 import androidx.testutils.TestExecutor
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Runnable
+import kotlinx.coroutines.test.resetMain
+import kotlinx.coroutines.test.setMain
 import org.junit.After
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertNotNull
@@ -43,6 +49,7 @@
 @SmallTest
 @RunWith(JUnit4::class)
 class LivePagedListBuilderTest {
+    private val mainDispatcher = TestDispatcher()
     private val backgroundExecutor = TestExecutor()
     private val lifecycleOwner = object : LifecycleOwner {
         private val lifecycle = LifecycleRegistry(this)
@@ -56,8 +63,10 @@
         }
     }
 
+    @ExperimentalCoroutinesApi
     @Before
     fun setup() {
+        Dispatchers.setMain(mainDispatcher)
         ArchTaskExecutor.getInstance().setDelegate(object : TaskExecutor() {
             override fun executeOnDiskIO(runnable: Runnable) {
                 fail("IO executor should be overwritten")
@@ -74,10 +83,12 @@
         lifecycleOwner.handleEvent(Lifecycle.Event.ON_START)
     }
 
+    @ExperimentalCoroutinesApi
     @After
     fun teardown() {
         lifecycleOwner.handleEvent(Lifecycle.Event.ON_STOP)
         ArchTaskExecutor.getInstance().setDelegate(null)
+        Dispatchers.resetMain()
     }
 
     class MockDataSourceFactory {
@@ -92,7 +103,7 @@
         }
 
         private inner class MockPagedSource : PagedSource<Int, String>() {
-            override val keyProvider = KeyProvider.Positional<String>()
+            override val keyProvider = KeyProvider.Positional
 
             override suspend fun load(params: LoadParams<Int>) = when (params.loadType) {
                 LoadType.INITIAL -> loadInitial(params)
@@ -111,23 +122,22 @@
 
                 val data = listOf("a", "b")
                 return LoadResult(
-                    itemsBefore = 0,
-                    itemsAfter = 4 - data.size,
                     data = data,
-                    offset = 0
+                    itemsBefore = 0,
+                    itemsAfter = 4 - data.size
                 )
             }
 
             private fun loadRange(): LoadResult<Int, String> {
-                return LoadResult(data = listOf("c", "d"), offset = 0)
+                return LoadResult(listOf("c", "d"))
             }
         }
     }
 
     @Test
     fun executorBehavior() {
-        // specify a background executor via builder, and verify it gets used for all loads,
-        // overriding default arch IO executor
+        // specify a background dispatcher via builder, and verify it gets used for all loads,
+        // overriding default IO dispatcher
         val livePagedList = LivePagedListBuilder(MockDataSourceFactory()::create, 2)
             .setFetchExecutor(backgroundExecutor)
             .build()
@@ -143,7 +153,7 @@
         assertTrue(pagedListHolder[0] is InitialPagedList<*, *>)
 
         // flush loadInitial, done with passed executor
-        backgroundExecutor.executeAll()
+        drain()
 
         val pagedList = pagedListHolder[0]
         assertNotNull(pagedList)
@@ -151,7 +161,7 @@
 
         // flush loadRange
         pagedList!!.loadAround(2)
-        backgroundExecutor.executeAll()
+        drain()
 
         assertEquals(listOf("a", "b", "c", "d"), pagedList)
     }
@@ -191,8 +201,8 @@
         }
         initPagedList.addWeakLoadStateListener(loadStateChangedCallback)
 
-        // flush loadInitial, done with passed executor
-        backgroundExecutor.executeAll()
+        // flush loadInitial, done with passed dispatcher
+        drain()
 
         assertSame(initPagedList, pagedListHolder[0])
         // TODO: Investigate removing initial IDLE state from callback updates.
@@ -208,7 +218,8 @@
         assertSame(initPagedList, pagedListHolder[0])
 
         // flush loadInitial, should succeed now
-        backgroundExecutor.executeAll()
+        drain()
+
         assertNotSame(initPagedList, pagedListHolder[0])
         assertEquals(listOf("a", "b", null, null), pagedListHolder[0])
 
@@ -235,6 +246,14 @@
         )
     }
 
+    private fun drain() {
+        var executed: Boolean
+        do {
+            executed = backgroundExecutor.executeAll()
+            mainDispatcher.executeAll()
+        } while (executed || mainDispatcher.queue.isNotEmpty())
+    }
+
     companion object {
         val RETRYABLE_EXCEPTION = Exception("retryable")
     }
diff --git a/paging/runtime/src/androidTest/java/androidx/paging/StringPagedList.kt b/paging/runtime/src/androidTest/java/androidx/paging/StringPagedList.kt
index 20c42d4..e9cdf9b 100644
--- a/paging/runtime/src/androidTest/java/androidx/paging/StringPagedList.kt
+++ b/paging/runtime/src/androidTest/java/androidx/paging/StringPagedList.kt
@@ -16,7 +16,8 @@
 
 package androidx.paging
 
-import androidx.testutils.TestExecutor
+import androidx.testutils.TestDispatcher
+import kotlinx.coroutines.GlobalScope
 
 class StringPagedList constructor(
     leadingNulls: Int,
@@ -24,10 +25,11 @@
     vararg items: String,
     list: List<String> = items.toList()
 ) : PagedList<String>(
+    GlobalScope,
     PagedSourceWrapper(ListDataSource(list)),
     PagedStorage(),
-    TestExecutor(),
-    TestExecutor(),
+    TestDispatcher(),
+    TestDispatcher(),
     null,
     Config.Builder().setPageSize(1).build()
 ), PagedStorage.Callback {
diff --git a/paging/runtime/src/main/java/androidx/paging/LivePagedList.kt b/paging/runtime/src/main/java/androidx/paging/LivePagedList.kt
index ce6fcde6d..2a0a7e4 100644
--- a/paging/runtime/src/main/java/androidx/paging/LivePagedList.kt
+++ b/paging/runtime/src/main/java/androidx/paging/LivePagedList.kt
@@ -18,9 +18,11 @@
 
 import androidx.arch.core.executor.ArchTaskExecutor
 import androidx.lifecycle.LiveData
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.Job
-import kotlinx.coroutines.asCoroutineDispatcher
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 import java.util.concurrent.Executor
@@ -31,8 +33,8 @@
     private val config: PagedList.Config,
     private val boundaryCallback: PagedList.BoundaryCallback<Value>?,
     private val pagedSourceFactory: PagedSourceFactory<Key, Value>,
-    private val notifyExecutor: Executor,
-    private val fetchExecutor: Executor
+    private val notifyDispatcher: CoroutineDispatcher,
+    private val fetchDispatcher: CoroutineDispatcher
 ) : LiveData<PagedList<Value>>() {
     private var currentData: PagedList<Value>
     private var currentJob: Job? = null
@@ -77,14 +79,14 @@
         if (currentJob != null && !force) return
 
         currentJob?.cancel()
-        currentJob = coroutineScope.launch(fetchExecutor.asCoroutineDispatcher()) {
+        currentJob = coroutineScope.launch(fetchDispatcher) {
             try {
                 val pagedList = createPagedList()
-                withContext(notifyExecutor.asCoroutineDispatcher()) {
+                withContext(notifyDispatcher) {
                     onSuccess(pagedList)
                 }
             } catch (throwable: Throwable) {
-                withContext(notifyExecutor.asCoroutineDispatcher()) {
+                withContext(notifyDispatcher) {
                     onError(throwable)
                 }
             }
@@ -100,16 +102,19 @@
         val pagedSource = pagedSourceFactory()
         currentData.pagedSource.unregisterInvalidatedCallback(callback)
         pagedSource.registerInvalidatedCallback(callback)
-        currentData.setInitialLoadState(PagedList.LoadState.LOADING, null)
+
+        withContext(notifyDispatcher) {
+            currentData.setInitialLoadState(PagedList.LoadState.LOADING, null)
+        }
 
         @Suppress("UNCHECKED_CAST") // getLastKey guaranteed to be of 'Key' type
         val lastKey = currentData.lastKey as Key?
         return PagedList.create(
             pagedSource,
             coroutineScope,
-            notifyExecutor,
-            fetchExecutor,
-            fetchExecutor,
+            notifyDispatcher,
+            fetchDispatcher,
+            fetchDispatcher,
             boundaryCallback,
             config,
             lastKey
@@ -121,13 +126,13 @@
  * Constructs a `LiveData<PagedList>`, from this `DataSource.Factory`, convenience for
  * [LivePagedListBuilder].
  *
- * No work (such as loading) is done immediately, the creation of the first PagedList is is
- * deferred until the LiveData is observed.
+ * No work (such as loading) is done immediately, the creation of the first [PagedList] is deferred
+ * until the [LiveData] is observed.
  *
  * @param config Paging configuration.
- * @param initialLoadKey Initial load key passed to the first PagedList/DataSource.
- * @param boundaryCallback The boundary callback for listening to PagedList load state.
- * @param fetchExecutor Executor for fetching data from DataSources.
+ * @param initialLoadKey Initial load key passed to the first [PagedList] / [PagedSource].
+ * @param boundaryCallback The boundary callback for listening to [PagedList] load state.
+ * @param fetchExecutor [Executor] for fetching data from [PagedSource]s.
  *
  * @see LivePagedListBuilder
  */
@@ -150,12 +155,12 @@
  * Constructs a `LiveData<PagedList>`, from this `DataSource.Factory`, convenience for
  * [LivePagedListBuilder].
  *
- * No work (such as loading) is done immediately, the creation of the first PagedList is is
- * deferred until the LiveData is observed.
+ * No work (such as loading) is done immediately, the creation of the first [PagedList] is deferred
+ * until the [LiveData] is observed.
  *
  * @param pageSize Page size.
- * @param initialLoadKey Initial load key passed to the first PagedList/DataSource.
- * @param boundaryCallback The boundary callback for listening to PagedList load state.
+ * @param initialLoadKey Initial load key passed to the first [PagedList] / [PagedSource].
+ * @param boundaryCallback The boundary callback for listening to [PagedList] load state.
  * @param fetchExecutor Executor for fetching data from DataSources.
  *
  * @see LivePagedListBuilder
@@ -179,13 +184,18 @@
  * Constructs a `LiveData<PagedList>`, from this [PagedSourceFactory], convenience for
  * [LivePagedListBuilder].
  *
- * No work (such as loading) is done immediately, the creation of the first PagedList is is
- * deferred until the LiveData is observed.
+ * No work (such as loading) is done immediately, the creation of the first [PagedList] is deferred
+ * until the [LiveData] is observed.
  *
  * @param config Paging configuration.
- * @param initialLoadKey Initial load key passed to the first PagedList/PagedSource.
- * @param boundaryCallback The boundary callback for listening to PagedList load state.
- * @param fetchExecutor Executor for fetching data from PagedSources.
+ * @param initialLoadKey Initial load key passed to the first [PagedList] / [PagedSource].
+ * @param boundaryCallback The boundary callback for listening to [PagedList] load state.
+ * @param coroutineScope Set the [CoroutineScope] that page loads should be launched within. The
+ * set [coroutineScope] allows a [PagedSource] to cancel running load operations when the results
+ * are no longer needed - for example, when the containing activity is destroyed.
+ *
+ * Defaults to [GlobalScope].
+ * @param fetchDispatcher [CoroutineDispatcher] for fetching data from [PagedSource]s.
  *
  * @see LivePagedListBuilder
  */
@@ -193,26 +203,36 @@
     config: PagedList.Config,
     initialLoadKey: Key? = null,
     boundaryCallback: PagedList.BoundaryCallback<Value>? = null,
-    fetchExecutor: Executor = ArchTaskExecutor.getIOThreadExecutor()
+    coroutineScope: CoroutineScope = GlobalScope,
+    fetchDispatcher: CoroutineDispatcher = Dispatchers.IO
 ): LiveData<PagedList<Value>> {
-    return LivePagedListBuilder(this, config)
-        .setInitialLoadKey(initialLoadKey)
-        .setBoundaryCallback(boundaryCallback)
-        .setFetchExecutor(fetchExecutor)
-        .build()
+    return LivePagedList(
+        coroutineScope,
+        initialLoadKey,
+        config,
+        boundaryCallback,
+        this,
+        Dispatchers.Main,
+        fetchDispatcher
+    )
 }
 
 /**
  * Constructs a `LiveData<PagedList>`, from this [PagedSourceFactory], convenience for
  * [LivePagedListBuilder].
  *
- * No work (such as loading) is done immediately, the creation of the first PagedList is is
- * deferred until the LiveData is observed.
+ * No work (such as loading) is done immediately, the creation of the first [PagedList] is deferred
+ * until the [LiveData] is observed.
  *
  * @param pageSize Page size.
- * @param initialLoadKey Initial load key passed to the first PagedList/PagedSource.
- * @param boundaryCallback The boundary callback for listening to PagedList load state.
- * @param fetchExecutor Executor for fetching data from PagedSources.
+ * @param initialLoadKey Initial load key passed to the first [PagedList] / [PagedSource].
+ * @param boundaryCallback The boundary callback for listening to [PagedList] load state.
+ * @param coroutineScope Set the [CoroutineScope] that page loads should be launched within. The
+ * set [coroutineScope] allows a [PagedSource] to cancel running load operations when the results
+ * are no longer needed - for example, when the containing activity is destroyed.
+ *
+ * Defaults to [GlobalScope].
+ * @param fetchDispatcher [CoroutineDispatcher] for fetching data from [PagedSource]s.
  *
  * @see LivePagedListBuilder
  */
@@ -220,11 +240,16 @@
     pageSize: Int,
     initialLoadKey: Key? = null,
     boundaryCallback: PagedList.BoundaryCallback<Value>? = null,
-    fetchExecutor: Executor = ArchTaskExecutor.getIOThreadExecutor()
+    coroutineScope: CoroutineScope = GlobalScope,
+    fetchDispatcher: CoroutineDispatcher = Dispatchers.IO
 ): LiveData<PagedList<Value>> {
-    return LivePagedListBuilder(this, Config(pageSize))
-        .setInitialLoadKey(initialLoadKey)
-        .setBoundaryCallback(boundaryCallback)
-        .setFetchExecutor(fetchExecutor)
-        .build()
+    return LivePagedList(
+        coroutineScope,
+        initialLoadKey,
+        PagedList.Config.Builder().setPageSize(pageSize).build(),
+        boundaryCallback,
+        this,
+        Dispatchers.Main,
+        fetchDispatcher
+    )
 }
diff --git a/paging/runtime/src/main/java/androidx/paging/LivePagedListBuilder.kt b/paging/runtime/src/main/java/androidx/paging/LivePagedListBuilder.kt
index ae1c147..a374d4a 100644
--- a/paging/runtime/src/main/java/androidx/paging/LivePagedListBuilder.kt
+++ b/paging/runtime/src/main/java/androidx/paging/LivePagedListBuilder.kt
@@ -16,15 +16,16 @@
 
 package androidx.paging
 
-import androidx.arch.core.executor.ArchTaskExecutor
 import androidx.lifecycle.LiveData
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.asCoroutineDispatcher
 import java.util.concurrent.Executor
 
 /**
- * Builder for `LiveData<PagedList>`, given a [androidx.paging.DataSource.Factory] and a
- * [androidx.paging.PagedList.Config].
+ * Builder for `LiveData<PagedList>` for Java users, given a [androidx.paging.DataSource.Factory]
+ * and a [androidx.paging.PagedList.Config].
  *
  * The required parameters are in the constructor, so you can simply construct and build, or
  * optionally enable extra features (such as initial load key, or BoundaryCallback).
@@ -32,6 +33,8 @@
  * @param Key Type of input valued used to load data from the [DataSource]. Must be integer if
  * you're using [PositionalDataSource].
  * @param Value Item type being presented.
+ *
+ * @see toLiveData
  */
 class LivePagedListBuilder<Key : Any, Value : Any> {
     private val pagedSourceFactory: PagedSourceFactory<Key, Value>
@@ -39,7 +42,7 @@
     private var coroutineScope: CoroutineScope = GlobalScope
     private var initialLoadKey: Key? = null
     private var boundaryCallback: PagedList.BoundaryCallback<Value>? = null
-    private var fetchExecutor = ArchTaskExecutor.getIOThreadExecutor()
+    private var fetchDispatcher = Dispatchers.IO
 
     /**
      * Creates a [LivePagedListBuilder] with required parameters.
@@ -148,9 +151,9 @@
      * Sets a [androidx.paging.PagedList.BoundaryCallback] on each PagedList created,
      * typically used to load additional data from network when paging from local storage.
      *
-     * Pass a BoundaryCallback to listen to when the PagedList runs out of data to load. If this
-     * method is not called, or `null` is passed, you will not be notified when each
-     * DataSource runs out of data to provide to its PagedList.
+     * Pass a [PagedList.BoundaryCallback] to listen to when the PagedList runs out of data to load.
+     * If this method is not called, or `null` is passed, you will not be notified when each
+     * [PagedSource] runs out of data to provide to its [PagedList].
      *
      * If you are paging from a DataSource.Factory backed by local storage, you can set a
      * BoundaryCallback to know when there is no more information to page from local storage.
@@ -169,15 +172,17 @@
     }
 
     /**
-     * Sets executor used for background fetching of PagedLists, and the pages within.
+     * Sets [Executor] used for background fetching of [PagedList]s, and the pages within.
      *
-     * If not set, defaults to the Arch components I/O thread pool.
+     * The library will wrap this as a [kotlinx.coroutines.CoroutineDispatcher].
      *
-     * @param fetchExecutor Executor for fetching data from DataSources.
+     * If not set, defaults to [Dispatchers.IO].
+     *
+     * @param fetchExecutor [Executor] for fetching data from [PagedSource]s.
      * @return this
      */
     fun setFetchExecutor(fetchExecutor: Executor) = this.apply {
-        this.fetchExecutor = fetchExecutor
+        this.fetchDispatcher = fetchExecutor.asCoroutineDispatcher()
     }
 
     /**
@@ -186,7 +191,7 @@
      * No work (such as loading) is done immediately, the creation of the first PagedList is is
      * deferred until the LiveData is observed.
      *
-     * @return The LiveData of PagedLists
+     * @return The [LiveData] of [PagedList]s
      */
     fun build(): LiveData<PagedList<Value>> {
         return LivePagedList(
@@ -195,8 +200,8 @@
             config,
             boundaryCallback,
             pagedSourceFactory,
-            ArchTaskExecutor.getMainThreadExecutor(),
-            fetchExecutor
+            Dispatchers.Main,
+            fetchDispatcher
         )
     }
 }
diff --git a/percentlayout/percentlayout/api/api_lint.ignore b/percentlayout/percentlayout/api/api_lint.ignore
new file mode 100644
index 0000000..aa25e85
--- /dev/null
+++ b/percentlayout/percentlayout/api/api_lint.ignore
@@ -0,0 +1,87 @@
+// Baseline format: 1.0
+MissingNullability: androidx.percentlayout.widget.PercentFrameLayout#PercentFrameLayout(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `PercentFrameLayout`
+MissingNullability: androidx.percentlayout.widget.PercentFrameLayout#PercentFrameLayout(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `PercentFrameLayout`
+MissingNullability: androidx.percentlayout.widget.PercentFrameLayout#PercentFrameLayout(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `PercentFrameLayout`
+MissingNullability: androidx.percentlayout.widget.PercentFrameLayout#PercentFrameLayout(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `PercentFrameLayout`
+MissingNullability: androidx.percentlayout.widget.PercentFrameLayout#PercentFrameLayout(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `PercentFrameLayout`
+MissingNullability: androidx.percentlayout.widget.PercentFrameLayout#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.percentlayout.widget.PercentFrameLayout#generateLayoutParams(android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.percentlayout.widget.PercentFrameLayout#generateLayoutParams(android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentFrameLayout.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `c` in method `LayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentFrameLayout.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `LayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentFrameLayout.LayoutParams#LayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentFrameLayout.LayoutParams#LayoutParams(android.view.ViewGroup.MarginLayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentFrameLayout.LayoutParams#LayoutParams(android.widget.FrameLayout.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentFrameLayout.LayoutParams#LayoutParams(androidx.percentlayout.widget.PercentFrameLayout.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentFrameLayout.LayoutParams#getPercentLayoutInfo():
+    Missing nullability on method `getPercentLayoutInfo` return
+MissingNullability: androidx.percentlayout.widget.PercentFrameLayout.LayoutParams#setBaseAttributes(android.content.res.TypedArray, int, int) parameter #0:
+    Missing nullability on parameter `a` in method `setBaseAttributes`
+MissingNullability: androidx.percentlayout.widget.PercentLayoutHelper#fetchWidthAndHeight(android.view.ViewGroup.LayoutParams, android.content.res.TypedArray, int, int) parameter #0:
+    Missing nullability on parameter `params` in method `fetchWidthAndHeight`
+MissingNullability: androidx.percentlayout.widget.PercentLayoutHelper#fetchWidthAndHeight(android.view.ViewGroup.LayoutParams, android.content.res.TypedArray, int, int) parameter #1:
+    Missing nullability on parameter `array` in method `fetchWidthAndHeight`
+MissingNullability: androidx.percentlayout.widget.PercentLayoutHelper#getPercentLayoutInfo(android.content.Context, android.util.AttributeSet):
+    Missing nullability on method `getPercentLayoutInfo` return
+MissingNullability: androidx.percentlayout.widget.PercentLayoutHelper#getPercentLayoutInfo(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `getPercentLayoutInfo`
+MissingNullability: androidx.percentlayout.widget.PercentLayoutHelper#getPercentLayoutInfo(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `getPercentLayoutInfo`
+MissingNullability: androidx.percentlayout.widget.PercentLayoutHelper.PercentLayoutInfo#fillLayoutParams(android.view.ViewGroup.LayoutParams, int, int) parameter #0:
+    Missing nullability on parameter `params` in method `fillLayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentLayoutHelper.PercentLayoutInfo#fillMarginLayoutParams(android.view.View, android.view.ViewGroup.MarginLayoutParams, int, int) parameter #0:
+    Missing nullability on parameter `view` in method `fillMarginLayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentLayoutHelper.PercentLayoutInfo#fillMarginLayoutParams(android.view.View, android.view.ViewGroup.MarginLayoutParams, int, int) parameter #1:
+    Missing nullability on parameter `params` in method `fillMarginLayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentLayoutHelper.PercentLayoutInfo#fillMarginLayoutParams(android.view.ViewGroup.MarginLayoutParams, int, int) parameter #0:
+    Missing nullability on parameter `params` in method `fillMarginLayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentLayoutHelper.PercentLayoutInfo#restoreLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `params` in method `restoreLayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentLayoutHelper.PercentLayoutInfo#restoreMarginLayoutParams(android.view.ViewGroup.MarginLayoutParams) parameter #0:
+    Missing nullability on parameter `params` in method `restoreMarginLayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentLayoutHelper.PercentLayoutInfo#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.percentlayout.widget.PercentLayoutHelper.PercentLayoutParams#getPercentLayoutInfo():
+    Missing nullability on method `getPercentLayoutInfo` return
+MissingNullability: androidx.percentlayout.widget.PercentRelativeLayout#PercentRelativeLayout(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `PercentRelativeLayout`
+MissingNullability: androidx.percentlayout.widget.PercentRelativeLayout#PercentRelativeLayout(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `PercentRelativeLayout`
+MissingNullability: androidx.percentlayout.widget.PercentRelativeLayout#PercentRelativeLayout(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `PercentRelativeLayout`
+MissingNullability: androidx.percentlayout.widget.PercentRelativeLayout#PercentRelativeLayout(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `PercentRelativeLayout`
+MissingNullability: androidx.percentlayout.widget.PercentRelativeLayout#PercentRelativeLayout(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `PercentRelativeLayout`
+MissingNullability: androidx.percentlayout.widget.PercentRelativeLayout#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.percentlayout.widget.PercentRelativeLayout#generateLayoutParams(android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.percentlayout.widget.PercentRelativeLayout#generateLayoutParams(android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentRelativeLayout.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `c` in method `LayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentRelativeLayout.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `LayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentRelativeLayout.LayoutParams#LayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentRelativeLayout.LayoutParams#LayoutParams(android.view.ViewGroup.MarginLayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.percentlayout.widget.PercentRelativeLayout.LayoutParams#getPercentLayoutInfo():
+    Missing nullability on method `getPercentLayoutInfo` return
+MissingNullability: androidx.percentlayout.widget.PercentRelativeLayout.LayoutParams#setBaseAttributes(android.content.res.TypedArray, int, int) parameter #0:
+    Missing nullability on parameter `a` in method `setBaseAttributes`
diff --git a/preference/api/api_lint.ignore b/preference/api/api_lint.ignore
deleted file mode 100644
index 5b1c512..0000000
--- a/preference/api/api_lint.ignore
+++ /dev/null
@@ -1,23 +0,0 @@
-// Baseline format: 1.0
-CallbackMethodName: androidx.preference.PreferenceManager.PreferenceComparisonCallback:
-    Callback method names must follow the on<Something> style: arePreferenceItemsTheSame
-CallbackMethodName: androidx.preference.PreferenceManager.SimplePreferenceComparisonCallback:
-    Callback method names must follow the on<Something> style: arePreferenceItemsTheSame
-
-
-ParcelConstructor: androidx.preference.Preference.BaseSavedState#BaseSavedState(android.os.Parcel):
-    Parcelable inflation is exposed through CREATOR, not raw constructors, in androidx.preference.Preference.BaseSavedState
-
-
-ParcelCreator: androidx.preference.Preference.BaseSavedState:
-    Parcelable requires `void writeToParcel(Parcel, int)`; missing in androidx.preference.Preference.BaseSavedState
-
-
-ParcelNotFinal: androidx.preference.Preference.BaseSavedState:
-    Parcelable classes must be final: androidx.preference.Preference.BaseSavedState is not final
-
-
-VisiblySynchronized: androidx.preference.PreferenceGroup#addPreference(androidx.preference.Preference):
-    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method androidx.preference.PreferenceGroup.addPreference(androidx.preference.Preference)
-VisiblySynchronized: androidx.preference.PreferenceGroup#removeAll():
-    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method androidx.preference.PreferenceGroup.removeAll()
diff --git a/preference/ktx/build.gradle b/preference/ktx/build.gradle
deleted file mode 100644
index 6852755..0000000
--- a/preference/ktx/build.gradle
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2018 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.LibraryGroups
-import androidx.build.LibraryVersions
-
-import static androidx.build.dependencies.DependenciesKt.*
-import androidx.build.Publish
-
-plugins {
-    id("AndroidXPlugin")
-    id("com.android.library")
-    id("org.jetbrains.kotlin.android")
-}
-
-android {
-    compileOptions {
-        sourceCompatibility = JavaVersion.VERSION_1_7
-        targetCompatibility = JavaVersion.VERSION_1_7
-    }
-    buildTypes {
-        debug {
-            testCoverageEnabled = false // Breaks Kotlin compiler.
-        }
-    }
-}
-
-dependencies {
-    api(project(":preference"))
-    api(KOTLIN_STDLIB)
-
-    androidTestImplementation(JUNIT)
-    androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
-    androidTestImplementation(ANDROIDX_TEST_CORE)
-    androidTestImplementation(ANDROIDX_TEST_RUNNER)
-    androidTestImplementation(ANDROIDX_TEST_RULES)
-    androidTestImplementation(TRUTH)
-    androidTestImplementation(project(":internal-testutils-ktx"))
-}
-
-androidx {
-    name = "Android Preferences KTX"
-    publish = Publish.SNAPSHOT_AND_RELEASE
-    mavenVersion = LibraryVersions.PREFERENCE
-    mavenGroup = LibraryGroups.PREFERENCE
-    inceptionYear = "2018"
-    description = "Kotlin extensions for preferences"
-}
diff --git a/preference/ktx/OWNERS b/preference/preference-ktx/OWNERS
similarity index 100%
rename from preference/ktx/OWNERS
rename to preference/preference-ktx/OWNERS
diff --git a/preference/ktx/api/1.0.0.txt b/preference/preference-ktx/api/1.0.0.txt
similarity index 100%
rename from preference/ktx/api/1.0.0.txt
rename to preference/preference-ktx/api/1.0.0.txt
diff --git a/preference/ktx/api/1.1.0-alpha02.txt b/preference/preference-ktx/api/1.1.0-alpha02.txt
similarity index 100%
rename from preference/ktx/api/1.1.0-alpha02.txt
rename to preference/preference-ktx/api/1.1.0-alpha02.txt
diff --git a/preference/ktx/api/1.1.0-alpha03.txt b/preference/preference-ktx/api/1.1.0-alpha03.txt
similarity index 100%
rename from preference/ktx/api/1.1.0-alpha03.txt
rename to preference/preference-ktx/api/1.1.0-alpha03.txt
diff --git a/preference/ktx/api/1.1.0-alpha04.txt b/preference/preference-ktx/api/1.1.0-alpha04.txt
similarity index 100%
rename from preference/ktx/api/1.1.0-alpha04.txt
rename to preference/preference-ktx/api/1.1.0-alpha04.txt
diff --git a/preference/ktx/api/1.1.0-alpha05.txt b/preference/preference-ktx/api/1.1.0-alpha05.txt
similarity index 100%
rename from preference/ktx/api/1.1.0-alpha05.txt
rename to preference/preference-ktx/api/1.1.0-alpha05.txt
diff --git a/preference/ktx/api/1.1.0-alpha06.txt b/preference/preference-ktx/api/1.1.0-alpha06.txt
similarity index 100%
rename from preference/ktx/api/1.1.0-alpha06.txt
rename to preference/preference-ktx/api/1.1.0-alpha06.txt
diff --git a/preference/ktx/api/1.1.0-beta01.txt b/preference/preference-ktx/api/1.1.0-beta01.txt
similarity index 100%
rename from preference/ktx/api/1.1.0-beta01.txt
rename to preference/preference-ktx/api/1.1.0-beta01.txt
diff --git a/preference/ktx/api/1.1.0-beta02.txt b/preference/preference-ktx/api/1.1.0-beta02.txt
similarity index 100%
rename from preference/ktx/api/1.1.0-beta02.txt
rename to preference/preference-ktx/api/1.1.0-beta02.txt
diff --git a/preference/ktx/api/1.1.0-rc01.txt b/preference/preference-ktx/api/1.1.0-rc01.txt
similarity index 100%
rename from preference/ktx/api/1.1.0-rc01.txt
rename to preference/preference-ktx/api/1.1.0-rc01.txt
diff --git a/preference/ktx/api/1.2.0-alpha01.txt b/preference/preference-ktx/api/1.2.0-alpha01.txt
similarity index 100%
rename from preference/ktx/api/1.2.0-alpha01.txt
rename to preference/preference-ktx/api/1.2.0-alpha01.txt
diff --git a/preference/ktx/api/api_lint.ignore b/preference/preference-ktx/api/api_lint.ignore
similarity index 100%
rename from preference/ktx/api/api_lint.ignore
rename to preference/preference-ktx/api/api_lint.ignore
diff --git a/preference/ktx/api/current.txt b/preference/preference-ktx/api/current.txt
similarity index 100%
rename from preference/ktx/api/current.txt
rename to preference/preference-ktx/api/current.txt
diff --git a/preference/ktx/api/res-1.0.0.txt b/preference/preference-ktx/api/res-1.0.0.txt
similarity index 100%
rename from preference/ktx/api/res-1.0.0.txt
rename to preference/preference-ktx/api/res-1.0.0.txt
diff --git a/preference/ktx/api/res-1.1.0-alpha02.txt b/preference/preference-ktx/api/res-1.1.0-alpha02.txt
similarity index 100%
rename from preference/ktx/api/res-1.1.0-alpha02.txt
rename to preference/preference-ktx/api/res-1.1.0-alpha02.txt
diff --git a/preference/ktx/api/res-1.1.0-alpha03.txt b/preference/preference-ktx/api/res-1.1.0-alpha03.txt
similarity index 100%
rename from preference/ktx/api/res-1.1.0-alpha03.txt
rename to preference/preference-ktx/api/res-1.1.0-alpha03.txt
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/preference/preference-ktx/api/res-1.1.0-alpha04.txt
similarity index 100%
rename from preference/ktx/api/res-1.1.0-alpha04.txt
rename to preference/preference-ktx/api/res-1.1.0-alpha04.txt
diff --git a/preference/ktx/api/res-1.1.0-alpha05.txt b/preference/preference-ktx/api/res-1.1.0-alpha05.txt
similarity index 100%
rename from preference/ktx/api/res-1.1.0-alpha05.txt
rename to preference/preference-ktx/api/res-1.1.0-alpha05.txt
diff --git a/preference/ktx/api/res-1.1.0-alpha06.txt b/preference/preference-ktx/api/res-1.1.0-alpha06.txt
similarity index 100%
rename from preference/ktx/api/res-1.1.0-alpha06.txt
rename to preference/preference-ktx/api/res-1.1.0-alpha06.txt
diff --git a/preference/ktx/api/res-1.1.0-beta01.txt b/preference/preference-ktx/api/res-1.1.0-beta01.txt
similarity index 100%
rename from preference/ktx/api/res-1.1.0-beta01.txt
rename to preference/preference-ktx/api/res-1.1.0-beta01.txt
diff --git a/preference/ktx/api/res-1.1.0-beta02.txt b/preference/preference-ktx/api/res-1.1.0-beta02.txt
similarity index 100%
rename from preference/ktx/api/res-1.1.0-beta02.txt
rename to preference/preference-ktx/api/res-1.1.0-beta02.txt
diff --git a/preference/ktx/api/res-1.1.0-rc01.txt b/preference/preference-ktx/api/res-1.1.0-rc01.txt
similarity index 100%
rename from preference/ktx/api/res-1.1.0-rc01.txt
rename to preference/preference-ktx/api/res-1.1.0-rc01.txt
diff --git a/preference/ktx/api/res-1.2.0-alpha01.txt b/preference/preference-ktx/api/res-1.2.0-alpha01.txt
similarity index 100%
rename from preference/ktx/api/res-1.2.0-alpha01.txt
rename to preference/preference-ktx/api/res-1.2.0-alpha01.txt
diff --git a/preference/ktx/api/restricted_1.0.0.txt b/preference/preference-ktx/api/restricted_1.0.0.txt
similarity index 100%
rename from preference/ktx/api/restricted_1.0.0.txt
rename to preference/preference-ktx/api/restricted_1.0.0.txt
diff --git a/preference/ktx/api/restricted_1.1.0-alpha04.txt b/preference/preference-ktx/api/restricted_1.1.0-alpha04.txt
similarity index 100%
rename from preference/ktx/api/restricted_1.1.0-alpha04.txt
rename to preference/preference-ktx/api/restricted_1.1.0-alpha04.txt
diff --git a/preference/ktx/api/restricted_1.1.0-alpha05.txt b/preference/preference-ktx/api/restricted_1.1.0-alpha05.txt
similarity index 100%
rename from preference/ktx/api/restricted_1.1.0-alpha05.txt
rename to preference/preference-ktx/api/restricted_1.1.0-alpha05.txt
diff --git a/preference/ktx/api/restricted_1.1.0-alpha06.txt b/preference/preference-ktx/api/restricted_1.1.0-alpha06.txt
similarity index 100%
rename from preference/ktx/api/restricted_1.1.0-alpha06.txt
rename to preference/preference-ktx/api/restricted_1.1.0-alpha06.txt
diff --git a/preference/ktx/api/restricted_1.1.0-beta01.txt b/preference/preference-ktx/api/restricted_1.1.0-beta01.txt
similarity index 100%
rename from preference/ktx/api/restricted_1.1.0-beta01.txt
rename to preference/preference-ktx/api/restricted_1.1.0-beta01.txt
diff --git a/preference/ktx/api/restricted_1.1.0-beta02.txt b/preference/preference-ktx/api/restricted_1.1.0-beta02.txt
similarity index 100%
rename from preference/ktx/api/restricted_1.1.0-beta02.txt
rename to preference/preference-ktx/api/restricted_1.1.0-beta02.txt
diff --git a/preference/ktx/api/restricted_1.1.0-rc01.txt b/preference/preference-ktx/api/restricted_1.1.0-rc01.txt
similarity index 100%
rename from preference/ktx/api/restricted_1.1.0-rc01.txt
rename to preference/preference-ktx/api/restricted_1.1.0-rc01.txt
diff --git a/preference/ktx/api/restricted_1.2.0-alpha01.txt b/preference/preference-ktx/api/restricted_1.2.0-alpha01.txt
similarity index 100%
rename from preference/ktx/api/restricted_1.2.0-alpha01.txt
rename to preference/preference-ktx/api/restricted_1.2.0-alpha01.txt
diff --git a/preference/ktx/api/restricted_current.txt b/preference/preference-ktx/api/restricted_current.txt
similarity index 100%
rename from preference/ktx/api/restricted_current.txt
rename to preference/preference-ktx/api/restricted_current.txt
diff --git a/preference/preference-ktx/build.gradle b/preference/preference-ktx/build.gradle
new file mode 100644
index 0000000..57fdce2
--- /dev/null
+++ b/preference/preference-ktx/build.gradle
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 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.LibraryGroups
+import androidx.build.LibraryVersions
+
+import static androidx.build.dependencies.DependenciesKt.*
+import androidx.build.Publish
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+    id("org.jetbrains.kotlin.android")
+}
+
+android {
+    compileOptions {
+        sourceCompatibility = JavaVersion.VERSION_1_7
+        targetCompatibility = JavaVersion.VERSION_1_7
+    }
+    buildTypes {
+        debug {
+            testCoverageEnabled = false // Breaks Kotlin compiler.
+        }
+    }
+}
+
+dependencies {
+    api(project(":preference:preference"))
+    api(KOTLIN_STDLIB)
+
+    androidTestImplementation(JUNIT)
+    androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
+    androidTestImplementation(ANDROIDX_TEST_CORE)
+    androidTestImplementation(ANDROIDX_TEST_RUNNER)
+    androidTestImplementation(ANDROIDX_TEST_RULES)
+    androidTestImplementation(TRUTH)
+    androidTestImplementation(project(":internal-testutils-ktx"))
+}
+
+androidx {
+    name = "Android Preferences KTX"
+    publish = Publish.SNAPSHOT_AND_RELEASE
+    mavenVersion = LibraryVersions.PREFERENCE
+    mavenGroup = LibraryGroups.PREFERENCE
+    inceptionYear = "2018"
+    description = "Kotlin extensions for preferences"
+}
diff --git a/preference/ktx/src/androidTest/AndroidManifest.xml b/preference/preference-ktx/src/androidTest/AndroidManifest.xml
similarity index 100%
rename from preference/ktx/src/androidTest/AndroidManifest.xml
rename to preference/preference-ktx/src/androidTest/AndroidManifest.xml
diff --git a/preference/ktx/src/androidTest/java/androidx/preference/PreferenceGroupTest.kt b/preference/preference-ktx/src/androidTest/java/androidx/preference/PreferenceGroupTest.kt
similarity index 100%
rename from preference/ktx/src/androidTest/java/androidx/preference/PreferenceGroupTest.kt
rename to preference/preference-ktx/src/androidTest/java/androidx/preference/PreferenceGroupTest.kt
diff --git a/preference/ktx/src/androidTest/java/androidx/preference/PreferenceTestHelperActivity.kt b/preference/preference-ktx/src/androidTest/java/androidx/preference/PreferenceTestHelperActivity.kt
similarity index 100%
rename from preference/ktx/src/androidTest/java/androidx/preference/PreferenceTestHelperActivity.kt
rename to preference/preference-ktx/src/androidTest/java/androidx/preference/PreferenceTestHelperActivity.kt
diff --git a/preference/ktx/src/androidTest/res/xml/test_preferencegroup.xml b/preference/preference-ktx/src/androidTest/res/xml/test_preferencegroup.xml
similarity index 100%
rename from preference/ktx/src/androidTest/res/xml/test_preferencegroup.xml
rename to preference/preference-ktx/src/androidTest/res/xml/test_preferencegroup.xml
diff --git a/preference/ktx/src/main/AndroidManifest.xml b/preference/preference-ktx/src/main/AndroidManifest.xml
similarity index 100%
rename from preference/ktx/src/main/AndroidManifest.xml
rename to preference/preference-ktx/src/main/AndroidManifest.xml
diff --git a/preference/ktx/src/main/java/androidx/preference/PreferenceGroup.kt b/preference/preference-ktx/src/main/java/androidx/preference/PreferenceGroup.kt
similarity index 100%
rename from preference/ktx/src/main/java/androidx/preference/PreferenceGroup.kt
rename to preference/preference-ktx/src/main/java/androidx/preference/PreferenceGroup.kt
diff --git a/preference/api/0.0.0.txt b/preference/preference/api/0.0.0.txt
similarity index 100%
rename from preference/api/0.0.0.txt
rename to preference/preference/api/0.0.0.txt
diff --git a/preference/api/1.0.0.txt b/preference/preference/api/1.0.0.txt
similarity index 100%
rename from preference/api/1.0.0.txt
rename to preference/preference/api/1.0.0.txt
diff --git a/preference/api/1.1.0-alpha01.txt b/preference/preference/api/1.1.0-alpha01.txt
similarity index 100%
rename from preference/api/1.1.0-alpha01.txt
rename to preference/preference/api/1.1.0-alpha01.txt
diff --git a/preference/api/1.1.0-alpha02.txt b/preference/preference/api/1.1.0-alpha02.txt
similarity index 100%
rename from preference/api/1.1.0-alpha02.txt
rename to preference/preference/api/1.1.0-alpha02.txt
diff --git a/preference/api/1.1.0-alpha03.txt b/preference/preference/api/1.1.0-alpha03.txt
similarity index 100%
rename from preference/api/1.1.0-alpha03.txt
rename to preference/preference/api/1.1.0-alpha03.txt
diff --git a/preference/api/1.1.0-alpha04.txt b/preference/preference/api/1.1.0-alpha04.txt
similarity index 100%
rename from preference/api/1.1.0-alpha04.txt
rename to preference/preference/api/1.1.0-alpha04.txt
diff --git a/preference/api/1.1.0-alpha05.txt b/preference/preference/api/1.1.0-alpha05.txt
similarity index 100%
rename from preference/api/1.1.0-alpha05.txt
rename to preference/preference/api/1.1.0-alpha05.txt
diff --git a/preference/api/1.1.0-alpha06.txt b/preference/preference/api/1.1.0-alpha06.txt
similarity index 100%
rename from preference/api/1.1.0-alpha06.txt
rename to preference/preference/api/1.1.0-alpha06.txt
diff --git a/preference/api/1.1.0-beta01.ignore b/preference/preference/api/1.1.0-beta01.ignore
similarity index 100%
rename from preference/api/1.1.0-beta01.ignore
rename to preference/preference/api/1.1.0-beta01.ignore
diff --git a/preference/api/1.1.0-beta01.txt b/preference/preference/api/1.1.0-beta01.txt
similarity index 100%
rename from preference/api/1.1.0-beta01.txt
rename to preference/preference/api/1.1.0-beta01.txt
diff --git a/preference/api/1.1.0-beta02.txt b/preference/preference/api/1.1.0-beta02.txt
similarity index 100%
rename from preference/api/1.1.0-beta02.txt
rename to preference/preference/api/1.1.0-beta02.txt
diff --git a/preference/api/1.1.0-rc01.txt b/preference/preference/api/1.1.0-rc01.txt
similarity index 100%
rename from preference/api/1.1.0-rc01.txt
rename to preference/preference/api/1.1.0-rc01.txt
diff --git a/preference/api/1.2.0-alpha01.txt b/preference/preference/api/1.2.0-alpha01.txt
similarity index 100%
rename from preference/api/1.2.0-alpha01.txt
rename to preference/preference/api/1.2.0-alpha01.txt
diff --git a/preference/preference/api/api_lint.ignore b/preference/preference/api/api_lint.ignore
new file mode 100644
index 0000000..7e3b6d5
--- /dev/null
+++ b/preference/preference/api/api_lint.ignore
@@ -0,0 +1,765 @@
+// Baseline format: 1.0
+CallbackMethodName: androidx.preference.PreferenceManager.PreferenceComparisonCallback:
+    Callback method names must follow the on<Something> style: arePreferenceItemsTheSame
+CallbackMethodName: androidx.preference.PreferenceManager.SimplePreferenceComparisonCallback:
+    Callback method names must follow the on<Something> style: arePreferenceItemsTheSame
+
+
+MissingNullability: androidx.preference.CheckBoxPreference#CheckBoxPreference(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `CheckBoxPreference`
+MissingNullability: androidx.preference.CheckBoxPreference#CheckBoxPreference(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `CheckBoxPreference`
+MissingNullability: androidx.preference.CheckBoxPreference#CheckBoxPreference(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `CheckBoxPreference`
+MissingNullability: androidx.preference.CheckBoxPreference#CheckBoxPreference(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `CheckBoxPreference`
+MissingNullability: androidx.preference.CheckBoxPreference#CheckBoxPreference(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `CheckBoxPreference`
+MissingNullability: androidx.preference.CheckBoxPreference#CheckBoxPreference(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `CheckBoxPreference`
+MissingNullability: androidx.preference.CheckBoxPreference#CheckBoxPreference(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `CheckBoxPreference`
+MissingNullability: androidx.preference.CheckBoxPreference#onBindViewHolder(androidx.preference.PreferenceViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onBindViewHolder`
+MissingNullability: androidx.preference.DialogPreference#DialogPreference(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `DialogPreference`
+MissingNullability: androidx.preference.DialogPreference#DialogPreference(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `DialogPreference`
+MissingNullability: androidx.preference.DialogPreference#DialogPreference(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `DialogPreference`
+MissingNullability: androidx.preference.DialogPreference#DialogPreference(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `DialogPreference`
+MissingNullability: androidx.preference.DialogPreference#DialogPreference(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `DialogPreference`
+MissingNullability: androidx.preference.DialogPreference#DialogPreference(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `DialogPreference`
+MissingNullability: androidx.preference.DialogPreference#DialogPreference(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `DialogPreference`
+MissingNullability: androidx.preference.DialogPreference#getDialogIcon():
+    Missing nullability on method `getDialogIcon` return
+MissingNullability: androidx.preference.DialogPreference#getDialogMessage():
+    Missing nullability on method `getDialogMessage` return
+MissingNullability: androidx.preference.DialogPreference#getDialogTitle():
+    Missing nullability on method `getDialogTitle` return
+MissingNullability: androidx.preference.DialogPreference#getNegativeButtonText():
+    Missing nullability on method `getNegativeButtonText` return
+MissingNullability: androidx.preference.DialogPreference#getPositiveButtonText():
+    Missing nullability on method `getPositiveButtonText` return
+MissingNullability: androidx.preference.DialogPreference#setDialogIcon(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `dialogIcon` in method `setDialogIcon`
+MissingNullability: androidx.preference.DialogPreference#setDialogMessage(CharSequence) parameter #0:
+    Missing nullability on parameter `dialogMessage` in method `setDialogMessage`
+MissingNullability: androidx.preference.DialogPreference#setDialogTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `dialogTitle` in method `setDialogTitle`
+MissingNullability: androidx.preference.DialogPreference#setNegativeButtonText(CharSequence) parameter #0:
+    Missing nullability on parameter `negativeButtonText` in method `setNegativeButtonText`
+MissingNullability: androidx.preference.DialogPreference#setPositiveButtonText(CharSequence) parameter #0:
+    Missing nullability on parameter `positiveButtonText` in method `setPositiveButtonText`
+MissingNullability: androidx.preference.DropDownPreference#DropDownPreference(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `DropDownPreference`
+MissingNullability: androidx.preference.DropDownPreference#DropDownPreference(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `DropDownPreference`
+MissingNullability: androidx.preference.DropDownPreference#DropDownPreference(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `DropDownPreference`
+MissingNullability: androidx.preference.DropDownPreference#DropDownPreference(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `DropDownPreference`
+MissingNullability: androidx.preference.DropDownPreference#DropDownPreference(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `DropDownPreference`
+MissingNullability: androidx.preference.DropDownPreference#DropDownPreference(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `DropDownPreference`
+MissingNullability: androidx.preference.DropDownPreference#DropDownPreference(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `DropDownPreference`
+MissingNullability: androidx.preference.DropDownPreference#createAdapter():
+    Missing nullability on method `createAdapter` return
+MissingNullability: androidx.preference.DropDownPreference#onBindViewHolder(androidx.preference.PreferenceViewHolder) parameter #0:
+    Missing nullability on parameter `view` in method `onBindViewHolder`
+MissingNullability: androidx.preference.EditTextPreference#EditTextPreference(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `EditTextPreference`
+MissingNullability: androidx.preference.EditTextPreference#EditTextPreference(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `EditTextPreference`
+MissingNullability: androidx.preference.EditTextPreference#EditTextPreference(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `EditTextPreference`
+MissingNullability: androidx.preference.EditTextPreference#EditTextPreference(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `EditTextPreference`
+MissingNullability: androidx.preference.EditTextPreference#EditTextPreference(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `EditTextPreference`
+MissingNullability: androidx.preference.EditTextPreference#EditTextPreference(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `EditTextPreference`
+MissingNullability: androidx.preference.EditTextPreference#EditTextPreference(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `EditTextPreference`
+MissingNullability: androidx.preference.EditTextPreference#getText():
+    Missing nullability on method `getText` return
+MissingNullability: androidx.preference.EditTextPreference#onGetDefaultValue(android.content.res.TypedArray, int):
+    Missing nullability on method `onGetDefaultValue` return
+MissingNullability: androidx.preference.EditTextPreference#onGetDefaultValue(android.content.res.TypedArray, int) parameter #0:
+    Missing nullability on parameter `a` in method `onGetDefaultValue`
+MissingNullability: androidx.preference.EditTextPreference#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.preference.EditTextPreference#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.preference.EditTextPreference#onSetInitialValue(Object) parameter #0:
+    Missing nullability on parameter `defaultValue` in method `onSetInitialValue`
+MissingNullability: androidx.preference.EditTextPreference#setText(String) parameter #0:
+    Missing nullability on parameter `text` in method `setText`
+MissingNullability: androidx.preference.EditTextPreference.SimpleSummaryProvider#getInstance():
+    Missing nullability on method `getInstance` return
+MissingNullability: androidx.preference.EditTextPreference.SimpleSummaryProvider#provideSummary(androidx.preference.EditTextPreference):
+    Missing nullability on method `provideSummary` return
+MissingNullability: androidx.preference.EditTextPreference.SimpleSummaryProvider#provideSummary(androidx.preference.EditTextPreference) parameter #0:
+    Missing nullability on parameter `preference` in method `provideSummary`
+MissingNullability: androidx.preference.EditTextPreferenceDialogFragment#newInstance(String) parameter #0:
+    Missing nullability on parameter `key` in method `newInstance`
+MissingNullability: androidx.preference.EditTextPreferenceDialogFragment#onBindDialogView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onBindDialogView`
+MissingNullability: androidx.preference.EditTextPreferenceDialogFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.preference.EditTextPreferenceDialogFragmentCompat#newInstance(String):
+    Missing nullability on method `newInstance` return
+MissingNullability: androidx.preference.EditTextPreferenceDialogFragmentCompat#newInstance(String) parameter #0:
+    Missing nullability on parameter `key` in method `newInstance`
+MissingNullability: androidx.preference.EditTextPreferenceDialogFragmentCompat#onBindDialogView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onBindDialogView`
+MissingNullability: androidx.preference.EditTextPreferenceDialogFragmentCompat#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.preference.ListPreference#ListPreference(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `ListPreference`
+MissingNullability: androidx.preference.ListPreference#ListPreference(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `ListPreference`
+MissingNullability: androidx.preference.ListPreference#ListPreference(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `ListPreference`
+MissingNullability: androidx.preference.ListPreference#ListPreference(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `ListPreference`
+MissingNullability: androidx.preference.ListPreference#ListPreference(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `ListPreference`
+MissingNullability: androidx.preference.ListPreference#ListPreference(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `ListPreference`
+MissingNullability: androidx.preference.ListPreference#ListPreference(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `ListPreference`
+MissingNullability: androidx.preference.ListPreference#findIndexOfValue(String) parameter #0:
+    Missing nullability on parameter `value` in method `findIndexOfValue`
+MissingNullability: androidx.preference.ListPreference#getEntries():
+    Missing nullability on method `getEntries` return
+MissingNullability: androidx.preference.ListPreference#getEntry():
+    Missing nullability on method `getEntry` return
+MissingNullability: androidx.preference.ListPreference#getEntryValues():
+    Missing nullability on method `getEntryValues` return
+MissingNullability: androidx.preference.ListPreference#getSummary():
+    Missing nullability on method `getSummary` return
+MissingNullability: androidx.preference.ListPreference#getValue():
+    Missing nullability on method `getValue` return
+MissingNullability: androidx.preference.ListPreference#onGetDefaultValue(android.content.res.TypedArray, int):
+    Missing nullability on method `onGetDefaultValue` return
+MissingNullability: androidx.preference.ListPreference#onGetDefaultValue(android.content.res.TypedArray, int) parameter #0:
+    Missing nullability on parameter `a` in method `onGetDefaultValue`
+MissingNullability: androidx.preference.ListPreference#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.preference.ListPreference#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.preference.ListPreference#onSetInitialValue(Object) parameter #0:
+    Missing nullability on parameter `defaultValue` in method `onSetInitialValue`
+MissingNullability: androidx.preference.ListPreference#setEntries(CharSequence[]) parameter #0:
+    Missing nullability on parameter `entries` in method `setEntries`
+MissingNullability: androidx.preference.ListPreference#setEntryValues(CharSequence[]) parameter #0:
+    Missing nullability on parameter `entryValues` in method `setEntryValues`
+MissingNullability: androidx.preference.ListPreference#setSummary(CharSequence) parameter #0:
+    Missing nullability on parameter `summary` in method `setSummary`
+MissingNullability: androidx.preference.ListPreference#setValue(String) parameter #0:
+    Missing nullability on parameter `value` in method `setValue`
+MissingNullability: androidx.preference.ListPreference.SimpleSummaryProvider#getInstance():
+    Missing nullability on method `getInstance` return
+MissingNullability: androidx.preference.ListPreference.SimpleSummaryProvider#provideSummary(androidx.preference.ListPreference):
+    Missing nullability on method `provideSummary` return
+MissingNullability: androidx.preference.ListPreference.SimpleSummaryProvider#provideSummary(androidx.preference.ListPreference) parameter #0:
+    Missing nullability on parameter `preference` in method `provideSummary`
+MissingNullability: androidx.preference.ListPreferenceDialogFragment#newInstance(String) parameter #0:
+    Missing nullability on parameter `key` in method `newInstance`
+MissingNullability: androidx.preference.ListPreferenceDialogFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.preference.ListPreferenceDialogFragment#onPrepareDialogBuilder(android.app.AlertDialog.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `onPrepareDialogBuilder`
+MissingNullability: androidx.preference.ListPreferenceDialogFragmentCompat#newInstance(String):
+    Missing nullability on method `newInstance` return
+MissingNullability: androidx.preference.ListPreferenceDialogFragmentCompat#newInstance(String) parameter #0:
+    Missing nullability on parameter `key` in method `newInstance`
+MissingNullability: androidx.preference.ListPreferenceDialogFragmentCompat#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.preference.ListPreferenceDialogFragmentCompat#onPrepareDialogBuilder(androidx.appcompat.app.AlertDialog.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `onPrepareDialogBuilder`
+MissingNullability: androidx.preference.MultiSelectListPreference#MultiSelectListPreference(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `MultiSelectListPreference`
+MissingNullability: androidx.preference.MultiSelectListPreference#MultiSelectListPreference(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `MultiSelectListPreference`
+MissingNullability: androidx.preference.MultiSelectListPreference#MultiSelectListPreference(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `MultiSelectListPreference`
+MissingNullability: androidx.preference.MultiSelectListPreference#MultiSelectListPreference(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `MultiSelectListPreference`
+MissingNullability: androidx.preference.MultiSelectListPreference#MultiSelectListPreference(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `MultiSelectListPreference`
+MissingNullability: androidx.preference.MultiSelectListPreference#MultiSelectListPreference(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `MultiSelectListPreference`
+MissingNullability: androidx.preference.MultiSelectListPreference#MultiSelectListPreference(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `MultiSelectListPreference`
+MissingNullability: androidx.preference.MultiSelectListPreference#findIndexOfValue(String) parameter #0:
+    Missing nullability on parameter `value` in method `findIndexOfValue`
+MissingNullability: androidx.preference.MultiSelectListPreference#getEntries():
+    Missing nullability on method `getEntries` return
+MissingNullability: androidx.preference.MultiSelectListPreference#getEntryValues():
+    Missing nullability on method `getEntryValues` return
+MissingNullability: androidx.preference.MultiSelectListPreference#getSelectedItems():
+    Missing nullability on method `getSelectedItems` return
+MissingNullability: androidx.preference.MultiSelectListPreference#getValues():
+    Missing nullability on method `getValues` return
+MissingNullability: androidx.preference.MultiSelectListPreference#onGetDefaultValue(android.content.res.TypedArray, int):
+    Missing nullability on method `onGetDefaultValue` return
+MissingNullability: androidx.preference.MultiSelectListPreference#onGetDefaultValue(android.content.res.TypedArray, int) parameter #0:
+    Missing nullability on parameter `a` in method `onGetDefaultValue`
+MissingNullability: androidx.preference.MultiSelectListPreference#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.preference.MultiSelectListPreference#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.preference.MultiSelectListPreference#onSetInitialValue(Object) parameter #0:
+    Missing nullability on parameter `defaultValue` in method `onSetInitialValue`
+MissingNullability: androidx.preference.MultiSelectListPreference#setEntries(CharSequence[]) parameter #0:
+    Missing nullability on parameter `entries` in method `setEntries`
+MissingNullability: androidx.preference.MultiSelectListPreference#setEntryValues(CharSequence[]) parameter #0:
+    Missing nullability on parameter `entryValues` in method `setEntryValues`
+MissingNullability: androidx.preference.MultiSelectListPreference#setValues(java.util.Set<java.lang.String>) parameter #0:
+    Missing nullability on parameter `values` in method `setValues`
+MissingNullability: androidx.preference.MultiSelectListPreferenceDialogFragment#newInstance(String) parameter #0:
+    Missing nullability on parameter `key` in method `newInstance`
+MissingNullability: androidx.preference.MultiSelectListPreferenceDialogFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.preference.MultiSelectListPreferenceDialogFragment#onPrepareDialogBuilder(android.app.AlertDialog.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `onPrepareDialogBuilder`
+MissingNullability: androidx.preference.MultiSelectListPreferenceDialogFragmentCompat#newInstance(String):
+    Missing nullability on method `newInstance` return
+MissingNullability: androidx.preference.MultiSelectListPreferenceDialogFragmentCompat#newInstance(String) parameter #0:
+    Missing nullability on parameter `key` in method `newInstance`
+MissingNullability: androidx.preference.MultiSelectListPreferenceDialogFragmentCompat#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.preference.MultiSelectListPreferenceDialogFragmentCompat#onPrepareDialogBuilder(androidx.appcompat.app.AlertDialog.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `onPrepareDialogBuilder`
+MissingNullability: androidx.preference.Preference#Preference(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `Preference`
+MissingNullability: androidx.preference.Preference#Preference(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `Preference`
+MissingNullability: androidx.preference.Preference#Preference(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `Preference`
+MissingNullability: androidx.preference.Preference#Preference(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `Preference`
+MissingNullability: androidx.preference.Preference#Preference(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `Preference`
+MissingNullability: androidx.preference.Preference#Preference(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `Preference`
+MissingNullability: androidx.preference.Preference#Preference(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `Preference`
+MissingNullability: androidx.preference.Preference#callChangeListener(Object) parameter #0:
+    Missing nullability on parameter `newValue` in method `callChangeListener`
+MissingNullability: androidx.preference.Preference#getContext():
+    Missing nullability on method `getContext` return
+MissingNullability: androidx.preference.Preference#getDependency():
+    Missing nullability on method `getDependency` return
+MissingNullability: androidx.preference.Preference#getExtras():
+    Missing nullability on method `getExtras` return
+MissingNullability: androidx.preference.Preference#getFragment():
+    Missing nullability on method `getFragment` return
+MissingNullability: androidx.preference.Preference#getIcon():
+    Missing nullability on method `getIcon` return
+MissingNullability: androidx.preference.Preference#getIntent():
+    Missing nullability on method `getIntent` return
+MissingNullability: androidx.preference.Preference#getKey():
+    Missing nullability on method `getKey` return
+MissingNullability: androidx.preference.Preference#getOnPreferenceChangeListener():
+    Missing nullability on method `getOnPreferenceChangeListener` return
+MissingNullability: androidx.preference.Preference#getOnPreferenceClickListener():
+    Missing nullability on method `getOnPreferenceClickListener` return
+MissingNullability: androidx.preference.Preference#getPersistedString(String):
+    Missing nullability on method `getPersistedString` return
+MissingNullability: androidx.preference.Preference#getPersistedString(String) parameter #0:
+    Missing nullability on parameter `defaultReturnValue` in method `getPersistedString`
+MissingNullability: androidx.preference.Preference#getPersistedStringSet(java.util.Set<java.lang.String>):
+    Missing nullability on method `getPersistedStringSet` return
+MissingNullability: androidx.preference.Preference#getPersistedStringSet(java.util.Set<java.lang.String>) parameter #0:
+    Missing nullability on parameter `defaultReturnValue` in method `getPersistedStringSet`
+MissingNullability: androidx.preference.Preference#getPreferenceManager():
+    Missing nullability on method `getPreferenceManager` return
+MissingNullability: androidx.preference.Preference#getSharedPreferences():
+    Missing nullability on method `getSharedPreferences` return
+MissingNullability: androidx.preference.Preference#getSummary():
+    Missing nullability on method `getSummary` return
+MissingNullability: androidx.preference.Preference#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.preference.Preference#onAttachedToHierarchy(androidx.preference.PreferenceManager) parameter #0:
+    Missing nullability on parameter `preferenceManager` in method `onAttachedToHierarchy`
+MissingNullability: androidx.preference.Preference#onBindViewHolder(androidx.preference.PreferenceViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onBindViewHolder`
+MissingNullability: androidx.preference.Preference#onDependencyChanged(androidx.preference.Preference, boolean) parameter #0:
+    Missing nullability on parameter `dependency` in method `onDependencyChanged`
+MissingNullability: androidx.preference.Preference#onGetDefaultValue(android.content.res.TypedArray, int):
+    Missing nullability on method `onGetDefaultValue` return
+MissingNullability: androidx.preference.Preference#onGetDefaultValue(android.content.res.TypedArray, int) parameter #0:
+    Missing nullability on parameter `a` in method `onGetDefaultValue`
+MissingNullability: androidx.preference.Preference#onInitializeAccessibilityNodeInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #0:
+    Missing nullability on parameter `info` in method `onInitializeAccessibilityNodeInfo`
+MissingNullability: androidx.preference.Preference#onParentChanged(androidx.preference.Preference, boolean) parameter #0:
+    Missing nullability on parameter `parent` in method `onParentChanged`
+MissingNullability: androidx.preference.Preference#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.preference.Preference#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.preference.Preference#onSetInitialValue(boolean, Object) parameter #1:
+    Missing nullability on parameter `defaultValue` in method `onSetInitialValue`
+MissingNullability: androidx.preference.Preference#peekExtras():
+    Missing nullability on method `peekExtras` return
+MissingNullability: androidx.preference.Preference#persistString(String) parameter #0:
+    Missing nullability on parameter `value` in method `persistString`
+MissingNullability: androidx.preference.Preference#persistStringSet(java.util.Set<java.lang.String>) parameter #0:
+    Missing nullability on parameter `values` in method `persistStringSet`
+MissingNullability: androidx.preference.Preference#restoreHierarchyState(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `container` in method `restoreHierarchyState`
+MissingNullability: androidx.preference.Preference#saveHierarchyState(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `container` in method `saveHierarchyState`
+MissingNullability: androidx.preference.Preference#setDefaultValue(Object) parameter #0:
+    Missing nullability on parameter `defaultValue` in method `setDefaultValue`
+MissingNullability: androidx.preference.Preference#setDependency(String) parameter #0:
+    Missing nullability on parameter `dependencyKey` in method `setDependency`
+MissingNullability: androidx.preference.Preference#setFragment(String) parameter #0:
+    Missing nullability on parameter `fragment` in method `setFragment`
+MissingNullability: androidx.preference.Preference#setIcon(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `icon` in method `setIcon`
+MissingNullability: androidx.preference.Preference#setIntent(android.content.Intent) parameter #0:
+    Missing nullability on parameter `intent` in method `setIntent`
+MissingNullability: androidx.preference.Preference#setKey(String) parameter #0:
+    Missing nullability on parameter `key` in method `setKey`
+MissingNullability: androidx.preference.Preference#setOnPreferenceChangeListener(androidx.preference.Preference.OnPreferenceChangeListener) parameter #0:
+    Missing nullability on parameter `onPreferenceChangeListener` in method `setOnPreferenceChangeListener`
+MissingNullability: androidx.preference.Preference#setOnPreferenceClickListener(androidx.preference.Preference.OnPreferenceClickListener) parameter #0:
+    Missing nullability on parameter `onPreferenceClickListener` in method `setOnPreferenceClickListener`
+MissingNullability: androidx.preference.Preference#setPreferenceDataStore(androidx.preference.PreferenceDataStore) parameter #0:
+    Missing nullability on parameter `dataStore` in method `setPreferenceDataStore`
+MissingNullability: androidx.preference.Preference#setSummary(CharSequence) parameter #0:
+    Missing nullability on parameter `summary` in method `setSummary`
+MissingNullability: androidx.preference.Preference#setTitle(CharSequence) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.preference.Preference#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.preference.Preference.BaseSavedState#BaseSavedState(android.os.Parcel) parameter #0:
+    Missing nullability on parameter `source` in method `BaseSavedState`
+MissingNullability: androidx.preference.Preference.BaseSavedState#BaseSavedState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `superState` in method `BaseSavedState`
+MissingNullability: androidx.preference.Preference.BaseSavedState#CREATOR:
+    Missing nullability on field `CREATOR` in class `class androidx.preference.Preference.BaseSavedState`
+MissingNullability: androidx.preference.Preference.OnPreferenceChangeListener#onPreferenceChange(androidx.preference.Preference, Object) parameter #0:
+    Missing nullability on parameter `preference` in method `onPreferenceChange`
+MissingNullability: androidx.preference.Preference.OnPreferenceChangeListener#onPreferenceChange(androidx.preference.Preference, Object) parameter #1:
+    Missing nullability on parameter `newValue` in method `onPreferenceChange`
+MissingNullability: androidx.preference.Preference.OnPreferenceClickListener#onPreferenceClick(androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `preference` in method `onPreferenceClick`
+MissingNullability: androidx.preference.Preference.SummaryProvider#provideSummary(T):
+    Missing nullability on method `provideSummary` return
+MissingNullability: androidx.preference.PreferenceCategory#PreferenceCategory(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `PreferenceCategory`
+MissingNullability: androidx.preference.PreferenceCategory#PreferenceCategory(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `PreferenceCategory`
+MissingNullability: androidx.preference.PreferenceCategory#PreferenceCategory(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `PreferenceCategory`
+MissingNullability: androidx.preference.PreferenceCategory#PreferenceCategory(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `PreferenceCategory`
+MissingNullability: androidx.preference.PreferenceCategory#PreferenceCategory(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `PreferenceCategory`
+MissingNullability: androidx.preference.PreferenceCategory#PreferenceCategory(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `PreferenceCategory`
+MissingNullability: androidx.preference.PreferenceCategory#PreferenceCategory(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `PreferenceCategory`
+MissingNullability: androidx.preference.PreferenceCategory#onBindViewHolder(androidx.preference.PreferenceViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onBindViewHolder`
+MissingNullability: androidx.preference.PreferenceCategory#onInitializeAccessibilityNodeInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #0:
+    Missing nullability on parameter `info` in method `onInitializeAccessibilityNodeInfo`
+MissingNullability: androidx.preference.PreferenceDataStore#getBoolean(String, boolean) parameter #0:
+    Missing nullability on parameter `key` in method `getBoolean`
+MissingNullability: androidx.preference.PreferenceDataStore#getFloat(String, float) parameter #0:
+    Missing nullability on parameter `key` in method `getFloat`
+MissingNullability: androidx.preference.PreferenceDataStore#getInt(String, int) parameter #0:
+    Missing nullability on parameter `key` in method `getInt`
+MissingNullability: androidx.preference.PreferenceDataStore#getLong(String, long) parameter #0:
+    Missing nullability on parameter `key` in method `getLong`
+MissingNullability: androidx.preference.PreferenceDataStore#getString(String, String) parameter #0:
+    Missing nullability on parameter `key` in method `getString`
+MissingNullability: androidx.preference.PreferenceDataStore#getStringSet(String, java.util.Set<java.lang.String>) parameter #0:
+    Missing nullability on parameter `key` in method `getStringSet`
+MissingNullability: androidx.preference.PreferenceDataStore#putBoolean(String, boolean) parameter #0:
+    Missing nullability on parameter `key` in method `putBoolean`
+MissingNullability: androidx.preference.PreferenceDataStore#putFloat(String, float) parameter #0:
+    Missing nullability on parameter `key` in method `putFloat`
+MissingNullability: androidx.preference.PreferenceDataStore#putInt(String, int) parameter #0:
+    Missing nullability on parameter `key` in method `putInt`
+MissingNullability: androidx.preference.PreferenceDataStore#putLong(String, long) parameter #0:
+    Missing nullability on parameter `key` in method `putLong`
+MissingNullability: androidx.preference.PreferenceDataStore#putString(String, String) parameter #0:
+    Missing nullability on parameter `key` in method `putString`
+MissingNullability: androidx.preference.PreferenceDataStore#putStringSet(String, java.util.Set<java.lang.String>) parameter #0:
+    Missing nullability on parameter `key` in method `putStringSet`
+MissingNullability: androidx.preference.PreferenceDialogFragment#onBindDialogView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onBindDialogView`
+MissingNullability: androidx.preference.PreferenceDialogFragment#onClick(android.content.DialogInterface, int) parameter #0:
+    Missing nullability on parameter `dialog` in method `onClick`
+MissingNullability: androidx.preference.PreferenceDialogFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.preference.PreferenceDialogFragment#onCreateDialog(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateDialog`
+MissingNullability: androidx.preference.PreferenceDialogFragment#onCreateDialogView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `onCreateDialogView`
+MissingNullability: androidx.preference.PreferenceDialogFragment#onDismiss(android.content.DialogInterface) parameter #0:
+    Missing nullability on parameter `dialog` in method `onDismiss`
+MissingNullability: androidx.preference.PreferenceDialogFragment#onPrepareDialogBuilder(android.app.AlertDialog.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `onPrepareDialogBuilder`
+MissingNullability: androidx.preference.PreferenceDialogFragmentCompat#getPreference():
+    Missing nullability on method `getPreference` return
+MissingNullability: androidx.preference.PreferenceDialogFragmentCompat#onBindDialogView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onBindDialogView`
+MissingNullability: androidx.preference.PreferenceDialogFragmentCompat#onClick(android.content.DialogInterface, int) parameter #0:
+    Missing nullability on parameter `dialog` in method `onClick`
+MissingNullability: androidx.preference.PreferenceDialogFragmentCompat#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.preference.PreferenceDialogFragmentCompat#onCreateDialog(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateDialog`
+MissingNullability: androidx.preference.PreferenceDialogFragmentCompat#onCreateDialogView(android.content.Context):
+    Missing nullability on method `onCreateDialogView` return
+MissingNullability: androidx.preference.PreferenceDialogFragmentCompat#onCreateDialogView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `onCreateDialogView`
+MissingNullability: androidx.preference.PreferenceDialogFragmentCompat#onPrepareDialogBuilder(androidx.appcompat.app.AlertDialog.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `onPrepareDialogBuilder`
+MissingNullability: androidx.preference.PreferenceFragment#findPreference(CharSequence) parameter #0:
+    Missing nullability on parameter `key` in method `findPreference`
+MissingNullability: androidx.preference.PreferenceFragment#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.preference.PreferenceFragment#onCreateAdapter(androidx.preference.PreferenceScreen) parameter #0:
+    Missing nullability on parameter `preferenceScreen` in method `onCreateAdapter`
+MissingNullability: androidx.preference.PreferenceFragment#onCreatePreferences(android.os.Bundle, String) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreatePreferences`
+MissingNullability: androidx.preference.PreferenceFragment#onCreatePreferences(android.os.Bundle, String) parameter #1:
+    Missing nullability on parameter `rootKey` in method `onCreatePreferences`
+MissingNullability: androidx.preference.PreferenceFragment#onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateRecyclerView`
+MissingNullability: androidx.preference.PreferenceFragment#onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `parent` in method `onCreateRecyclerView`
+MissingNullability: androidx.preference.PreferenceFragment#onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateRecyclerView`
+MissingNullability: androidx.preference.PreferenceFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.preference.PreferenceFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateView`
+MissingNullability: androidx.preference.PreferenceFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `container` in method `onCreateView`
+MissingNullability: androidx.preference.PreferenceFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateView`
+MissingNullability: androidx.preference.PreferenceFragment#onDisplayPreferenceDialog(androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `preference` in method `onDisplayPreferenceDialog`
+MissingNullability: androidx.preference.PreferenceFragment#onNavigateToScreen(androidx.preference.PreferenceScreen) parameter #0:
+    Missing nullability on parameter `preferenceScreen` in method `onNavigateToScreen`
+MissingNullability: androidx.preference.PreferenceFragment#onPreferenceTreeClick(androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `preference` in method `onPreferenceTreeClick`
+MissingNullability: androidx.preference.PreferenceFragment#onSaveInstanceState(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `outState` in method `onSaveInstanceState`
+MissingNullability: androidx.preference.PreferenceFragment#onViewCreated(android.view.View, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `view` in method `onViewCreated`
+MissingNullability: androidx.preference.PreferenceFragment#onViewCreated(android.view.View, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `savedInstanceState` in method `onViewCreated`
+MissingNullability: androidx.preference.PreferenceFragment#scrollToPreference(String) parameter #0:
+    Missing nullability on parameter `key` in method `scrollToPreference`
+MissingNullability: androidx.preference.PreferenceFragment#scrollToPreference(androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `preference` in method `scrollToPreference`
+MissingNullability: androidx.preference.PreferenceFragment#setDivider(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `divider` in method `setDivider`
+MissingNullability: androidx.preference.PreferenceFragment#setPreferenceScreen(androidx.preference.PreferenceScreen) parameter #0:
+    Missing nullability on parameter `preferenceScreen` in method `setPreferenceScreen`
+MissingNullability: androidx.preference.PreferenceFragment.OnPreferenceDisplayDialogCallback#onPreferenceDisplayDialog(androidx.preference.PreferenceFragment, androidx.preference.Preference) parameter #1:
+    Missing nullability on parameter `pref` in method `onPreferenceDisplayDialog`
+MissingNullability: androidx.preference.PreferenceFragment.OnPreferenceStartFragmentCallback#onPreferenceStartFragment(androidx.preference.PreferenceFragment, androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `caller` in method `onPreferenceStartFragment`
+MissingNullability: androidx.preference.PreferenceFragment.OnPreferenceStartFragmentCallback#onPreferenceStartFragment(androidx.preference.PreferenceFragment, androidx.preference.Preference) parameter #1:
+    Missing nullability on parameter `pref` in method `onPreferenceStartFragment`
+MissingNullability: androidx.preference.PreferenceFragment.OnPreferenceStartScreenCallback#onPreferenceStartScreen(androidx.preference.PreferenceFragment, androidx.preference.PreferenceScreen) parameter #0:
+    Missing nullability on parameter `caller` in method `onPreferenceStartScreen`
+MissingNullability: androidx.preference.PreferenceFragment.OnPreferenceStartScreenCallback#onPreferenceStartScreen(androidx.preference.PreferenceFragment, androidx.preference.PreferenceScreen) parameter #1:
+    Missing nullability on parameter `pref` in method `onPreferenceStartScreen`
+MissingNullability: androidx.preference.PreferenceFragmentCompat#getListView():
+    Missing nullability on method `getListView` return
+MissingNullability: androidx.preference.PreferenceFragmentCompat#getPreferenceManager():
+    Missing nullability on method `getPreferenceManager` return
+MissingNullability: androidx.preference.PreferenceFragmentCompat#getPreferenceScreen():
+    Missing nullability on method `getPreferenceScreen` return
+MissingNullability: androidx.preference.PreferenceFragmentCompat#onCreateAdapter(androidx.preference.PreferenceScreen):
+    Missing nullability on method `onCreateAdapter` return
+MissingNullability: androidx.preference.PreferenceFragmentCompat#onCreateAdapter(androidx.preference.PreferenceScreen) parameter #0:
+    Missing nullability on parameter `preferenceScreen` in method `onCreateAdapter`
+MissingNullability: androidx.preference.PreferenceFragmentCompat#onCreateLayoutManager():
+    Missing nullability on method `onCreateLayoutManager` return
+MissingNullability: androidx.preference.PreferenceFragmentCompat#onCreatePreferences(android.os.Bundle, String) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreatePreferences`
+MissingNullability: androidx.preference.PreferenceFragmentCompat#onCreatePreferences(android.os.Bundle, String) parameter #1:
+    Missing nullability on parameter `rootKey` in method `onCreatePreferences`
+MissingNullability: androidx.preference.PreferenceFragmentCompat#onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateRecyclerView` return
+MissingNullability: androidx.preference.PreferenceFragmentCompat#onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `inflater` in method `onCreateRecyclerView`
+MissingNullability: androidx.preference.PreferenceFragmentCompat#onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `parent` in method `onCreateRecyclerView`
+MissingNullability: androidx.preference.PreferenceFragmentCompat#onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `savedInstanceState` in method `onCreateRecyclerView`
+MissingNullability: androidx.preference.PreferenceFragmentCompat#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle):
+    Missing nullability on method `onCreateView` return
+MissingNullability: androidx.preference.PreferenceFragmentCompat#onDisplayPreferenceDialog(androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `preference` in method `onDisplayPreferenceDialog`
+MissingNullability: androidx.preference.PreferenceFragmentCompat#onNavigateToScreen(androidx.preference.PreferenceScreen) parameter #0:
+    Missing nullability on parameter `preferenceScreen` in method `onNavigateToScreen`
+MissingNullability: androidx.preference.PreferenceFragmentCompat#onPreferenceTreeClick(androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `preference` in method `onPreferenceTreeClick`
+MissingNullability: androidx.preference.PreferenceFragmentCompat#scrollToPreference(String) parameter #0:
+    Missing nullability on parameter `key` in method `scrollToPreference`
+MissingNullability: androidx.preference.PreferenceFragmentCompat#scrollToPreference(androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `preference` in method `scrollToPreference`
+MissingNullability: androidx.preference.PreferenceFragmentCompat#setDivider(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `divider` in method `setDivider`
+MissingNullability: androidx.preference.PreferenceFragmentCompat#setPreferenceScreen(androidx.preference.PreferenceScreen) parameter #0:
+    Missing nullability on parameter `preferenceScreen` in method `setPreferenceScreen`
+MissingNullability: androidx.preference.PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback#onPreferenceDisplayDialog(androidx.preference.PreferenceFragmentCompat, androidx.preference.Preference) parameter #1:
+    Missing nullability on parameter `pref` in method `onPreferenceDisplayDialog`
+MissingNullability: androidx.preference.PreferenceFragmentCompat.OnPreferenceStartFragmentCallback#onPreferenceStartFragment(androidx.preference.PreferenceFragmentCompat, androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `caller` in method `onPreferenceStartFragment`
+MissingNullability: androidx.preference.PreferenceFragmentCompat.OnPreferenceStartFragmentCallback#onPreferenceStartFragment(androidx.preference.PreferenceFragmentCompat, androidx.preference.Preference) parameter #1:
+    Missing nullability on parameter `pref` in method `onPreferenceStartFragment`
+MissingNullability: androidx.preference.PreferenceFragmentCompat.OnPreferenceStartScreenCallback#onPreferenceStartScreen(androidx.preference.PreferenceFragmentCompat, androidx.preference.PreferenceScreen) parameter #0:
+    Missing nullability on parameter `caller` in method `onPreferenceStartScreen`
+MissingNullability: androidx.preference.PreferenceFragmentCompat.OnPreferenceStartScreenCallback#onPreferenceStartScreen(androidx.preference.PreferenceFragmentCompat, androidx.preference.PreferenceScreen) parameter #1:
+    Missing nullability on parameter `pref` in method `onPreferenceStartScreen`
+MissingNullability: androidx.preference.PreferenceGroup#PreferenceGroup(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `PreferenceGroup`
+MissingNullability: androidx.preference.PreferenceGroup#PreferenceGroup(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `PreferenceGroup`
+MissingNullability: androidx.preference.PreferenceGroup#PreferenceGroup(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `PreferenceGroup`
+MissingNullability: androidx.preference.PreferenceGroup#PreferenceGroup(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `PreferenceGroup`
+MissingNullability: androidx.preference.PreferenceGroup#PreferenceGroup(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `PreferenceGroup`
+MissingNullability: androidx.preference.PreferenceGroup#PreferenceGroup(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `PreferenceGroup`
+MissingNullability: androidx.preference.PreferenceGroup#addItemFromInflater(androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `preference` in method `addItemFromInflater`
+MissingNullability: androidx.preference.PreferenceGroup#addPreference(androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `preference` in method `addPreference`
+MissingNullability: androidx.preference.PreferenceGroup#dispatchRestoreInstanceState(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `container` in method `dispatchRestoreInstanceState`
+MissingNullability: androidx.preference.PreferenceGroup#dispatchSaveInstanceState(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `container` in method `dispatchSaveInstanceState`
+MissingNullability: androidx.preference.PreferenceGroup#getPreference(int):
+    Missing nullability on method `getPreference` return
+MissingNullability: androidx.preference.PreferenceGroup#onPrepareAddPreference(androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `preference` in method `onPrepareAddPreference`
+MissingNullability: androidx.preference.PreferenceGroup#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.preference.PreferenceGroup#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.preference.PreferenceGroup#removePreference(androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `preference` in method `removePreference`
+MissingNullability: androidx.preference.PreferenceGroup.PreferencePositionCallback#getPreferenceAdapterPosition(String) parameter #0:
+    Missing nullability on parameter `key` in method `getPreferenceAdapterPosition`
+MissingNullability: androidx.preference.PreferenceGroup.PreferencePositionCallback#getPreferenceAdapterPosition(androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `preference` in method `getPreferenceAdapterPosition`
+MissingNullability: androidx.preference.PreferenceManager#createPreferenceScreen(android.content.Context):
+    Missing nullability on method `createPreferenceScreen` return
+MissingNullability: androidx.preference.PreferenceManager#createPreferenceScreen(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `createPreferenceScreen`
+MissingNullability: androidx.preference.PreferenceManager#getContext():
+    Missing nullability on method `getContext` return
+MissingNullability: androidx.preference.PreferenceManager#getDefaultSharedPreferences(android.content.Context):
+    Missing nullability on method `getDefaultSharedPreferences` return
+MissingNullability: androidx.preference.PreferenceManager#getDefaultSharedPreferences(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `getDefaultSharedPreferences`
+MissingNullability: androidx.preference.PreferenceManager#getOnDisplayPreferenceDialogListener():
+    Missing nullability on method `getOnDisplayPreferenceDialogListener` return
+MissingNullability: androidx.preference.PreferenceManager#getOnNavigateToScreenListener():
+    Missing nullability on method `getOnNavigateToScreenListener` return
+MissingNullability: androidx.preference.PreferenceManager#getOnPreferenceTreeClickListener():
+    Missing nullability on method `getOnPreferenceTreeClickListener` return
+MissingNullability: androidx.preference.PreferenceManager#getPreferenceComparisonCallback():
+    Missing nullability on method `getPreferenceComparisonCallback` return
+MissingNullability: androidx.preference.PreferenceManager#getPreferenceScreen():
+    Missing nullability on method `getPreferenceScreen` return
+MissingNullability: androidx.preference.PreferenceManager#getSharedPreferences():
+    Missing nullability on method `getSharedPreferences` return
+MissingNullability: androidx.preference.PreferenceManager#getSharedPreferencesName():
+    Missing nullability on method `getSharedPreferencesName` return
+MissingNullability: androidx.preference.PreferenceManager#setDefaultValues(android.content.Context, String, int, int, boolean) parameter #0:
+    Missing nullability on parameter `context` in method `setDefaultValues`
+MissingNullability: androidx.preference.PreferenceManager#setDefaultValues(android.content.Context, String, int, int, boolean) parameter #1:
+    Missing nullability on parameter `sharedPreferencesName` in method `setDefaultValues`
+MissingNullability: androidx.preference.PreferenceManager#setDefaultValues(android.content.Context, int, boolean) parameter #0:
+    Missing nullability on parameter `context` in method `setDefaultValues`
+MissingNullability: androidx.preference.PreferenceManager#setOnDisplayPreferenceDialogListener(androidx.preference.PreferenceManager.OnDisplayPreferenceDialogListener) parameter #0:
+    Missing nullability on parameter `onDisplayPreferenceDialogListener` in method `setOnDisplayPreferenceDialogListener`
+MissingNullability: androidx.preference.PreferenceManager#setOnNavigateToScreenListener(androidx.preference.PreferenceManager.OnNavigateToScreenListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnNavigateToScreenListener`
+MissingNullability: androidx.preference.PreferenceManager#setOnPreferenceTreeClickListener(androidx.preference.PreferenceManager.OnPreferenceTreeClickListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnPreferenceTreeClickListener`
+MissingNullability: androidx.preference.PreferenceManager#setPreferenceComparisonCallback(androidx.preference.PreferenceManager.PreferenceComparisonCallback) parameter #0:
+    Missing nullability on parameter `preferenceComparisonCallback` in method `setPreferenceComparisonCallback`
+MissingNullability: androidx.preference.PreferenceManager#setPreferenceDataStore(androidx.preference.PreferenceDataStore) parameter #0:
+    Missing nullability on parameter `dataStore` in method `setPreferenceDataStore`
+MissingNullability: androidx.preference.PreferenceManager#setPreferences(androidx.preference.PreferenceScreen) parameter #0:
+    Missing nullability on parameter `preferenceScreen` in method `setPreferences`
+MissingNullability: androidx.preference.PreferenceManager#setSharedPreferencesName(String) parameter #0:
+    Missing nullability on parameter `sharedPreferencesName` in method `setSharedPreferencesName`
+MissingNullability: androidx.preference.PreferenceManager#showDialog(androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `preference` in method `showDialog`
+MissingNullability: androidx.preference.PreferenceManager.OnDisplayPreferenceDialogListener#onDisplayPreferenceDialog(androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `preference` in method `onDisplayPreferenceDialog`
+MissingNullability: androidx.preference.PreferenceManager.OnNavigateToScreenListener#onNavigateToScreen(androidx.preference.PreferenceScreen) parameter #0:
+    Missing nullability on parameter `preferenceScreen` in method `onNavigateToScreen`
+MissingNullability: androidx.preference.PreferenceManager.OnPreferenceTreeClickListener#onPreferenceTreeClick(androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `preference` in method `onPreferenceTreeClick`
+MissingNullability: androidx.preference.PreferenceManager.PreferenceComparisonCallback#arePreferenceContentsTheSame(androidx.preference.Preference, androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `p1` in method `arePreferenceContentsTheSame`
+MissingNullability: androidx.preference.PreferenceManager.PreferenceComparisonCallback#arePreferenceContentsTheSame(androidx.preference.Preference, androidx.preference.Preference) parameter #1:
+    Missing nullability on parameter `p2` in method `arePreferenceContentsTheSame`
+MissingNullability: androidx.preference.PreferenceManager.PreferenceComparisonCallback#arePreferenceItemsTheSame(androidx.preference.Preference, androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `p1` in method `arePreferenceItemsTheSame`
+MissingNullability: androidx.preference.PreferenceManager.PreferenceComparisonCallback#arePreferenceItemsTheSame(androidx.preference.Preference, androidx.preference.Preference) parameter #1:
+    Missing nullability on parameter `p2` in method `arePreferenceItemsTheSame`
+MissingNullability: androidx.preference.PreferenceManager.SimplePreferenceComparisonCallback#arePreferenceContentsTheSame(androidx.preference.Preference, androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `p1` in method `arePreferenceContentsTheSame`
+MissingNullability: androidx.preference.PreferenceManager.SimplePreferenceComparisonCallback#arePreferenceContentsTheSame(androidx.preference.Preference, androidx.preference.Preference) parameter #1:
+    Missing nullability on parameter `p2` in method `arePreferenceContentsTheSame`
+MissingNullability: androidx.preference.PreferenceManager.SimplePreferenceComparisonCallback#arePreferenceItemsTheSame(androidx.preference.Preference, androidx.preference.Preference) parameter #0:
+    Missing nullability on parameter `p1` in method `arePreferenceItemsTheSame`
+MissingNullability: androidx.preference.PreferenceManager.SimplePreferenceComparisonCallback#arePreferenceItemsTheSame(androidx.preference.Preference, androidx.preference.Preference) parameter #1:
+    Missing nullability on parameter `p2` in method `arePreferenceItemsTheSame`
+MissingNullability: androidx.preference.PreferenceViewHolder#findViewById(int):
+    Missing nullability on method `findViewById` return
+MissingNullability: androidx.preference.SeekBarPreference#SeekBarPreference(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `SeekBarPreference`
+MissingNullability: androidx.preference.SeekBarPreference#SeekBarPreference(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `SeekBarPreference`
+MissingNullability: androidx.preference.SeekBarPreference#SeekBarPreference(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `SeekBarPreference`
+MissingNullability: androidx.preference.SeekBarPreference#SeekBarPreference(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `SeekBarPreference`
+MissingNullability: androidx.preference.SeekBarPreference#SeekBarPreference(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `SeekBarPreference`
+MissingNullability: androidx.preference.SeekBarPreference#SeekBarPreference(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `SeekBarPreference`
+MissingNullability: androidx.preference.SeekBarPreference#SeekBarPreference(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `SeekBarPreference`
+MissingNullability: androidx.preference.SeekBarPreference#onBindViewHolder(androidx.preference.PreferenceViewHolder) parameter #0:
+    Missing nullability on parameter `view` in method `onBindViewHolder`
+MissingNullability: androidx.preference.SeekBarPreference#onGetDefaultValue(android.content.res.TypedArray, int):
+    Missing nullability on method `onGetDefaultValue` return
+MissingNullability: androidx.preference.SeekBarPreference#onGetDefaultValue(android.content.res.TypedArray, int) parameter #0:
+    Missing nullability on parameter `a` in method `onGetDefaultValue`
+MissingNullability: androidx.preference.SeekBarPreference#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.preference.SeekBarPreference#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.preference.SeekBarPreference#onSetInitialValue(Object) parameter #0:
+    Missing nullability on parameter `defaultValue` in method `onSetInitialValue`
+MissingNullability: androidx.preference.SwitchPreference#SwitchPreference(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `SwitchPreference`
+MissingNullability: androidx.preference.SwitchPreference#SwitchPreference(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `SwitchPreference`
+MissingNullability: androidx.preference.SwitchPreference#SwitchPreference(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `SwitchPreference`
+MissingNullability: androidx.preference.SwitchPreference#SwitchPreference(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `SwitchPreference`
+MissingNullability: androidx.preference.SwitchPreference#SwitchPreference(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `SwitchPreference`
+MissingNullability: androidx.preference.SwitchPreference#SwitchPreference(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `SwitchPreference`
+MissingNullability: androidx.preference.SwitchPreference#SwitchPreference(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `SwitchPreference`
+MissingNullability: androidx.preference.SwitchPreference#getSwitchTextOff():
+    Missing nullability on method `getSwitchTextOff` return
+MissingNullability: androidx.preference.SwitchPreference#getSwitchTextOn():
+    Missing nullability on method `getSwitchTextOn` return
+MissingNullability: androidx.preference.SwitchPreference#onBindViewHolder(androidx.preference.PreferenceViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onBindViewHolder`
+MissingNullability: androidx.preference.SwitchPreference#setSwitchTextOff(CharSequence) parameter #0:
+    Missing nullability on parameter `offText` in method `setSwitchTextOff`
+MissingNullability: androidx.preference.SwitchPreference#setSwitchTextOn(CharSequence) parameter #0:
+    Missing nullability on parameter `onText` in method `setSwitchTextOn`
+MissingNullability: androidx.preference.SwitchPreferenceCompat#SwitchPreferenceCompat(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `SwitchPreferenceCompat`
+MissingNullability: androidx.preference.SwitchPreferenceCompat#SwitchPreferenceCompat(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `SwitchPreferenceCompat`
+MissingNullability: androidx.preference.SwitchPreferenceCompat#SwitchPreferenceCompat(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `SwitchPreferenceCompat`
+MissingNullability: androidx.preference.SwitchPreferenceCompat#SwitchPreferenceCompat(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `SwitchPreferenceCompat`
+MissingNullability: androidx.preference.SwitchPreferenceCompat#SwitchPreferenceCompat(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `SwitchPreferenceCompat`
+MissingNullability: androidx.preference.SwitchPreferenceCompat#SwitchPreferenceCompat(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `SwitchPreferenceCompat`
+MissingNullability: androidx.preference.SwitchPreferenceCompat#SwitchPreferenceCompat(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `SwitchPreferenceCompat`
+MissingNullability: androidx.preference.SwitchPreferenceCompat#getSwitchTextOff():
+    Missing nullability on method `getSwitchTextOff` return
+MissingNullability: androidx.preference.SwitchPreferenceCompat#getSwitchTextOn():
+    Missing nullability on method `getSwitchTextOn` return
+MissingNullability: androidx.preference.SwitchPreferenceCompat#onBindViewHolder(androidx.preference.PreferenceViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `onBindViewHolder`
+MissingNullability: androidx.preference.SwitchPreferenceCompat#setSwitchTextOff(CharSequence) parameter #0:
+    Missing nullability on parameter `offText` in method `setSwitchTextOff`
+MissingNullability: androidx.preference.SwitchPreferenceCompat#setSwitchTextOn(CharSequence) parameter #0:
+    Missing nullability on parameter `onText` in method `setSwitchTextOn`
+MissingNullability: androidx.preference.TwoStatePreference#TwoStatePreference(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `TwoStatePreference`
+MissingNullability: androidx.preference.TwoStatePreference#TwoStatePreference(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `TwoStatePreference`
+MissingNullability: androidx.preference.TwoStatePreference#TwoStatePreference(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `TwoStatePreference`
+MissingNullability: androidx.preference.TwoStatePreference#TwoStatePreference(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `TwoStatePreference`
+MissingNullability: androidx.preference.TwoStatePreference#TwoStatePreference(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `TwoStatePreference`
+MissingNullability: androidx.preference.TwoStatePreference#TwoStatePreference(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `TwoStatePreference`
+MissingNullability: androidx.preference.TwoStatePreference#TwoStatePreference(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `TwoStatePreference`
+MissingNullability: androidx.preference.TwoStatePreference#getSummaryOff():
+    Missing nullability on method `getSummaryOff` return
+MissingNullability: androidx.preference.TwoStatePreference#getSummaryOn():
+    Missing nullability on method `getSummaryOn` return
+MissingNullability: androidx.preference.TwoStatePreference#onGetDefaultValue(android.content.res.TypedArray, int):
+    Missing nullability on method `onGetDefaultValue` return
+MissingNullability: androidx.preference.TwoStatePreference#onGetDefaultValue(android.content.res.TypedArray, int) parameter #0:
+    Missing nullability on parameter `a` in method `onGetDefaultValue`
+MissingNullability: androidx.preference.TwoStatePreference#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.preference.TwoStatePreference#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.preference.TwoStatePreference#onSetInitialValue(Object) parameter #0:
+    Missing nullability on parameter `defaultValue` in method `onSetInitialValue`
+MissingNullability: androidx.preference.TwoStatePreference#setSummaryOff(CharSequence) parameter #0:
+    Missing nullability on parameter `summary` in method `setSummaryOff`
+MissingNullability: androidx.preference.TwoStatePreference#setSummaryOn(CharSequence) parameter #0:
+    Missing nullability on parameter `summary` in method `setSummaryOn`
+MissingNullability: androidx.preference.TwoStatePreference#syncSummaryView(androidx.preference.PreferenceViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `syncSummaryView`
+
+
+ParcelConstructor: androidx.preference.Preference.BaseSavedState#BaseSavedState(android.os.Parcel):
+    Parcelable inflation is exposed through CREATOR, not raw constructors, in androidx.preference.Preference.BaseSavedState
+
+
+ParcelCreator: androidx.preference.Preference.BaseSavedState:
+    Parcelable requires `void writeToParcel(Parcel, int)`; missing in androidx.preference.Preference.BaseSavedState
+
+
+ParcelNotFinal: androidx.preference.Preference.BaseSavedState:
+    Parcelable classes must be final: androidx.preference.Preference.BaseSavedState is not final
+
+
+VisiblySynchronized: androidx.preference.PreferenceGroup#addPreference(androidx.preference.Preference):
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method androidx.preference.PreferenceGroup.addPreference(androidx.preference.Preference)
+VisiblySynchronized: androidx.preference.PreferenceGroup#removeAll():
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method androidx.preference.PreferenceGroup.removeAll()
diff --git a/preference/api/current.txt b/preference/preference/api/current.txt
similarity index 100%
rename from preference/api/current.txt
rename to preference/preference/api/current.txt
diff --git a/preference/api/res-1.1.0-alpha02.txt b/preference/preference/api/res-1.1.0-alpha02.txt
similarity index 100%
rename from preference/api/res-1.1.0-alpha02.txt
rename to preference/preference/api/res-1.1.0-alpha02.txt
diff --git a/preference/api/res-1.1.0-alpha03.txt b/preference/preference/api/res-1.1.0-alpha03.txt
similarity index 100%
rename from preference/api/res-1.1.0-alpha03.txt
rename to preference/preference/api/res-1.1.0-alpha03.txt
diff --git a/preference/api/res-1.1.0-alpha04.txt b/preference/preference/api/res-1.1.0-alpha04.txt
similarity index 100%
rename from preference/api/res-1.1.0-alpha04.txt
rename to preference/preference/api/res-1.1.0-alpha04.txt
diff --git a/preference/api/res-1.1.0-alpha05.txt b/preference/preference/api/res-1.1.0-alpha05.txt
similarity index 100%
rename from preference/api/res-1.1.0-alpha05.txt
rename to preference/preference/api/res-1.1.0-alpha05.txt
diff --git a/preference/api/res-1.1.0-alpha06.txt b/preference/preference/api/res-1.1.0-alpha06.txt
similarity index 100%
rename from preference/api/res-1.1.0-alpha06.txt
rename to preference/preference/api/res-1.1.0-alpha06.txt
diff --git a/preference/api/res-1.1.0-beta01.txt b/preference/preference/api/res-1.1.0-beta01.txt
similarity index 100%
rename from preference/api/res-1.1.0-beta01.txt
rename to preference/preference/api/res-1.1.0-beta01.txt
diff --git a/preference/api/res-1.1.0-beta02.txt b/preference/preference/api/res-1.1.0-beta02.txt
similarity index 100%
rename from preference/api/res-1.1.0-beta02.txt
rename to preference/preference/api/res-1.1.0-beta02.txt
diff --git a/preference/api/res-1.1.0-rc01.txt b/preference/preference/api/res-1.1.0-rc01.txt
similarity index 100%
rename from preference/api/res-1.1.0-rc01.txt
rename to preference/preference/api/res-1.1.0-rc01.txt
diff --git a/preference/api/res-1.2.0-alpha01.txt b/preference/preference/api/res-1.2.0-alpha01.txt
similarity index 100%
rename from preference/api/res-1.2.0-alpha01.txt
rename to preference/preference/api/res-1.2.0-alpha01.txt
diff --git a/preference/api/restricted_1.0.0.txt b/preference/preference/api/restricted_1.0.0.txt
similarity index 100%
rename from preference/api/restricted_1.0.0.txt
rename to preference/preference/api/restricted_1.0.0.txt
diff --git a/preference/api/restricted_1.1.0-alpha04.ignore b/preference/preference/api/restricted_1.1.0-alpha04.ignore
similarity index 100%
rename from preference/api/restricted_1.1.0-alpha04.ignore
rename to preference/preference/api/restricted_1.1.0-alpha04.ignore
diff --git a/preference/api/restricted_1.1.0-alpha04.txt b/preference/preference/api/restricted_1.1.0-alpha04.txt
similarity index 100%
rename from preference/api/restricted_1.1.0-alpha04.txt
rename to preference/preference/api/restricted_1.1.0-alpha04.txt
diff --git a/preference/api/restricted_1.1.0-alpha05.ignore b/preference/preference/api/restricted_1.1.0-alpha05.ignore
similarity index 100%
rename from preference/api/restricted_1.1.0-alpha05.ignore
rename to preference/preference/api/restricted_1.1.0-alpha05.ignore
diff --git a/preference/api/restricted_1.1.0-alpha05.txt b/preference/preference/api/restricted_1.1.0-alpha05.txt
similarity index 100%
rename from preference/api/restricted_1.1.0-alpha05.txt
rename to preference/preference/api/restricted_1.1.0-alpha05.txt
diff --git a/preference/api/restricted_1.1.0-alpha06.ignore b/preference/preference/api/restricted_1.1.0-alpha06.ignore
similarity index 100%
rename from preference/api/restricted_1.1.0-alpha06.ignore
rename to preference/preference/api/restricted_1.1.0-alpha06.ignore
diff --git a/preference/api/restricted_1.1.0-alpha06.txt b/preference/preference/api/restricted_1.1.0-alpha06.txt
similarity index 100%
rename from preference/api/restricted_1.1.0-alpha06.txt
rename to preference/preference/api/restricted_1.1.0-alpha06.txt
diff --git a/preference/api/restricted_1.1.0-beta01.ignore b/preference/preference/api/restricted_1.1.0-beta01.ignore
similarity index 100%
rename from preference/api/restricted_1.1.0-beta01.ignore
rename to preference/preference/api/restricted_1.1.0-beta01.ignore
diff --git a/preference/api/restricted_1.1.0-beta01.txt b/preference/preference/api/restricted_1.1.0-beta01.txt
similarity index 100%
rename from preference/api/restricted_1.1.0-beta01.txt
rename to preference/preference/api/restricted_1.1.0-beta01.txt
diff --git a/preference/api/restricted_1.1.0-beta02.txt b/preference/preference/api/restricted_1.1.0-beta02.txt
similarity index 100%
rename from preference/api/restricted_1.1.0-beta02.txt
rename to preference/preference/api/restricted_1.1.0-beta02.txt
diff --git a/preference/api/restricted_1.1.0-rc01.ignore b/preference/preference/api/restricted_1.1.0-rc01.ignore
similarity index 100%
rename from preference/api/restricted_1.1.0-rc01.ignore
rename to preference/preference/api/restricted_1.1.0-rc01.ignore
diff --git a/preference/api/restricted_1.1.0-rc01.txt b/preference/preference/api/restricted_1.1.0-rc01.txt
similarity index 100%
rename from preference/api/restricted_1.1.0-rc01.txt
rename to preference/preference/api/restricted_1.1.0-rc01.txt
diff --git a/preference/api/restricted_1.2.0-alpha01.txt b/preference/preference/api/restricted_1.2.0-alpha01.txt
similarity index 100%
rename from preference/api/restricted_1.2.0-alpha01.txt
rename to preference/preference/api/restricted_1.2.0-alpha01.txt
diff --git a/preference/api/restricted_current.txt b/preference/preference/api/restricted_current.txt
similarity index 100%
rename from preference/api/restricted_current.txt
rename to preference/preference/api/restricted_current.txt
diff --git a/preference/api_legacy/26.0.0.txt b/preference/preference/api_legacy/26.0.0.txt
similarity index 100%
rename from preference/api_legacy/26.0.0.txt
rename to preference/preference/api_legacy/26.0.0.txt
diff --git a/preference/api_legacy/26.1.0.txt b/preference/preference/api_legacy/26.1.0.txt
similarity index 100%
rename from preference/api_legacy/26.1.0.txt
rename to preference/preference/api_legacy/26.1.0.txt
diff --git a/preference/api_legacy/27.0.0.txt b/preference/preference/api_legacy/27.0.0.txt
similarity index 100%
rename from preference/api_legacy/27.0.0.txt
rename to preference/preference/api_legacy/27.0.0.txt
diff --git a/preference/api_legacy/27.1.0.txt b/preference/preference/api_legacy/27.1.0.txt
similarity index 100%
rename from preference/api_legacy/27.1.0.txt
rename to preference/preference/api_legacy/27.1.0.txt
diff --git a/preference/api_legacy/28.0.0-alpha1.txt b/preference/preference/api_legacy/28.0.0-alpha1.txt
similarity index 100%
rename from preference/api_legacy/28.0.0-alpha1.txt
rename to preference/preference/api_legacy/28.0.0-alpha1.txt
diff --git a/preference/api_legacy/current.txt b/preference/preference/api_legacy/current.txt
similarity index 100%
rename from preference/api_legacy/current.txt
rename to preference/preference/api_legacy/current.txt
diff --git a/preference/build.gradle b/preference/preference/build.gradle
similarity index 100%
rename from preference/build.gradle
rename to preference/preference/build.gradle
diff --git a/preference/lint-baseline.xml b/preference/preference/lint-baseline.xml
similarity index 100%
rename from preference/lint-baseline.xml
rename to preference/preference/lint-baseline.xml
diff --git a/preference/proguard-rules.pro b/preference/preference/proguard-rules.pro
similarity index 100%
rename from preference/proguard-rules.pro
rename to preference/preference/proguard-rules.pro
diff --git a/preference/res-public/values/public_attrs.xml b/preference/preference/res-public/values/public_attrs.xml
similarity index 100%
rename from preference/res-public/values/public_attrs.xml
rename to preference/preference/res-public/values/public_attrs.xml
diff --git a/preference/res-public/values/public_styles.xml b/preference/preference/res-public/values/public_styles.xml
similarity index 100%
rename from preference/res-public/values/public_styles.xml
rename to preference/preference/res-public/values/public_styles.xml
diff --git a/preference/res-public/values/public_themes.xml b/preference/preference/res-public/values/public_themes.xml
similarity index 100%
rename from preference/res-public/values/public_themes.xml
rename to preference/preference/res-public/values/public_themes.xml
diff --git a/preference/res/drawable-v21/ic_arrow_down_24dp.xml b/preference/preference/res/drawable-v21/ic_arrow_down_24dp.xml
similarity index 100%
rename from preference/res/drawable-v21/ic_arrow_down_24dp.xml
rename to preference/preference/res/drawable-v21/ic_arrow_down_24dp.xml
diff --git a/preference/res/drawable-v21/preference_list_divider_material.xml b/preference/preference/res/drawable-v21/preference_list_divider_material.xml
similarity index 100%
rename from preference/res/drawable-v21/preference_list_divider_material.xml
rename to preference/preference/res/drawable-v21/preference_list_divider_material.xml
diff --git a/preference/res/drawable/ic_arrow_down_24dp.xml b/preference/preference/res/drawable/ic_arrow_down_24dp.xml
similarity index 100%
rename from preference/res/drawable/ic_arrow_down_24dp.xml
rename to preference/preference/res/drawable/ic_arrow_down_24dp.xml
diff --git a/preference/res/drawable/preference_list_divider_material.xml b/preference/preference/res/drawable/preference_list_divider_material.xml
similarity index 100%
rename from preference/res/drawable/preference_list_divider_material.xml
rename to preference/preference/res/drawable/preference_list_divider_material.xml
diff --git a/preference/res/layout/expand_button.xml b/preference/preference/res/layout/expand_button.xml
similarity index 100%
rename from preference/res/layout/expand_button.xml
rename to preference/preference/res/layout/expand_button.xml
diff --git a/preference/res/layout/image_frame.xml b/preference/preference/res/layout/image_frame.xml
similarity index 100%
rename from preference/res/layout/image_frame.xml
rename to preference/preference/res/layout/image_frame.xml
diff --git a/preference/res/layout/preference.xml b/preference/preference/res/layout/preference.xml
similarity index 100%
rename from preference/res/layout/preference.xml
rename to preference/preference/res/layout/preference.xml
diff --git a/preference/res/layout/preference_category.xml b/preference/preference/res/layout/preference_category.xml
similarity index 100%
rename from preference/res/layout/preference_category.xml
rename to preference/preference/res/layout/preference_category.xml
diff --git a/preference/res/layout/preference_category_material.xml b/preference/preference/res/layout/preference_category_material.xml
similarity index 100%
rename from preference/res/layout/preference_category_material.xml
rename to preference/preference/res/layout/preference_category_material.xml
diff --git a/preference/res/layout/preference_dialog_edittext.xml b/preference/preference/res/layout/preference_dialog_edittext.xml
similarity index 100%
rename from preference/res/layout/preference_dialog_edittext.xml
rename to preference/preference/res/layout/preference_dialog_edittext.xml
diff --git a/preference/res/layout/preference_dropdown.xml b/preference/preference/res/layout/preference_dropdown.xml
similarity index 100%
rename from preference/res/layout/preference_dropdown.xml
rename to preference/preference/res/layout/preference_dropdown.xml
diff --git a/preference/res/layout/preference_dropdown_material.xml b/preference/preference/res/layout/preference_dropdown_material.xml
similarity index 100%
rename from preference/res/layout/preference_dropdown_material.xml
rename to preference/preference/res/layout/preference_dropdown_material.xml
diff --git a/preference/res/layout/preference_information.xml b/preference/preference/res/layout/preference_information.xml
similarity index 100%
rename from preference/res/layout/preference_information.xml
rename to preference/preference/res/layout/preference_information.xml
diff --git a/preference/res/layout/preference_information_material.xml b/preference/preference/res/layout/preference_information_material.xml
similarity index 100%
rename from preference/res/layout/preference_information_material.xml
rename to preference/preference/res/layout/preference_information_material.xml
diff --git a/preference/res/layout/preference_list_fragment.xml b/preference/preference/res/layout/preference_list_fragment.xml
similarity index 100%
rename from preference/res/layout/preference_list_fragment.xml
rename to preference/preference/res/layout/preference_list_fragment.xml
diff --git a/preference/res/layout/preference_material.xml b/preference/preference/res/layout/preference_material.xml
similarity index 100%
rename from preference/res/layout/preference_material.xml
rename to preference/preference/res/layout/preference_material.xml
diff --git a/preference/res/layout/preference_recyclerview.xml b/preference/preference/res/layout/preference_recyclerview.xml
similarity index 100%
rename from preference/res/layout/preference_recyclerview.xml
rename to preference/preference/res/layout/preference_recyclerview.xml
diff --git a/preference/res/layout/preference_widget_checkbox.xml b/preference/preference/res/layout/preference_widget_checkbox.xml
similarity index 100%
rename from preference/res/layout/preference_widget_checkbox.xml
rename to preference/preference/res/layout/preference_widget_checkbox.xml
diff --git a/preference/res/layout/preference_widget_seekbar.xml b/preference/preference/res/layout/preference_widget_seekbar.xml
similarity index 100%
rename from preference/res/layout/preference_widget_seekbar.xml
rename to preference/preference/res/layout/preference_widget_seekbar.xml
diff --git a/preference/res/layout/preference_widget_seekbar_material.xml b/preference/preference/res/layout/preference_widget_seekbar_material.xml
similarity index 100%
rename from preference/res/layout/preference_widget_seekbar_material.xml
rename to preference/preference/res/layout/preference_widget_seekbar_material.xml
diff --git a/preference/res/layout/preference_widget_switch.xml b/preference/preference/res/layout/preference_widget_switch.xml
similarity index 100%
rename from preference/res/layout/preference_widget_switch.xml
rename to preference/preference/res/layout/preference_widget_switch.xml
diff --git a/preference/res/layout/preference_widget_switch_compat.xml b/preference/preference/res/layout/preference_widget_switch_compat.xml
similarity index 100%
rename from preference/res/layout/preference_widget_switch_compat.xml
rename to preference/preference/res/layout/preference_widget_switch_compat.xml
diff --git a/preference/res/values-af/strings.xml b/preference/preference/res/values-af/strings.xml
similarity index 100%
rename from preference/res/values-af/strings.xml
rename to preference/preference/res/values-af/strings.xml
diff --git a/preference/res/values-am/strings.xml b/preference/preference/res/values-am/strings.xml
similarity index 100%
rename from preference/res/values-am/strings.xml
rename to preference/preference/res/values-am/strings.xml
diff --git a/preference/res/values-ar/strings.xml b/preference/preference/res/values-ar/strings.xml
similarity index 100%
rename from preference/res/values-ar/strings.xml
rename to preference/preference/res/values-ar/strings.xml
diff --git a/preference/res/values-as/strings.xml b/preference/preference/res/values-as/strings.xml
similarity index 100%
rename from preference/res/values-as/strings.xml
rename to preference/preference/res/values-as/strings.xml
diff --git a/preference/res/values-az/strings.xml b/preference/preference/res/values-az/strings.xml
similarity index 100%
rename from preference/res/values-az/strings.xml
rename to preference/preference/res/values-az/strings.xml
diff --git a/preference/res/values-b+sr+Latn/strings.xml b/preference/preference/res/values-b+sr+Latn/strings.xml
similarity index 100%
rename from preference/res/values-b+sr+Latn/strings.xml
rename to preference/preference/res/values-b+sr+Latn/strings.xml
diff --git a/preference/res/values-be/strings.xml b/preference/preference/res/values-be/strings.xml
similarity index 100%
rename from preference/res/values-be/strings.xml
rename to preference/preference/res/values-be/strings.xml
diff --git a/preference/res/values-bg/strings.xml b/preference/preference/res/values-bg/strings.xml
similarity index 100%
rename from preference/res/values-bg/strings.xml
rename to preference/preference/res/values-bg/strings.xml
diff --git a/preference/res/values-bn/strings.xml b/preference/preference/res/values-bn/strings.xml
similarity index 100%
rename from preference/res/values-bn/strings.xml
rename to preference/preference/res/values-bn/strings.xml
diff --git a/preference/res/values-bs/strings.xml b/preference/preference/res/values-bs/strings.xml
similarity index 100%
rename from preference/res/values-bs/strings.xml
rename to preference/preference/res/values-bs/strings.xml
diff --git a/preference/res/values-ca/strings.xml b/preference/preference/res/values-ca/strings.xml
similarity index 100%
rename from preference/res/values-ca/strings.xml
rename to preference/preference/res/values-ca/strings.xml
diff --git a/preference/res/values-cs/strings.xml b/preference/preference/res/values-cs/strings.xml
similarity index 100%
rename from preference/res/values-cs/strings.xml
rename to preference/preference/res/values-cs/strings.xml
diff --git a/preference/res/values-da/strings.xml b/preference/preference/res/values-da/strings.xml
similarity index 100%
rename from preference/res/values-da/strings.xml
rename to preference/preference/res/values-da/strings.xml
diff --git a/preference/res/values-de/strings.xml b/preference/preference/res/values-de/strings.xml
similarity index 100%
rename from preference/res/values-de/strings.xml
rename to preference/preference/res/values-de/strings.xml
diff --git a/preference/res/values-el/strings.xml b/preference/preference/res/values-el/strings.xml
similarity index 100%
rename from preference/res/values-el/strings.xml
rename to preference/preference/res/values-el/strings.xml
diff --git a/preference/res/values-en-rAU/strings.xml b/preference/preference/res/values-en-rAU/strings.xml
similarity index 100%
rename from preference/res/values-en-rAU/strings.xml
rename to preference/preference/res/values-en-rAU/strings.xml
diff --git a/preference/res/values-en-rCA/strings.xml b/preference/preference/res/values-en-rCA/strings.xml
similarity index 100%
rename from preference/res/values-en-rCA/strings.xml
rename to preference/preference/res/values-en-rCA/strings.xml
diff --git a/preference/res/values-en-rGB/strings.xml b/preference/preference/res/values-en-rGB/strings.xml
similarity index 100%
rename from preference/res/values-en-rGB/strings.xml
rename to preference/preference/res/values-en-rGB/strings.xml
diff --git a/preference/res/values-en-rIN/strings.xml b/preference/preference/res/values-en-rIN/strings.xml
similarity index 100%
rename from preference/res/values-en-rIN/strings.xml
rename to preference/preference/res/values-en-rIN/strings.xml
diff --git a/preference/res/values-en-rXC/strings.xml b/preference/preference/res/values-en-rXC/strings.xml
similarity index 100%
rename from preference/res/values-en-rXC/strings.xml
rename to preference/preference/res/values-en-rXC/strings.xml
diff --git a/preference/res/values-es-rUS/strings.xml b/preference/preference/res/values-es-rUS/strings.xml
similarity index 100%
rename from preference/res/values-es-rUS/strings.xml
rename to preference/preference/res/values-es-rUS/strings.xml
diff --git a/preference/res/values-es/strings.xml b/preference/preference/res/values-es/strings.xml
similarity index 100%
rename from preference/res/values-es/strings.xml
rename to preference/preference/res/values-es/strings.xml
diff --git a/preference/res/values-et/strings.xml b/preference/preference/res/values-et/strings.xml
similarity index 100%
rename from preference/res/values-et/strings.xml
rename to preference/preference/res/values-et/strings.xml
diff --git a/preference/res/values-eu/strings.xml b/preference/preference/res/values-eu/strings.xml
similarity index 100%
rename from preference/res/values-eu/strings.xml
rename to preference/preference/res/values-eu/strings.xml
diff --git a/preference/res/values-fa/strings.xml b/preference/preference/res/values-fa/strings.xml
similarity index 100%
rename from preference/res/values-fa/strings.xml
rename to preference/preference/res/values-fa/strings.xml
diff --git a/preference/res/values-fi/strings.xml b/preference/preference/res/values-fi/strings.xml
similarity index 100%
rename from preference/res/values-fi/strings.xml
rename to preference/preference/res/values-fi/strings.xml
diff --git a/preference/res/values-fr-rCA/strings.xml b/preference/preference/res/values-fr-rCA/strings.xml
similarity index 100%
rename from preference/res/values-fr-rCA/strings.xml
rename to preference/preference/res/values-fr-rCA/strings.xml
diff --git a/preference/res/values-fr/strings.xml b/preference/preference/res/values-fr/strings.xml
similarity index 100%
rename from preference/res/values-fr/strings.xml
rename to preference/preference/res/values-fr/strings.xml
diff --git a/preference/res/values-gl/strings.xml b/preference/preference/res/values-gl/strings.xml
similarity index 100%
rename from preference/res/values-gl/strings.xml
rename to preference/preference/res/values-gl/strings.xml
diff --git a/preference/res/values-gu/strings.xml b/preference/preference/res/values-gu/strings.xml
similarity index 100%
rename from preference/res/values-gu/strings.xml
rename to preference/preference/res/values-gu/strings.xml
diff --git a/preference/res/values-hi/strings.xml b/preference/preference/res/values-hi/strings.xml
similarity index 100%
rename from preference/res/values-hi/strings.xml
rename to preference/preference/res/values-hi/strings.xml
diff --git a/preference/res/values-hr/strings.xml b/preference/preference/res/values-hr/strings.xml
similarity index 100%
rename from preference/res/values-hr/strings.xml
rename to preference/preference/res/values-hr/strings.xml
diff --git a/preference/res/values-hu/strings.xml b/preference/preference/res/values-hu/strings.xml
similarity index 100%
rename from preference/res/values-hu/strings.xml
rename to preference/preference/res/values-hu/strings.xml
diff --git a/preference/res/values-hy/strings.xml b/preference/preference/res/values-hy/strings.xml
similarity index 100%
rename from preference/res/values-hy/strings.xml
rename to preference/preference/res/values-hy/strings.xml
diff --git a/preference/res/values-in/strings.xml b/preference/preference/res/values-in/strings.xml
similarity index 100%
rename from preference/res/values-in/strings.xml
rename to preference/preference/res/values-in/strings.xml
diff --git a/preference/res/values-is/strings.xml b/preference/preference/res/values-is/strings.xml
similarity index 100%
rename from preference/res/values-is/strings.xml
rename to preference/preference/res/values-is/strings.xml
diff --git a/preference/res/values-it/strings.xml b/preference/preference/res/values-it/strings.xml
similarity index 100%
rename from preference/res/values-it/strings.xml
rename to preference/preference/res/values-it/strings.xml
diff --git a/preference/res/values-iw/strings.xml b/preference/preference/res/values-iw/strings.xml
similarity index 100%
rename from preference/res/values-iw/strings.xml
rename to preference/preference/res/values-iw/strings.xml
diff --git a/preference/res/values-ja/strings.xml b/preference/preference/res/values-ja/strings.xml
similarity index 100%
rename from preference/res/values-ja/strings.xml
rename to preference/preference/res/values-ja/strings.xml
diff --git a/preference/res/values-ka/strings.xml b/preference/preference/res/values-ka/strings.xml
similarity index 100%
rename from preference/res/values-ka/strings.xml
rename to preference/preference/res/values-ka/strings.xml
diff --git a/preference/res/values-kk/strings.xml b/preference/preference/res/values-kk/strings.xml
similarity index 100%
rename from preference/res/values-kk/strings.xml
rename to preference/preference/res/values-kk/strings.xml
diff --git a/preference/res/values-km/strings.xml b/preference/preference/res/values-km/strings.xml
similarity index 100%
rename from preference/res/values-km/strings.xml
rename to preference/preference/res/values-km/strings.xml
diff --git a/preference/res/values-kn/strings.xml b/preference/preference/res/values-kn/strings.xml
similarity index 100%
rename from preference/res/values-kn/strings.xml
rename to preference/preference/res/values-kn/strings.xml
diff --git a/preference/res/values-ko/strings.xml b/preference/preference/res/values-ko/strings.xml
similarity index 100%
rename from preference/res/values-ko/strings.xml
rename to preference/preference/res/values-ko/strings.xml
diff --git a/preference/res/values-ky/strings.xml b/preference/preference/res/values-ky/strings.xml
similarity index 100%
rename from preference/res/values-ky/strings.xml
rename to preference/preference/res/values-ky/strings.xml
diff --git a/preference/res/values-lo/strings.xml b/preference/preference/res/values-lo/strings.xml
similarity index 100%
rename from preference/res/values-lo/strings.xml
rename to preference/preference/res/values-lo/strings.xml
diff --git a/preference/res/values-lt/strings.xml b/preference/preference/res/values-lt/strings.xml
similarity index 100%
rename from preference/res/values-lt/strings.xml
rename to preference/preference/res/values-lt/strings.xml
diff --git a/preference/res/values-lv/strings.xml b/preference/preference/res/values-lv/strings.xml
similarity index 100%
rename from preference/res/values-lv/strings.xml
rename to preference/preference/res/values-lv/strings.xml
diff --git a/preference/res/values-mk/strings.xml b/preference/preference/res/values-mk/strings.xml
similarity index 100%
rename from preference/res/values-mk/strings.xml
rename to preference/preference/res/values-mk/strings.xml
diff --git a/preference/res/values-ml/strings.xml b/preference/preference/res/values-ml/strings.xml
similarity index 100%
rename from preference/res/values-ml/strings.xml
rename to preference/preference/res/values-ml/strings.xml
diff --git a/preference/res/values-mn/strings.xml b/preference/preference/res/values-mn/strings.xml
similarity index 100%
rename from preference/res/values-mn/strings.xml
rename to preference/preference/res/values-mn/strings.xml
diff --git a/preference/res/values-mr/strings.xml b/preference/preference/res/values-mr/strings.xml
similarity index 100%
rename from preference/res/values-mr/strings.xml
rename to preference/preference/res/values-mr/strings.xml
diff --git a/preference/res/values-ms/strings.xml b/preference/preference/res/values-ms/strings.xml
similarity index 100%
rename from preference/res/values-ms/strings.xml
rename to preference/preference/res/values-ms/strings.xml
diff --git a/preference/res/values-my/strings.xml b/preference/preference/res/values-my/strings.xml
similarity index 100%
rename from preference/res/values-my/strings.xml
rename to preference/preference/res/values-my/strings.xml
diff --git a/preference/res/values-nb/strings.xml b/preference/preference/res/values-nb/strings.xml
similarity index 100%
rename from preference/res/values-nb/strings.xml
rename to preference/preference/res/values-nb/strings.xml
diff --git a/preference/res/values-ne/strings.xml b/preference/preference/res/values-ne/strings.xml
similarity index 100%
rename from preference/res/values-ne/strings.xml
rename to preference/preference/res/values-ne/strings.xml
diff --git a/preference/res/values-nl/strings.xml b/preference/preference/res/values-nl/strings.xml
similarity index 100%
rename from preference/res/values-nl/strings.xml
rename to preference/preference/res/values-nl/strings.xml
diff --git a/preference/res/values-or/strings.xml b/preference/preference/res/values-or/strings.xml
similarity index 100%
rename from preference/res/values-or/strings.xml
rename to preference/preference/res/values-or/strings.xml
diff --git a/preference/res/values-pa/strings.xml b/preference/preference/res/values-pa/strings.xml
similarity index 100%
rename from preference/res/values-pa/strings.xml
rename to preference/preference/res/values-pa/strings.xml
diff --git a/preference/res/values-pl/strings.xml b/preference/preference/res/values-pl/strings.xml
similarity index 100%
rename from preference/res/values-pl/strings.xml
rename to preference/preference/res/values-pl/strings.xml
diff --git a/preference/res/values-pt-rBR/strings.xml b/preference/preference/res/values-pt-rBR/strings.xml
similarity index 100%
rename from preference/res/values-pt-rBR/strings.xml
rename to preference/preference/res/values-pt-rBR/strings.xml
diff --git a/preference/res/values-pt-rPT/strings.xml b/preference/preference/res/values-pt-rPT/strings.xml
similarity index 100%
rename from preference/res/values-pt-rPT/strings.xml
rename to preference/preference/res/values-pt-rPT/strings.xml
diff --git a/preference/res/values-pt/strings.xml b/preference/preference/res/values-pt/strings.xml
similarity index 100%
rename from preference/res/values-pt/strings.xml
rename to preference/preference/res/values-pt/strings.xml
diff --git a/preference/res/values-ro/strings.xml b/preference/preference/res/values-ro/strings.xml
similarity index 100%
rename from preference/res/values-ro/strings.xml
rename to preference/preference/res/values-ro/strings.xml
diff --git a/preference/res/values-ru/strings.xml b/preference/preference/res/values-ru/strings.xml
similarity index 100%
rename from preference/res/values-ru/strings.xml
rename to preference/preference/res/values-ru/strings.xml
diff --git a/preference/res/values-si/strings.xml b/preference/preference/res/values-si/strings.xml
similarity index 100%
rename from preference/res/values-si/strings.xml
rename to preference/preference/res/values-si/strings.xml
diff --git a/preference/res/values-sk/strings.xml b/preference/preference/res/values-sk/strings.xml
similarity index 100%
rename from preference/res/values-sk/strings.xml
rename to preference/preference/res/values-sk/strings.xml
diff --git a/preference/res/values-sl/strings.xml b/preference/preference/res/values-sl/strings.xml
similarity index 100%
rename from preference/res/values-sl/strings.xml
rename to preference/preference/res/values-sl/strings.xml
diff --git a/preference/res/values-sq/strings.xml b/preference/preference/res/values-sq/strings.xml
similarity index 100%
rename from preference/res/values-sq/strings.xml
rename to preference/preference/res/values-sq/strings.xml
diff --git a/preference/res/values-sr/strings.xml b/preference/preference/res/values-sr/strings.xml
similarity index 100%
rename from preference/res/values-sr/strings.xml
rename to preference/preference/res/values-sr/strings.xml
diff --git a/preference/res/values-sv/strings.xml b/preference/preference/res/values-sv/strings.xml
similarity index 100%
rename from preference/res/values-sv/strings.xml
rename to preference/preference/res/values-sv/strings.xml
diff --git a/preference/res/values-sw/strings.xml b/preference/preference/res/values-sw/strings.xml
similarity index 100%
rename from preference/res/values-sw/strings.xml
rename to preference/preference/res/values-sw/strings.xml
diff --git a/preference/res/values-sw360dp/config.xml b/preference/preference/res/values-sw360dp/config.xml
similarity index 100%
rename from preference/res/values-sw360dp/config.xml
rename to preference/preference/res/values-sw360dp/config.xml
diff --git a/preference/res/values-ta/strings.xml b/preference/preference/res/values-ta/strings.xml
similarity index 100%
rename from preference/res/values-ta/strings.xml
rename to preference/preference/res/values-ta/strings.xml
diff --git a/preference/res/values-te/strings.xml b/preference/preference/res/values-te/strings.xml
similarity index 100%
rename from preference/res/values-te/strings.xml
rename to preference/preference/res/values-te/strings.xml
diff --git a/preference/res/values-th/strings.xml b/preference/preference/res/values-th/strings.xml
similarity index 100%
rename from preference/res/values-th/strings.xml
rename to preference/preference/res/values-th/strings.xml
diff --git a/preference/res/values-tl/strings.xml b/preference/preference/res/values-tl/strings.xml
similarity index 100%
rename from preference/res/values-tl/strings.xml
rename to preference/preference/res/values-tl/strings.xml
diff --git a/preference/res/values-tr/strings.xml b/preference/preference/res/values-tr/strings.xml
similarity index 100%
rename from preference/res/values-tr/strings.xml
rename to preference/preference/res/values-tr/strings.xml
diff --git a/preference/res/values-uk/strings.xml b/preference/preference/res/values-uk/strings.xml
similarity index 100%
rename from preference/res/values-uk/strings.xml
rename to preference/preference/res/values-uk/strings.xml
diff --git a/preference/res/values-ur/strings.xml b/preference/preference/res/values-ur/strings.xml
similarity index 100%
rename from preference/res/values-ur/strings.xml
rename to preference/preference/res/values-ur/strings.xml
diff --git a/preference/res/values-uz/strings.xml b/preference/preference/res/values-uz/strings.xml
similarity index 100%
rename from preference/res/values-uz/strings.xml
rename to preference/preference/res/values-uz/strings.xml
diff --git a/preference/res/values-v21/dimens.xml b/preference/preference/res/values-v21/dimens.xml
similarity index 100%
rename from preference/res/values-v21/dimens.xml
rename to preference/preference/res/values-v21/dimens.xml
diff --git a/preference/res/values-v21/styles.xml b/preference/preference/res/values-v21/styles.xml
similarity index 100%
rename from preference/res/values-v21/styles.xml
rename to preference/preference/res/values-v21/styles.xml
diff --git a/preference/res/values-vi/strings.xml b/preference/preference/res/values-vi/strings.xml
similarity index 100%
rename from preference/res/values-vi/strings.xml
rename to preference/preference/res/values-vi/strings.xml
diff --git a/preference/res/values-zh-rCN/strings.xml b/preference/preference/res/values-zh-rCN/strings.xml
similarity index 100%
rename from preference/res/values-zh-rCN/strings.xml
rename to preference/preference/res/values-zh-rCN/strings.xml
diff --git a/preference/res/values-zh-rHK/strings.xml b/preference/preference/res/values-zh-rHK/strings.xml
similarity index 100%
rename from preference/res/values-zh-rHK/strings.xml
rename to preference/preference/res/values-zh-rHK/strings.xml
diff --git a/preference/res/values-zh-rTW/strings.xml b/preference/preference/res/values-zh-rTW/strings.xml
similarity index 100%
rename from preference/res/values-zh-rTW/strings.xml
rename to preference/preference/res/values-zh-rTW/strings.xml
diff --git a/preference/res/values-zu/strings.xml b/preference/preference/res/values-zu/strings.xml
similarity index 100%
rename from preference/res/values-zu/strings.xml
rename to preference/preference/res/values-zu/strings.xml
diff --git a/preference/res/values/attrs.xml b/preference/preference/res/values/attrs.xml
similarity index 100%
rename from preference/res/values/attrs.xml
rename to preference/preference/res/values/attrs.xml
diff --git a/preference/res/values/colors.xml b/preference/preference/res/values/colors.xml
similarity index 100%
rename from preference/res/values/colors.xml
rename to preference/preference/res/values/colors.xml
diff --git a/preference/res/values/config.xml b/preference/preference/res/values/config.xml
similarity index 100%
rename from preference/res/values/config.xml
rename to preference/preference/res/values/config.xml
diff --git a/preference/res/values/dimens.xml b/preference/preference/res/values/dimens.xml
similarity index 100%
rename from preference/res/values/dimens.xml
rename to preference/preference/res/values/dimens.xml
diff --git a/preference/res/values/strings.xml b/preference/preference/res/values/strings.xml
similarity index 100%
rename from preference/res/values/strings.xml
rename to preference/preference/res/values/strings.xml
diff --git a/preference/res/values/styles.xml b/preference/preference/res/values/styles.xml
similarity index 100%
rename from preference/res/values/styles.xml
rename to preference/preference/res/values/styles.xml
diff --git a/preference/res/values/themes.xml b/preference/preference/res/values/themes.xml
similarity index 100%
rename from preference/res/values/themes.xml
rename to preference/preference/res/values/themes.xml
diff --git a/preference/src/androidTest/AndroidManifest.xml b/preference/preference/src/androidTest/AndroidManifest.xml
similarity index 100%
rename from preference/src/androidTest/AndroidManifest.xml
rename to preference/preference/src/androidTest/AndroidManifest.xml
diff --git a/preference/src/androidTest/java/androidx/preference/PreferenceGroupInitialExpandedChildrenCountTest.java b/preference/preference/src/androidTest/java/androidx/preference/PreferenceGroupInitialExpandedChildrenCountTest.java
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/PreferenceGroupInitialExpandedChildrenCountTest.java
rename to preference/preference/src/androidTest/java/androidx/preference/PreferenceGroupInitialExpandedChildrenCountTest.java
diff --git a/preference/src/androidTest/java/androidx/preference/tests/EditTextPreferenceTest.java b/preference/preference/src/androidTest/java/androidx/preference/tests/EditTextPreferenceTest.java
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/EditTextPreferenceTest.java
rename to preference/preference/src/androidTest/java/androidx/preference/tests/EditTextPreferenceTest.java
diff --git a/preference/src/androidTest/java/androidx/preference/tests/ExpandablePreferenceTest.java b/preference/preference/src/androidTest/java/androidx/preference/tests/ExpandablePreferenceTest.java
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/ExpandablePreferenceTest.java
rename to preference/preference/src/androidTest/java/androidx/preference/tests/ExpandablePreferenceTest.java
diff --git a/preference/src/androidTest/java/androidx/preference/tests/ListPreferenceSummaryTest.java b/preference/preference/src/androidTest/java/androidx/preference/tests/ListPreferenceSummaryTest.java
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/ListPreferenceSummaryTest.java
rename to preference/preference/src/androidTest/java/androidx/preference/tests/ListPreferenceSummaryTest.java
diff --git a/preference/src/androidTest/java/androidx/preference/tests/PreferenceComparisonCallbackTest.java b/preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceComparisonCallbackTest.java
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/PreferenceComparisonCallbackTest.java
rename to preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceComparisonCallbackTest.java
diff --git a/preference/src/androidTest/java/androidx/preference/tests/PreferenceCopyingTest.java b/preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceCopyingTest.java
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/PreferenceCopyingTest.java
rename to preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceCopyingTest.java
diff --git a/preference/src/androidTest/java/androidx/preference/tests/PreferenceDataStoreTest.java b/preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceDataStoreTest.java
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/PreferenceDataStoreTest.java
rename to preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceDataStoreTest.java
diff --git a/preference/src/androidTest/java/androidx/preference/tests/PreferenceGroupFindPreferenceTest.java b/preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceGroupFindPreferenceTest.java
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/PreferenceGroupFindPreferenceTest.java
rename to preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceGroupFindPreferenceTest.java
diff --git a/preference/src/androidTest/java/androidx/preference/tests/PreferenceIconSpaceTest.java b/preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceIconSpaceTest.java
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/PreferenceIconSpaceTest.java
rename to preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceIconSpaceTest.java
diff --git a/preference/src/androidTest/java/androidx/preference/tests/PreferenceParentGroupTest.java b/preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceParentGroupTest.java
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/PreferenceParentGroupTest.java
rename to preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceParentGroupTest.java
diff --git a/preference/src/androidTest/java/androidx/preference/tests/PreferencePersistTest.java b/preference/preference/src/androidTest/java/androidx/preference/tests/PreferencePersistTest.java
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/PreferencePersistTest.java
rename to preference/preference/src/androidTest/java/androidx/preference/tests/PreferencePersistTest.java
diff --git a/preference/src/androidTest/java/androidx/preference/tests/PreferenceSingleLineTitleTest.java b/preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceSingleLineTitleTest.java
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/PreferenceSingleLineTitleTest.java
rename to preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceSingleLineTitleTest.java
diff --git a/preference/src/androidTest/java/androidx/preference/tests/PreferenceVisibilityTest.java b/preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceVisibilityTest.java
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/PreferenceVisibilityTest.java
rename to preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceVisibilityTest.java
diff --git a/preference/src/androidTest/java/androidx/preference/tests/SeekBarPreferenceTest.kt b/preference/preference/src/androidTest/java/androidx/preference/tests/SeekBarPreferenceTest.kt
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/SeekBarPreferenceTest.kt
rename to preference/preference/src/androidTest/java/androidx/preference/tests/SeekBarPreferenceTest.kt
diff --git a/preference/src/androidTest/java/androidx/preference/tests/SelectableTest.kt b/preference/preference/src/androidTest/java/androidx/preference/tests/SelectableTest.kt
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/SelectableTest.kt
rename to preference/preference/src/androidTest/java/androidx/preference/tests/SelectableTest.kt
diff --git a/preference/src/androidTest/java/androidx/preference/tests/SummaryProviderTest.java b/preference/preference/src/androidTest/java/androidx/preference/tests/SummaryProviderTest.java
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/SummaryProviderTest.java
rename to preference/preference/src/androidTest/java/androidx/preference/tests/SummaryProviderTest.java
diff --git a/preference/src/androidTest/java/androidx/preference/tests/helpers/PreferenceTestHelperActivity.java b/preference/preference/src/androidTest/java/androidx/preference/tests/helpers/PreferenceTestHelperActivity.java
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/helpers/PreferenceTestHelperActivity.java
rename to preference/preference/src/androidTest/java/androidx/preference/tests/helpers/PreferenceTestHelperActivity.java
diff --git a/preference/src/androidTest/java/androidx/preference/tests/helpers/PreferenceWrapper.java b/preference/preference/src/androidTest/java/androidx/preference/tests/helpers/PreferenceWrapper.java
similarity index 100%
rename from preference/src/androidTest/java/androidx/preference/tests/helpers/PreferenceWrapper.java
rename to preference/preference/src/androidTest/java/androidx/preference/tests/helpers/PreferenceWrapper.java
diff --git a/preference/src/androidTest/res/values/styles.xml b/preference/preference/src/androidTest/res/values/styles.xml
similarity index 100%
rename from preference/src/androidTest/res/values/styles.xml
rename to preference/preference/src/androidTest/res/values/styles.xml
diff --git a/preference/src/androidTest/res/xml/test_copying.xml b/preference/preference/src/androidTest/res/xml/test_copying.xml
similarity index 100%
rename from preference/src/androidTest/res/xml/test_copying.xml
rename to preference/preference/src/androidTest/res/xml/test_copying.xml
diff --git a/preference/src/androidTest/res/xml/test_edit_text_preference.xml b/preference/preference/src/androidTest/res/xml/test_edit_text_preference.xml
similarity index 100%
rename from preference/src/androidTest/res/xml/test_edit_text_preference.xml
rename to preference/preference/src/androidTest/res/xml/test_edit_text_preference.xml
diff --git a/preference/src/androidTest/res/xml/test_seekbar.xml b/preference/preference/src/androidTest/res/xml/test_seekbar.xml
similarity index 100%
rename from preference/src/androidTest/res/xml/test_seekbar.xml
rename to preference/preference/src/androidTest/res/xml/test_seekbar.xml
diff --git a/preference/src/androidTest/res/xml/test_selectable.xml b/preference/preference/src/androidTest/res/xml/test_selectable.xml
similarity index 100%
rename from preference/src/androidTest/res/xml/test_selectable.xml
rename to preference/preference/src/androidTest/res/xml/test_selectable.xml
diff --git a/preference/src/androidTest/res/xml/test_visibility.xml b/preference/preference/src/androidTest/res/xml/test_visibility.xml
similarity index 100%
rename from preference/src/androidTest/res/xml/test_visibility.xml
rename to preference/preference/src/androidTest/res/xml/test_visibility.xml
diff --git a/preference/src/main/AndroidManifest.xml b/preference/preference/src/main/AndroidManifest.xml
similarity index 100%
rename from preference/src/main/AndroidManifest.xml
rename to preference/preference/src/main/AndroidManifest.xml
diff --git a/preference/src/main/java/androidx/preference/AndroidResources.java b/preference/preference/src/main/java/androidx/preference/AndroidResources.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/AndroidResources.java
rename to preference/preference/src/main/java/androidx/preference/AndroidResources.java
diff --git a/preference/src/main/java/androidx/preference/CheckBoxPreference.java b/preference/preference/src/main/java/androidx/preference/CheckBoxPreference.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/CheckBoxPreference.java
rename to preference/preference/src/main/java/androidx/preference/CheckBoxPreference.java
diff --git a/preference/src/main/java/androidx/preference/DialogPreference.java b/preference/preference/src/main/java/androidx/preference/DialogPreference.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/DialogPreference.java
rename to preference/preference/src/main/java/androidx/preference/DialogPreference.java
diff --git a/preference/src/main/java/androidx/preference/DropDownPreference.java b/preference/preference/src/main/java/androidx/preference/DropDownPreference.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/DropDownPreference.java
rename to preference/preference/src/main/java/androidx/preference/DropDownPreference.java
diff --git a/preference/src/main/java/androidx/preference/EditTextPreference.java b/preference/preference/src/main/java/androidx/preference/EditTextPreference.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/EditTextPreference.java
rename to preference/preference/src/main/java/androidx/preference/EditTextPreference.java
diff --git a/preference/src/main/java/androidx/preference/EditTextPreferenceDialogFragment.java b/preference/preference/src/main/java/androidx/preference/EditTextPreferenceDialogFragment.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/EditTextPreferenceDialogFragment.java
rename to preference/preference/src/main/java/androidx/preference/EditTextPreferenceDialogFragment.java
diff --git a/preference/src/main/java/androidx/preference/EditTextPreferenceDialogFragmentCompat.java b/preference/preference/src/main/java/androidx/preference/EditTextPreferenceDialogFragmentCompat.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/EditTextPreferenceDialogFragmentCompat.java
rename to preference/preference/src/main/java/androidx/preference/EditTextPreferenceDialogFragmentCompat.java
diff --git a/preference/src/main/java/androidx/preference/ExpandButton.java b/preference/preference/src/main/java/androidx/preference/ExpandButton.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/ExpandButton.java
rename to preference/preference/src/main/java/androidx/preference/ExpandButton.java
diff --git a/preference/src/main/java/androidx/preference/ListPreference.java b/preference/preference/src/main/java/androidx/preference/ListPreference.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/ListPreference.java
rename to preference/preference/src/main/java/androidx/preference/ListPreference.java
diff --git a/preference/src/main/java/androidx/preference/ListPreferenceDialogFragment.java b/preference/preference/src/main/java/androidx/preference/ListPreferenceDialogFragment.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/ListPreferenceDialogFragment.java
rename to preference/preference/src/main/java/androidx/preference/ListPreferenceDialogFragment.java
diff --git a/preference/src/main/java/androidx/preference/ListPreferenceDialogFragmentCompat.java b/preference/preference/src/main/java/androidx/preference/ListPreferenceDialogFragmentCompat.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/ListPreferenceDialogFragmentCompat.java
rename to preference/preference/src/main/java/androidx/preference/ListPreferenceDialogFragmentCompat.java
diff --git a/preference/src/main/java/androidx/preference/MultiSelectListPreference.java b/preference/preference/src/main/java/androidx/preference/MultiSelectListPreference.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/MultiSelectListPreference.java
rename to preference/preference/src/main/java/androidx/preference/MultiSelectListPreference.java
diff --git a/preference/src/main/java/androidx/preference/MultiSelectListPreferenceDialogFragment.java b/preference/preference/src/main/java/androidx/preference/MultiSelectListPreferenceDialogFragment.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/MultiSelectListPreferenceDialogFragment.java
rename to preference/preference/src/main/java/androidx/preference/MultiSelectListPreferenceDialogFragment.java
diff --git a/preference/src/main/java/androidx/preference/MultiSelectListPreferenceDialogFragmentCompat.java b/preference/preference/src/main/java/androidx/preference/MultiSelectListPreferenceDialogFragmentCompat.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/MultiSelectListPreferenceDialogFragmentCompat.java
rename to preference/preference/src/main/java/androidx/preference/MultiSelectListPreferenceDialogFragmentCompat.java
diff --git a/preference/src/main/java/androidx/preference/Preference.java b/preference/preference/src/main/java/androidx/preference/Preference.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/Preference.java
rename to preference/preference/src/main/java/androidx/preference/Preference.java
diff --git a/preference/src/main/java/androidx/preference/PreferenceCategory.java b/preference/preference/src/main/java/androidx/preference/PreferenceCategory.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/PreferenceCategory.java
rename to preference/preference/src/main/java/androidx/preference/PreferenceCategory.java
diff --git a/preference/src/main/java/androidx/preference/PreferenceDataStore.java b/preference/preference/src/main/java/androidx/preference/PreferenceDataStore.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/PreferenceDataStore.java
rename to preference/preference/src/main/java/androidx/preference/PreferenceDataStore.java
diff --git a/preference/src/main/java/androidx/preference/PreferenceDialogFragment.java b/preference/preference/src/main/java/androidx/preference/PreferenceDialogFragment.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/PreferenceDialogFragment.java
rename to preference/preference/src/main/java/androidx/preference/PreferenceDialogFragment.java
diff --git a/preference/src/main/java/androidx/preference/PreferenceDialogFragmentCompat.java b/preference/preference/src/main/java/androidx/preference/PreferenceDialogFragmentCompat.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/PreferenceDialogFragmentCompat.java
rename to preference/preference/src/main/java/androidx/preference/PreferenceDialogFragmentCompat.java
diff --git a/preference/src/main/java/androidx/preference/PreferenceFragment.java b/preference/preference/src/main/java/androidx/preference/PreferenceFragment.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/PreferenceFragment.java
rename to preference/preference/src/main/java/androidx/preference/PreferenceFragment.java
diff --git a/preference/src/main/java/androidx/preference/PreferenceFragmentCompat.java b/preference/preference/src/main/java/androidx/preference/PreferenceFragmentCompat.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/PreferenceFragmentCompat.java
rename to preference/preference/src/main/java/androidx/preference/PreferenceFragmentCompat.java
diff --git a/preference/src/main/java/androidx/preference/PreferenceGroup.java b/preference/preference/src/main/java/androidx/preference/PreferenceGroup.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/PreferenceGroup.java
rename to preference/preference/src/main/java/androidx/preference/PreferenceGroup.java
diff --git a/preference/src/main/java/androidx/preference/PreferenceGroupAdapter.java b/preference/preference/src/main/java/androidx/preference/PreferenceGroupAdapter.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/PreferenceGroupAdapter.java
rename to preference/preference/src/main/java/androidx/preference/PreferenceGroupAdapter.java
diff --git a/preference/src/main/java/androidx/preference/PreferenceInflater.java b/preference/preference/src/main/java/androidx/preference/PreferenceInflater.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/PreferenceInflater.java
rename to preference/preference/src/main/java/androidx/preference/PreferenceInflater.java
diff --git a/preference/src/main/java/androidx/preference/PreferenceManager.java b/preference/preference/src/main/java/androidx/preference/PreferenceManager.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/PreferenceManager.java
rename to preference/preference/src/main/java/androidx/preference/PreferenceManager.java
diff --git a/preference/src/main/java/androidx/preference/PreferenceRecyclerViewAccessibilityDelegate.java b/preference/preference/src/main/java/androidx/preference/PreferenceRecyclerViewAccessibilityDelegate.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/PreferenceRecyclerViewAccessibilityDelegate.java
rename to preference/preference/src/main/java/androidx/preference/PreferenceRecyclerViewAccessibilityDelegate.java
diff --git a/preference/src/main/java/androidx/preference/PreferenceScreen.java b/preference/preference/src/main/java/androidx/preference/PreferenceScreen.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/PreferenceScreen.java
rename to preference/preference/src/main/java/androidx/preference/PreferenceScreen.java
diff --git a/preference/src/main/java/androidx/preference/PreferenceViewHolder.java b/preference/preference/src/main/java/androidx/preference/PreferenceViewHolder.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/PreferenceViewHolder.java
rename to preference/preference/src/main/java/androidx/preference/PreferenceViewHolder.java
diff --git a/preference/src/main/java/androidx/preference/SeekBarPreference.java b/preference/preference/src/main/java/androidx/preference/SeekBarPreference.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/SeekBarPreference.java
rename to preference/preference/src/main/java/androidx/preference/SeekBarPreference.java
diff --git a/preference/src/main/java/androidx/preference/SwitchPreference.java b/preference/preference/src/main/java/androidx/preference/SwitchPreference.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/SwitchPreference.java
rename to preference/preference/src/main/java/androidx/preference/SwitchPreference.java
diff --git a/preference/src/main/java/androidx/preference/SwitchPreferenceCompat.java b/preference/preference/src/main/java/androidx/preference/SwitchPreferenceCompat.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/SwitchPreferenceCompat.java
rename to preference/preference/src/main/java/androidx/preference/SwitchPreferenceCompat.java
diff --git a/preference/src/main/java/androidx/preference/TwoStatePreference.java b/preference/preference/src/main/java/androidx/preference/TwoStatePreference.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/TwoStatePreference.java
rename to preference/preference/src/main/java/androidx/preference/TwoStatePreference.java
diff --git a/preference/src/main/java/androidx/preference/UnPressableLinearLayout.java b/preference/preference/src/main/java/androidx/preference/UnPressableLinearLayout.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/UnPressableLinearLayout.java
rename to preference/preference/src/main/java/androidx/preference/UnPressableLinearLayout.java
diff --git a/preference/src/main/java/androidx/preference/internal/PreferenceImageView.java b/preference/preference/src/main/java/androidx/preference/internal/PreferenceImageView.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/internal/PreferenceImageView.java
rename to preference/preference/src/main/java/androidx/preference/internal/PreferenceImageView.java
diff --git a/preference/src/main/java/androidx/preference/internal/package-info.java b/preference/preference/src/main/java/androidx/preference/internal/package-info.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/internal/package-info.java
rename to preference/preference/src/main/java/androidx/preference/internal/package-info.java
diff --git a/preference/src/main/java/androidx/preference/package-info.java b/preference/preference/src/main/java/androidx/preference/package-info.java
similarity index 100%
rename from preference/src/main/java/androidx/preference/package-info.java
rename to preference/preference/src/main/java/androidx/preference/package-info.java
diff --git a/recommendation/api/api_lint.ignore b/recommendation/api/api_lint.ignore
new file mode 100644
index 0000000..8ceaa272
--- /dev/null
+++ b/recommendation/api/api_lint.ignore
@@ -0,0 +1,141 @@
+// Baseline format: 1.0
+MissingNullability: androidx.recommendation.app.ContentRecommendation#equals(Object) parameter #0:
+    Missing nullability on parameter `other` in method `equals`
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getBackgroundImageUri():
+    Missing nullability on method `getBackgroundImageUri` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getContentImage():
+    Missing nullability on method `getContentImage` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getContentIntent():
+    Missing nullability on method `getContentIntent` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getContentTypes():
+    Missing nullability on method `getContentTypes` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getDismissIntent():
+    Missing nullability on method `getDismissIntent` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getGenres():
+    Missing nullability on method `getGenres` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getGroup():
+    Missing nullability on method `getGroup` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getIdTag():
+    Missing nullability on method `getIdTag` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getMaturityRating():
+    Missing nullability on method `getMaturityRating` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getNotificationObject(android.content.Context):
+    Missing nullability on method `getNotificationObject` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getNotificationObject(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `getNotificationObject`
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getPricingType():
+    Missing nullability on method `getPricingType` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getPricingValue():
+    Missing nullability on method `getPricingValue` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getPrimaryContentType():
+    Missing nullability on method `getPrimaryContentType` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getSortKey():
+    Missing nullability on method `getSortKey` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getSourceName():
+    Missing nullability on method `getSourceName` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getText():
+    Missing nullability on method `getText` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#getTitle():
+    Missing nullability on method `getTitle` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation#setGroup(String) parameter #0:
+    Missing nullability on parameter `groupTag` in method `setGroup`
+MissingNullability: androidx.recommendation.app.ContentRecommendation#setSortKey(String) parameter #0:
+    Missing nullability on parameter `sortKey` in method `setSortKey`
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setAutoDismiss(boolean):
+    Missing nullability on method `setAutoDismiss` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setBackgroundImageUri(String):
+    Missing nullability on method `setBackgroundImageUri` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setBadgeIcon(int):
+    Missing nullability on method `setBadgeIcon` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setColor(int):
+    Missing nullability on method `setColor` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setContentImage(android.graphics.Bitmap):
+    Missing nullability on method `setContentImage` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setContentImage(android.graphics.Bitmap) parameter #0:
+    Missing nullability on parameter `image` in method `setContentImage`
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setContentIntentData(int, android.content.Intent, int, android.os.Bundle):
+    Missing nullability on method `setContentIntentData` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setContentIntentData(int, android.content.Intent, int, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `intent` in method `setContentIntentData`
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setContentTypes(String[]):
+    Missing nullability on method `setContentTypes` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setContentTypes(String[]) parameter #0:
+    Missing nullability on parameter `types` in method `setContentTypes`
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setDismissIntentData(int, android.content.Intent, int, android.os.Bundle):
+    Missing nullability on method `setDismissIntentData` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setGenres(String[]):
+    Missing nullability on method `setGenres` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setGenres(String[]) parameter #0:
+    Missing nullability on parameter `genres` in method `setGenres`
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setGroup(String):
+    Missing nullability on method `setGroup` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setIdTag(String):
+    Missing nullability on method `setIdTag` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setIdTag(String) parameter #0:
+    Missing nullability on parameter `idTag` in method `setIdTag`
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setMaturityRating(String):
+    Missing nullability on method `setMaturityRating` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setMaturityRating(String) parameter #0:
+    Missing nullability on parameter `maturityRating` in method `setMaturityRating`
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setPricingInformation(String, String):
+    Missing nullability on method `setPricingInformation` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setPricingInformation(String, String) parameter #0:
+    Missing nullability on parameter `priceType` in method `setPricingInformation`
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setProgress(int, int):
+    Missing nullability on method `setProgress` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setRunningTime(long):
+    Missing nullability on method `setRunningTime` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setSortKey(String):
+    Missing nullability on method `setSortKey` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setSourceName(String):
+    Missing nullability on method `setSourceName` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setStatus(int):
+    Missing nullability on method `setStatus` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setText(String):
+    Missing nullability on method `setText` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setTitle(String):
+    Missing nullability on method `setTitle` return
+MissingNullability: androidx.recommendation.app.ContentRecommendation.Builder#setTitle(String) parameter #0:
+    Missing nullability on parameter `title` in method `setTitle`
+MissingNullability: androidx.recommendation.app.RecommendationExtender#RecommendationExtender(android.app.Notification) parameter #0:
+    Missing nullability on parameter `notif` in method `RecommendationExtender`
+MissingNullability: androidx.recommendation.app.RecommendationExtender#extend(android.app.Notification.Builder):
+    Missing nullability on method `extend` return
+MissingNullability: androidx.recommendation.app.RecommendationExtender#extend(android.app.Notification.Builder) parameter #0:
+    Missing nullability on parameter `builder` in method `extend`
+MissingNullability: androidx.recommendation.app.RecommendationExtender#getContentTypes():
+    Missing nullability on method `getContentTypes` return
+MissingNullability: androidx.recommendation.app.RecommendationExtender#getGenres():
+    Missing nullability on method `getGenres` return
+MissingNullability: androidx.recommendation.app.RecommendationExtender#getMaturityRating():
+    Missing nullability on method `getMaturityRating` return
+MissingNullability: androidx.recommendation.app.RecommendationExtender#getPricingType():
+    Missing nullability on method `getPricingType` return
+MissingNullability: androidx.recommendation.app.RecommendationExtender#getPricingValue():
+    Missing nullability on method `getPricingValue` return
+MissingNullability: androidx.recommendation.app.RecommendationExtender#getPrimaryContentType():
+    Missing nullability on method `getPrimaryContentType` return
+MissingNullability: androidx.recommendation.app.RecommendationExtender#setContentTypes(String[]):
+    Missing nullability on method `setContentTypes` return
+MissingNullability: androidx.recommendation.app.RecommendationExtender#setContentTypes(String[]) parameter #0:
+    Missing nullability on parameter `types` in method `setContentTypes`
+MissingNullability: androidx.recommendation.app.RecommendationExtender#setGenres(String[]):
+    Missing nullability on method `setGenres` return
+MissingNullability: androidx.recommendation.app.RecommendationExtender#setGenres(String[]) parameter #0:
+    Missing nullability on parameter `genres` in method `setGenres`
+MissingNullability: androidx.recommendation.app.RecommendationExtender#setMaturityRating(String):
+    Missing nullability on method `setMaturityRating` return
+MissingNullability: androidx.recommendation.app.RecommendationExtender#setMaturityRating(String) parameter #0:
+    Missing nullability on parameter `maturityRating` in method `setMaturityRating`
+MissingNullability: androidx.recommendation.app.RecommendationExtender#setPricingInformation(String, String):
+    Missing nullability on method `setPricingInformation` return
+MissingNullability: androidx.recommendation.app.RecommendationExtender#setPricingInformation(String, String) parameter #0:
+    Missing nullability on parameter `priceType` in method `setPricingInformation`
+MissingNullability: androidx.recommendation.app.RecommendationExtender#setPricingInformation(String, String) parameter #1:
+    Missing nullability on parameter `priceValue` in method `setPricingInformation`
+MissingNullability: androidx.recommendation.app.RecommendationExtender#setRunningTime(long):
+    Missing nullability on method `setRunningTime` return
+MissingNullability: androidx.recommendation.app.RecommendationExtender#setStatus(int):
+    Missing nullability on method `setStatus` return
diff --git a/recyclerview/recyclerview-selection/api/api_lint.ignore b/recyclerview/recyclerview-selection/api/api_lint.ignore
index 1940c27..3d1c94e 100644
--- a/recyclerview/recyclerview-selection/api/api_lint.ignore
+++ b/recyclerview/recyclerview-selection/api/api_lint.ignore
@@ -13,5 +13,57 @@
     Method can be invoked as a "in" operator from Kotlin: `contains` (this is usually desirable; just make sure it makes sense for this type of object)
 
 
+MissingNullability: androidx.recyclerview.selection.BandPredicate#canInitiate(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `e` in method `canInitiate`
+MissingNullability: androidx.recyclerview.selection.Selection#equals(Object) parameter #0:
+    Missing nullability on parameter `other` in method `equals`
+MissingNullability: androidx.recyclerview.selection.Selection#iterator():
+    Missing nullability on method `iterator` return
+MissingNullability: androidx.recyclerview.selection.Selection#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.recyclerview.selection.SelectionPredicates#createSelectAnything():
+    Missing nullability on method `createSelectAnything` return
+MissingNullability: androidx.recyclerview.selection.SelectionPredicates#createSelectSingleAnything():
+    Missing nullability on method `createSelectSingleAnything` return
+MissingNullability: androidx.recyclerview.selection.SelectionTracker#addObserver(androidx.recyclerview.selection.SelectionTracker.SelectionObserver) parameter #0:
+    Missing nullability on parameter `observer` in method `addObserver`
+MissingNullability: androidx.recyclerview.selection.SelectionTracker#getSelection():
+    Missing nullability on method `getSelection` return
+MissingNullability: androidx.recyclerview.selection.SelectionTracker.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.recyclerview.selection.SelectionTracker.Builder#withBandOverlay(int):
+    Missing nullability on method `withBandOverlay` return
+MissingNullability: androidx.recyclerview.selection.SelectionTracker.Builder#withBandPredicate(androidx.recyclerview.selection.BandPredicate):
+    Missing nullability on method `withBandPredicate` return
+MissingNullability: androidx.recyclerview.selection.SelectionTracker.Builder#withFocusDelegate(androidx.recyclerview.selection.FocusDelegate<K>):
+    Missing nullability on method `withFocusDelegate` return
+MissingNullability: androidx.recyclerview.selection.SelectionTracker.Builder#withGestureTooltypes(int...):
+    Missing nullability on method `withGestureTooltypes` return
+MissingNullability: androidx.recyclerview.selection.SelectionTracker.Builder#withGestureTooltypes(int...) parameter #0:
+    Missing nullability on parameter `toolTypes` in method `withGestureTooltypes`
+MissingNullability: androidx.recyclerview.selection.SelectionTracker.Builder#withOnContextClickListener(androidx.recyclerview.selection.OnContextClickListener):
+    Missing nullability on method `withOnContextClickListener` return
+MissingNullability: androidx.recyclerview.selection.SelectionTracker.Builder#withOnDragInitiatedListener(androidx.recyclerview.selection.OnDragInitiatedListener):
+    Missing nullability on method `withOnDragInitiatedListener` return
+MissingNullability: androidx.recyclerview.selection.SelectionTracker.Builder#withOnItemActivatedListener(androidx.recyclerview.selection.OnItemActivatedListener<K>):
+    Missing nullability on method `withOnItemActivatedListener` return
+MissingNullability: androidx.recyclerview.selection.SelectionTracker.Builder#withOperationMonitor(androidx.recyclerview.selection.OperationMonitor):
+    Missing nullability on method `withOperationMonitor` return
+MissingNullability: androidx.recyclerview.selection.SelectionTracker.Builder#withPointerTooltypes(int...):
+    Missing nullability on method `withPointerTooltypes` return
+MissingNullability: androidx.recyclerview.selection.SelectionTracker.Builder#withPointerTooltypes(int...) parameter #0:
+    Missing nullability on parameter `toolTypes` in method `withPointerTooltypes`
+MissingNullability: androidx.recyclerview.selection.SelectionTracker.Builder#withSelectionPredicate(androidx.recyclerview.selection.SelectionTracker.SelectionPredicate<K>):
+    Missing nullability on method `withSelectionPredicate` return
+MissingNullability: androidx.recyclerview.selection.StorageStrategy#createLongStorage():
+    Missing nullability on method `createLongStorage` return
+MissingNullability: androidx.recyclerview.selection.StorageStrategy#createParcelableStorage(Class<K>):
+    Missing nullability on method `createParcelableStorage` return
+MissingNullability: androidx.recyclerview.selection.StorageStrategy#createParcelableStorage(Class<K>) parameter #0:
+    Missing nullability on parameter `type` in method `createParcelableStorage`
+MissingNullability: androidx.recyclerview.selection.StorageStrategy#createStringStorage():
+    Missing nullability on method `createStringStorage` return
+
+
 VisiblySynchronized: androidx.recyclerview.selection.OperationMonitor#isStarted():
     Internal locks must not be exposed: method androidx.recyclerview.selection.OperationMonitor.isStarted()
diff --git a/recyclerview/recyclerview-selection/src/androidTest/java/androidx/recyclerview/selection/ToolHandlerRegistryTest.java b/recyclerview/recyclerview-selection/src/androidTest/java/androidx/recyclerview/selection/ToolHandlerRegistryTest.java
new file mode 100644
index 0000000..96bb216
--- /dev/null
+++ b/recyclerview/recyclerview-selection/src/androidTest/java/androidx/recyclerview/selection/ToolHandlerRegistryTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2019 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.recyclerview.selection;
+
+import static org.junit.Assert.assertEquals;
+
+import android.view.MotionEvent;
+
+import androidx.recyclerview.selection.testing.TestEvents;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ToolHandlerRegistryTest {
+
+    private static final class Events {
+        private static final MotionEvent ERASER = TestEvents.builder()
+                .type(MotionEvent.TOOL_TYPE_ERASER)
+                .build();
+        private static final MotionEvent FINGER = TestEvents.builder()
+                .type(MotionEvent.TOOL_TYPE_FINGER)
+                .build();
+        private static final MotionEvent MOUSE = TestEvents.builder()
+                .type(MotionEvent.TOOL_TYPE_MOUSE)
+                .build();
+        private static final MotionEvent STYLUS = TestEvents.builder()
+                .type(MotionEvent.TOOL_TYPE_STYLUS)
+                .build();
+        private static final MotionEvent UNKNOWN = TestEvents.builder()
+                .type(MotionEvent.TOOL_TYPE_UNKNOWN)
+                .build();
+    }
+
+    private static final class Handlers {
+        private static final String DEFAULT = "default";
+        private static final String ERASER = "eraser";
+        private static final String FINGER = "finger";
+        private static final String MOUSE = "mouse";
+        private static final String STYLUS = "stylus";
+        private static final String UNKNOWN = "unknown";
+    }
+
+    private ToolHandlerRegistry mRegistry;
+
+    @Before
+    public void setUp() {
+        mRegistry = new ToolHandlerRegistry(Handlers.DEFAULT);
+    }
+
+    @Test
+    public void testFallsBackToDefaultHandler() {
+        assertEquals(Handlers.DEFAULT, mRegistry.get(Events.ERASER));
+        assertEquals(Handlers.DEFAULT, mRegistry.get(Events.FINGER));
+        assertEquals(Handlers.DEFAULT, mRegistry.get(Events.MOUSE));
+        assertEquals(Handlers.DEFAULT, mRegistry.get(Events.STYLUS));
+        assertEquals(Handlers.DEFAULT, mRegistry.get(Events.UNKNOWN));
+    }
+
+    @Test
+    public void testGets() {
+        assertGets(Events.ERASER, Handlers.ERASER);
+        assertGets(Events.FINGER, Handlers.FINGER);
+        assertGets(Events.MOUSE, Handlers.MOUSE);
+        assertGets(Events.STYLUS, Handlers.STYLUS);
+        assertGets(Events.UNKNOWN, Handlers.UNKNOWN);
+    }
+
+    private void assertGets(MotionEvent event, String handler) {
+        mRegistry.set(event.getToolType(0), handler);
+        assertEquals(handler, mRegistry.get(event));
+    }
+}
diff --git a/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/DummyOnItemTouchListener.java b/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/DummyOnItemTouchListener.java
new file mode 100644
index 0000000..5880d97
--- /dev/null
+++ b/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/DummyOnItemTouchListener.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019 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.recyclerview.selection;
+
+import android.view.MotionEvent;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+/**
+ * No-op implementation of OnItemTouchListener suitable for use as a default
+ * handler w/ ToolHandlerRegistery, or in tests.
+ */
+final class DummyOnItemTouchListener implements RecyclerView.OnItemTouchListener {
+    @Override
+    public boolean onInterceptTouchEvent(
+            @NonNull RecyclerView unused, @NonNull MotionEvent e) {
+        return false;
+    }
+
+    @Override
+    public void onTouchEvent(
+            @NonNull RecyclerView unused, @NonNull MotionEvent e) {
+    }
+
+    @Override
+    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+    }
+}
diff --git a/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/EventRouter.java b/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/EventRouter.java
new file mode 100644
index 0000000..2ef4f8a
--- /dev/null
+++ b/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/EventRouter.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2017 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.recyclerview.selection;
+
+import static androidx.core.util.Preconditions.checkArgument;
+
+import android.view.MotionEvent;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener;
+
+/**
+ * A class responsible for routing MotionEvents to tool-type specific handlers.
+ * Individual tool-type specific handlers are added after the class is constructed.
+ *
+ * <p>
+ * EventRouter takes its name from
+ * {@link RecyclerView#addOnItemTouchListener(OnItemTouchListener)}. Despite "Touch"
+ * being in the name, it receives MotionEvents for all types of tools.
+ */
+final class EventRouter implements OnItemTouchListener {
+
+    private static final String TAG = "EventRouter";
+
+    private final ToolHandlerRegistry<OnItemTouchListener> mDelegates;
+
+    EventRouter() {
+        mDelegates = new ToolHandlerRegistry<OnItemTouchListener>(new DummyOnItemTouchListener());
+    }
+
+    /**
+     * @param toolType See MotionEvent for details on available types.
+     * @param delegate An {@link OnItemTouchListener} to receive events
+     *     of {@code toolType}.
+     */
+    void set(int toolType, @NonNull OnItemTouchListener delegate) {
+        checkArgument(delegate != null);
+
+        mDelegates.set(toolType, delegate);
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
+        return mDelegates.get(e).onInterceptTouchEvent(rv, e);
+    }
+
+    @Override
+    public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
+        mDelegates.get(e).onTouchEvent(rv, e);
+    }
+
+    @Override
+    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+        // TODO(b/139141511): Handle onRequestDisallowInterceptTouchEvent.
+    }
+}
diff --git a/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/GestureDetectorOnItemTouchListenerAdapter.java b/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/GestureDetectorOnItemTouchListenerAdapter.java
new file mode 100644
index 0000000..4f06bee
--- /dev/null
+++ b/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/GestureDetectorOnItemTouchListenerAdapter.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2019 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.recyclerview.selection;
+
+import static androidx.core.util.Preconditions.checkArgument;
+
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+/**
+ * Class allowing GestureDetector to listen directly to RecyclerView touch events.
+ */
+final class GestureDetectorOnItemTouchListenerAdapter implements RecyclerView.OnItemTouchListener {
+
+    private final GestureDetector mDetector;
+    GestureDetectorOnItemTouchListenerAdapter(@NonNull GestureDetector detector) {
+        checkArgument(detector != null);
+
+        mDetector = detector;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
+        // Regardless of whether or not gesture detector detects something, don't
+        // consume the event stream. The concept of intercepting is alien to GestureDetector.
+        mDetector.onTouchEvent(e);
+        return false;
+    }
+
+    @Override
+    public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {}
+
+    @Override
+    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
+}
diff --git a/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/ItemDetailsLookup.java b/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/ItemDetailsLookup.java
index 002849c..9955d7b 100644
--- a/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/ItemDetailsLookup.java
+++ b/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/ItemDetailsLookup.java
@@ -45,9 +45,9 @@
  *   }
  *
  *   public ItemDetails<Uri> getItemDetails(MotionEvent e) {
- *       View view = mRecView.findChildViewUnder(e.getX(), e.getY());
+ *       View view = mRecyclerView.findChildViewUnder(e.getX(), e.getY());
  *       if (view != null) {
- *           ViewHolder holder = mRecView.getChildViewHolder(view);
+ *           ViewHolder holder = mRecyclerView.getChildViewHolder(view);
  *           if (holder instanceof MyHolder) {
  *               return ((MyHolder) holder).getItemDetails();
  *           }
diff --git a/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/PointerDragEventInterceptor.java b/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/PointerDragEventInterceptor.java
index 46ec5dd..ea8936f 100644
--- a/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/PointerDragEventInterceptor.java
+++ b/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/PointerDragEventInterceptor.java
@@ -25,7 +25,7 @@
 import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener;
 
 /**
- * OnItemTouchListener that delegates drag events to a drag listener,
+ * OnItemTouchListener that detects and delegates drag events to a drag listener,
  * else sends event to fallback {@link OnItemTouchListener}.
  *
  * <p>See {@link OnDragInitiatedListener} for details on implementing drag and drop.
@@ -34,7 +34,7 @@
 
     private final ItemDetailsLookup mEventDetailsLookup;
     private final OnDragInitiatedListener mDragListener;
-    private @Nullable OnItemTouchListener mDelegate;
+    private OnItemTouchListener mDelegate;
 
     PointerDragEventInterceptor(
             ItemDetailsLookup eventDetailsLookup,
@@ -46,30 +46,29 @@
 
         mEventDetailsLookup = eventDetailsLookup;
         mDragListener = dragListener;
-        mDelegate = delegate;
+
+        if (delegate != null) {
+            mDelegate = delegate;
+        } else {
+            mDelegate = new DummyOnItemTouchListener();
+        }
     }
 
     @Override
     public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
         if (MotionEvents.isPointerDragEvent(e) && mEventDetailsLookup.inItemDragRegion(e)) {
             return mDragListener.onDragInitiated(e);
-        } else if (mDelegate != null) {
-            return mDelegate.onInterceptTouchEvent(rv, e);
         }
-        return false;
+        return mDelegate.onInterceptTouchEvent(rv, e);
     }
 
     @Override
     public void onTouchEvent(RecyclerView rv, MotionEvent e) {
-        if (mDelegate != null) {
-            mDelegate.onTouchEvent(rv, e);
-        }
+        mDelegate.onTouchEvent(rv, e);
     }
 
     @Override
     public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
-        if (mDelegate != null) {
-            mDelegate.onRequestDisallowInterceptTouchEvent(disallowIntercept);
-        }
+        mDelegate.onRequestDisallowInterceptTouchEvent(disallowIntercept);
     }
 }
diff --git a/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/SelectionTracker.java b/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/SelectionTracker.java
index 76087ea..68f9d02 100644
--- a/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/SelectionTracker.java
+++ b/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/SelectionTracker.java
@@ -490,6 +490,7 @@
         private BandPredicate mBandPredicate;
         private int mBandOverlayId = R.drawable.selection_band_overlay;
 
+        // TODO(b/138958244): Support resetting state in response to unknown > cancel events.
         private int[] mGestureToolTypes = new int[] {
                 MotionEvent.TOOL_TYPE_FINGER,
                 MotionEvent.TOOL_TYPE_UNKNOWN
@@ -696,17 +697,15 @@
             // of events. If mouse handling is configured as well, the mouse input
             // related handlers will intercept mouse input events.
 
+            // EventRouter receives events for RecyclerView, dispatching to handlers
+            // registered by tool-type.
+            EventRouter eventRouter = new EventRouter();
+
             // GestureRouter is responsible for routing GestureDetector events
             // to tool-type specific handlers.
             GestureRouter<MotionInputHandler> gestureRouter = new GestureRouter<>();
             GestureDetector gestureDetector = new GestureDetector(mContext, gestureRouter);
 
-            // TouchEventRouter takes its name from RecyclerView#OnItemTouchListener.
-            // Despite "Touch" being in the name, it receives events for all types of tools.
-            // This class is responsible for routing events to tool-type specific handlers,
-            // and if not handled by a handler, on to a GestureDetector for analysis.
-            TouchEventRouter eventRouter = new TouchEventRouter(gestureDetector);
-
             // GestureSelectionHelper provides logic that interprets a combination
             // of motions and gestures in order to provide gesture driven selection support
             // when used in conjunction with RecyclerView.
@@ -715,6 +714,8 @@
 
             // Finally hook the framework up to listening to recycle view events.
             mRecyclerView.addOnItemTouchListener(eventRouter);
+            mRecyclerView.addOnItemTouchListener(
+                    new GestureDetectorOnItemTouchListenerAdapter(gestureDetector));
 
             // But before you move on, there's more work to do. Event plumbing has been
             // installed, but we haven't registered any of our helpers or callbacks.
@@ -782,7 +783,7 @@
 
             for (int toolType : mGestureToolTypes) {
                 gestureRouter.register(toolType, touchHandler);
-                eventRouter.register(toolType, gestureHelper);
+                eventRouter.set(toolType, gestureHelper);
             }
 
             // Provides high level glue for binding mouse events and gestures
@@ -826,7 +827,7 @@
                     mDetailsLookup, mOnDragInitiatedListener, bandHelper);
 
             for (int toolType : mPointerToolTypes) {
-                eventRouter.register(toolType, pointerEventHandler);
+                eventRouter.set(toolType, pointerEventHandler);
             }
 
             return tracker;
diff --git a/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/ToolHandlerRegistry.java b/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/ToolHandlerRegistry.java
index 8fc82c6..856ebb3 100644
--- a/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/ToolHandlerRegistry.java
+++ b/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/ToolHandlerRegistry.java
@@ -30,29 +30,27 @@
 /**
  * Registry for tool specific event handler. This provides map like functionality,
  * along with fallback to a default handler, while avoiding auto-boxing of tool
- * type values that would be necessitated where a Map used.
+ * type values that would be necessitated were a Map used.k
+ *
+ * <p>ToolHandlerRegistry guarantees that it will never return a null handler ensuring
+ * client code isn't peppered with null checks. To that end a default handler
+ * is required. This default handler will be returned when a handler matching
+ * the event tooltype has not be registered using {@link #set(int, T)}.
  *
  * @param <T> type of item being registered.
  */
 final class ToolHandlerRegistry<T> {
 
-    // Currently there are four known input types. ERASER is the last one, so has the
-    // highest value. UNKNOWN is zero, so we add one. This allows delegates to be
-    // registered by type, and avoid the auto-boxing that would be necessary were we
-    // to store delegates in a Map<Integer, Delegate>.
-    private static final int NUM_INPUT_TYPES = MotionEvent.TOOL_TYPE_ERASER + 1;
-
+    // list with one null entry for each known tooltype (0-4).
+    // See MotionEvent.TOOL_TYPE_ERASER for details. We're using a list here because
+    // it is parameterized type friendly, and a natural container given that
+    // the index values are 0-based ints.
     private final List<T> mHandlers = Arrays.asList(null, null, null, null, null);
     private final T mDefault;
 
     ToolHandlerRegistry(@NonNull T defaultDelegate) {
         checkArgument(defaultDelegate != null);
         mDefault = defaultDelegate;
-
-        // Initialize all values to null.
-        for (int i = 0; i < NUM_INPUT_TYPES; i++) {
-            mHandlers.set(i, null);
-        }
     }
 
     /**
diff --git a/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/TouchEventRouter.java b/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/TouchEventRouter.java
deleted file mode 100644
index a5501da..0000000
--- a/recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/TouchEventRouter.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2017 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.recyclerview.selection;
-
-import static androidx.core.util.Preconditions.checkArgument;
-
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener;
-
-/**
- * A class responsible for routing MotionEvents to tool-type specific handlers,
- * and if not handled by a handler, on to a {@link GestureDetector} for further
- * processing.
- *
- * <p>
- * TouchEventRouter takes its name from
- * {@link RecyclerView#addOnItemTouchListener(OnItemTouchListener)}. Despite "Touch"
- * being in the name, it receives MotionEvents for all types of tools.
- */
-final class TouchEventRouter implements OnItemTouchListener {
-
-    private static final String TAG = "TouchEventRouter";
-
-    private final GestureDetector mDetector;
-    private final ToolHandlerRegistry<OnItemTouchListener> mDelegates;
-
-    TouchEventRouter(
-            @NonNull GestureDetector detector, @NonNull OnItemTouchListener defaultDelegate) {
-
-        checkArgument(detector != null);
-        checkArgument(defaultDelegate != null);
-
-        mDetector = detector;
-        mDelegates = new ToolHandlerRegistry<>(defaultDelegate);
-    }
-
-    TouchEventRouter(@NonNull GestureDetector detector) {
-        this(
-                detector,
-                // Supply a fallback listener does nothing...because the caller
-                // didn't supply a fallback.
-                new OnItemTouchListener() {
-                    @Override
-                    public boolean onInterceptTouchEvent(
-                            @NonNull RecyclerView unused, @NonNull MotionEvent e) {
-
-                        return false;
-                    }
-
-                    @Override
-                    public void onTouchEvent(
-                            @NonNull RecyclerView unused, @NonNull MotionEvent e) {
-                    }
-
-                    @Override
-                    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
-                    }
-                });
-    }
-
-    /**
-     * @param toolType See MotionEvent for details on available types.
-     * @param delegate An {@link OnItemTouchListener} to receive events
-     *     of {@code toolType}.
-     */
-    void register(int toolType, @NonNull OnItemTouchListener delegate) {
-        checkArgument(delegate != null);
-        mDelegates.set(toolType, delegate);
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
-        boolean handled = mDelegates.get(e).onInterceptTouchEvent(rv, e);
-
-        // Forward all events to UserInputHandler.
-        // This is necessary since UserInputHandler needs to always see the first DOWN event. Or
-        // else all future UP events will be tossed.
-        handled |= mDetector.onTouchEvent(e);
-
-        return handled;
-    }
-
-    @Override
-    public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
-        mDelegates.get(e).onTouchEvent(rv, e);
-
-        // Note: even though this event is being handled as part of gestures such as drag and band,
-        // continue forwarding to the GestureDetector. The detector needs to see the entire cluster
-        // of events in order to properly interpret other gestures, such as long press.
-        mDetector.onTouchEvent(e);
-    }
-
-    @Override
-    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
-}
diff --git a/recyclerview/recyclerview/api/1.1.0-beta03.txt b/recyclerview/recyclerview/api/1.1.0-beta03.txt
new file mode 100644
index 0000000..2e41ff1
--- /dev/null
+++ b/recyclerview/recyclerview/api/1.1.0-beta03.txt
@@ -0,0 +1,1037 @@
+// Signature format: 3.0
+package androidx.recyclerview.widget {
+
+  public final class AdapterListUpdateCallback implements androidx.recyclerview.widget.ListUpdateCallback {
+    ctor public AdapterListUpdateCallback(androidx.recyclerview.widget.RecyclerView.Adapter);
+    method public void onChanged(int, int, Object!);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public final class AsyncDifferConfig<T> {
+    method public java.util.concurrent.Executor getBackgroundThreadExecutor();
+    method public androidx.recyclerview.widget.DiffUtil.ItemCallback<T!> getDiffCallback();
+  }
+
+  public static final class AsyncDifferConfig.Builder<T> {
+    ctor public AsyncDifferConfig.Builder(androidx.recyclerview.widget.DiffUtil.ItemCallback<T!>);
+    method public androidx.recyclerview.widget.AsyncDifferConfig<T!> build();
+    method public androidx.recyclerview.widget.AsyncDifferConfig.Builder<T!> setBackgroundThreadExecutor(java.util.concurrent.Executor!);
+  }
+
+  public class AsyncListDiffer<T> {
+    ctor public AsyncListDiffer(androidx.recyclerview.widget.RecyclerView.Adapter, androidx.recyclerview.widget.DiffUtil.ItemCallback<T!>);
+    ctor public AsyncListDiffer(androidx.recyclerview.widget.ListUpdateCallback, androidx.recyclerview.widget.AsyncDifferConfig<T!>);
+    method public void addListListener(androidx.recyclerview.widget.AsyncListDiffer.ListListener<T!>);
+    method public java.util.List<T!> getCurrentList();
+    method public void removeListListener(androidx.recyclerview.widget.AsyncListDiffer.ListListener<T!>);
+    method public void submitList(java.util.List<T!>?);
+    method public void submitList(java.util.List<T!>?, Runnable?);
+  }
+
+  public static interface AsyncListDiffer.ListListener<T> {
+    method public void onCurrentListChanged(java.util.List<T!>, java.util.List<T!>);
+  }
+
+  public class AsyncListUtil<T> {
+    ctor public AsyncListUtil(Class<T!>, int, androidx.recyclerview.widget.AsyncListUtil.DataCallback<T!>, androidx.recyclerview.widget.AsyncListUtil.ViewCallback);
+    method public T? getItem(int);
+    method public int getItemCount();
+    method public void onRangeChanged();
+    method public void refresh();
+  }
+
+  public abstract static class AsyncListUtil.DataCallback<T> {
+    ctor public AsyncListUtil.DataCallback();
+    method @WorkerThread public abstract void fillData(T![], int, int);
+    method @WorkerThread public int getMaxCachedTiles();
+    method @WorkerThread public void recycleData(T![], int);
+    method @WorkerThread public abstract int refreshData();
+  }
+
+  public abstract static class AsyncListUtil.ViewCallback {
+    ctor public AsyncListUtil.ViewCallback();
+    method @UiThread public void extendRangeInto(int[], int[], int);
+    method @UiThread public abstract void getItemRangeInto(int[]);
+    method @UiThread public abstract void onDataRefresh();
+    method @UiThread public abstract void onItemLoaded(int);
+    field public static final int HINT_SCROLL_ASC = 2; // 0x2
+    field public static final int HINT_SCROLL_DESC = 1; // 0x1
+    field public static final int HINT_SCROLL_NONE = 0; // 0x0
+  }
+
+  public class BatchingListUpdateCallback implements androidx.recyclerview.widget.ListUpdateCallback {
+    ctor public BatchingListUpdateCallback(androidx.recyclerview.widget.ListUpdateCallback);
+    method public void dispatchLastEvent();
+    method public void onChanged(int, int, Object!);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public class DefaultItemAnimator extends androidx.recyclerview.widget.SimpleItemAnimator {
+    ctor public DefaultItemAnimator();
+    method public boolean animateAdd(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder!, androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animateMove(androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animateRemove(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void endAnimation(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void endAnimations();
+    method public boolean isRunning();
+    method public void runPendingAnimations();
+  }
+
+  public class DiffUtil {
+    method public static androidx.recyclerview.widget.DiffUtil.DiffResult calculateDiff(androidx.recyclerview.widget.DiffUtil.Callback);
+    method public static androidx.recyclerview.widget.DiffUtil.DiffResult calculateDiff(androidx.recyclerview.widget.DiffUtil.Callback, boolean);
+  }
+
+  public abstract static class DiffUtil.Callback {
+    ctor public DiffUtil.Callback();
+    method public abstract boolean areContentsTheSame(int, int);
+    method public abstract boolean areItemsTheSame(int, int);
+    method public Object? getChangePayload(int, int);
+    method public abstract int getNewListSize();
+    method public abstract int getOldListSize();
+  }
+
+  public static class DiffUtil.DiffResult {
+    method public int convertNewPositionToOld(@IntRange(from=0) int);
+    method public int convertOldPositionToNew(@IntRange(from=0) int);
+    method public void dispatchUpdatesTo(androidx.recyclerview.widget.RecyclerView.Adapter);
+    method public void dispatchUpdatesTo(androidx.recyclerview.widget.ListUpdateCallback);
+    field public static final int NO_POSITION = -1; // 0xffffffff
+  }
+
+  public abstract static class DiffUtil.ItemCallback<T> {
+    ctor public DiffUtil.ItemCallback();
+    method public abstract boolean areContentsTheSame(T, T);
+    method public abstract boolean areItemsTheSame(T, T);
+    method public Object? getChangePayload(T, T);
+  }
+
+  public class DividerItemDecoration extends androidx.recyclerview.widget.RecyclerView.ItemDecoration {
+    ctor public DividerItemDecoration(android.content.Context!, int);
+    method public android.graphics.drawable.Drawable? getDrawable();
+    method public void setDrawable(android.graphics.drawable.Drawable);
+    method public void setOrientation(int);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public class GridLayoutManager extends androidx.recyclerview.widget.LinearLayoutManager {
+    ctor public GridLayoutManager(android.content.Context!, android.util.AttributeSet!, int, int);
+    ctor public GridLayoutManager(android.content.Context!, int);
+    ctor public GridLayoutManager(android.content.Context!, int, int, boolean);
+    method public int getSpanCount();
+    method public androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup! getSpanSizeLookup();
+    method public boolean isUsingSpansToEstimateScrollbarDimensions();
+    method public void setSpanCount(int);
+    method public void setSpanSizeLookup(androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup!);
+    method public void setUsingSpansToEstimateScrollbarDimensions(boolean);
+    field public static final int DEFAULT_SPAN_COUNT = -1; // 0xffffffff
+  }
+
+  public static final class GridLayoutManager.DefaultSpanSizeLookup extends androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup {
+    ctor public GridLayoutManager.DefaultSpanSizeLookup();
+    method public int getSpanSize(int);
+  }
+
+  public static class GridLayoutManager.LayoutParams extends androidx.recyclerview.widget.RecyclerView.LayoutParams {
+    ctor public GridLayoutManager.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public GridLayoutManager.LayoutParams(int, int);
+    ctor public GridLayoutManager.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public GridLayoutManager.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public GridLayoutManager.LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public int getSpanIndex();
+    method public int getSpanSize();
+    field public static final int INVALID_SPAN_ID = -1; // 0xffffffff
+  }
+
+  public abstract static class GridLayoutManager.SpanSizeLookup {
+    ctor public GridLayoutManager.SpanSizeLookup();
+    method public int getSpanGroupIndex(int, int);
+    method public int getSpanIndex(int, int);
+    method public abstract int getSpanSize(int);
+    method public void invalidateSpanGroupIndexCache();
+    method public void invalidateSpanIndexCache();
+    method public boolean isSpanGroupIndexCacheEnabled();
+    method public boolean isSpanIndexCacheEnabled();
+    method public void setSpanGroupIndexCacheEnabled(boolean);
+    method public void setSpanIndexCacheEnabled(boolean);
+  }
+
+  public class ItemTouchHelper extends androidx.recyclerview.widget.RecyclerView.ItemDecoration implements androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener {
+    ctor public ItemTouchHelper(androidx.recyclerview.widget.ItemTouchHelper.Callback);
+    method public void attachToRecyclerView(androidx.recyclerview.widget.RecyclerView?);
+    method public void onChildViewAttachedToWindow(android.view.View);
+    method public void onChildViewDetachedFromWindow(android.view.View);
+    method public void startDrag(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void startSwipe(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    field public static final int ACTION_STATE_DRAG = 2; // 0x2
+    field public static final int ACTION_STATE_IDLE = 0; // 0x0
+    field public static final int ACTION_STATE_SWIPE = 1; // 0x1
+    field public static final int ANIMATION_TYPE_DRAG = 8; // 0x8
+    field public static final int ANIMATION_TYPE_SWIPE_CANCEL = 4; // 0x4
+    field public static final int ANIMATION_TYPE_SWIPE_SUCCESS = 2; // 0x2
+    field public static final int DOWN = 2; // 0x2
+    field public static final int END = 32; // 0x20
+    field public static final int LEFT = 4; // 0x4
+    field public static final int RIGHT = 8; // 0x8
+    field public static final int START = 16; // 0x10
+    field public static final int UP = 1; // 0x1
+  }
+
+  public abstract static class ItemTouchHelper.Callback {
+    ctor public ItemTouchHelper.Callback();
+    method public boolean canDropOver(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder! chooseDropTarget(androidx.recyclerview.widget.RecyclerView.ViewHolder, java.util.List<androidx.recyclerview.widget.RecyclerView.ViewHolder!>, int, int);
+    method public void clearView(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public int convertToAbsoluteDirection(int, int);
+    method public static int convertToRelativeDirection(int, int);
+    method public long getAnimationDuration(androidx.recyclerview.widget.RecyclerView, int, float, float);
+    method public int getBoundingBoxMargin();
+    method public static androidx.recyclerview.widget.ItemTouchUIUtil getDefaultUIUtil();
+    method public float getMoveThreshold(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public abstract int getMovementFlags(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public float getSwipeEscapeVelocity(float);
+    method public float getSwipeThreshold(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public float getSwipeVelocityThreshold(float);
+    method public int interpolateOutOfBoundsScroll(androidx.recyclerview.widget.RecyclerView, int, int, int, long);
+    method public boolean isItemViewSwipeEnabled();
+    method public boolean isLongPressDragEnabled();
+    method public static int makeFlag(int, int);
+    method public static int makeMovementFlags(int, int);
+    method public void onChildDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, float, float, int, boolean);
+    method public void onChildDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder!, float, float, int, boolean);
+    method public abstract boolean onMove(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onMoved(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, int, int);
+    method public void onSelectedChanged(androidx.recyclerview.widget.RecyclerView.ViewHolder?, int);
+    method public abstract void onSwiped(androidx.recyclerview.widget.RecyclerView.ViewHolder, int);
+    field public static final int DEFAULT_DRAG_ANIMATION_DURATION = 200; // 0xc8
+    field public static final int DEFAULT_SWIPE_ANIMATION_DURATION = 250; // 0xfa
+  }
+
+  public abstract static class ItemTouchHelper.SimpleCallback extends androidx.recyclerview.widget.ItemTouchHelper.Callback {
+    ctor public ItemTouchHelper.SimpleCallback(int, int);
+    method public int getDragDirs(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public int getMovementFlags(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public int getSwipeDirs(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void setDefaultDragDirs(int);
+    method public void setDefaultSwipeDirs(int);
+  }
+
+  public static interface ItemTouchHelper.ViewDropHandler {
+    method public void prepareForDrop(android.view.View, android.view.View, int, int);
+  }
+
+  public interface ItemTouchUIUtil {
+    method public void clearView(android.view.View!);
+    method public void onDraw(android.graphics.Canvas!, androidx.recyclerview.widget.RecyclerView!, android.view.View!, float, float, int, boolean);
+    method public void onDrawOver(android.graphics.Canvas!, androidx.recyclerview.widget.RecyclerView!, android.view.View!, float, float, int, boolean);
+    method public void onSelected(android.view.View!);
+  }
+
+  public class LinearLayoutManager extends androidx.recyclerview.widget.RecyclerView.LayoutManager implements androidx.recyclerview.widget.ItemTouchHelper.ViewDropHandler androidx.recyclerview.widget.RecyclerView.SmoothScroller.ScrollVectorProvider {
+    ctor public LinearLayoutManager(android.content.Context!);
+    ctor public LinearLayoutManager(android.content.Context!, int, boolean);
+    ctor public LinearLayoutManager(android.content.Context!, android.util.AttributeSet!, int, int);
+    method protected void calculateExtraLayoutSpace(androidx.recyclerview.widget.RecyclerView.State, int[]);
+    method public android.graphics.PointF! computeScrollVectorForPosition(int);
+    method public int findFirstCompletelyVisibleItemPosition();
+    method public int findFirstVisibleItemPosition();
+    method public int findLastCompletelyVisibleItemPosition();
+    method public int findLastVisibleItemPosition();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateDefaultLayoutParams();
+    method @Deprecated protected int getExtraLayoutSpace(androidx.recyclerview.widget.RecyclerView.State!);
+    method public int getInitialPrefetchItemCount();
+    method public int getOrientation();
+    method public boolean getRecycleChildrenOnDetach();
+    method public boolean getReverseLayout();
+    method public boolean getStackFromEnd();
+    method protected boolean isLayoutRTL();
+    method public boolean isSmoothScrollbarEnabled();
+    method public void prepareForDrop(android.view.View, android.view.View, int, int);
+    method public void scrollToPositionWithOffset(int, int);
+    method public void setInitialPrefetchItemCount(int);
+    method public void setOrientation(int);
+    method public void setRecycleChildrenOnDetach(boolean);
+    method public void setReverseLayout(boolean);
+    method public void setSmoothScrollbarEnabled(boolean);
+    method public void setStackFromEnd(boolean);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int INVALID_OFFSET = -2147483648; // 0x80000000
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  protected static class LinearLayoutManager.LayoutChunkResult {
+    ctor protected LinearLayoutManager.LayoutChunkResult();
+    field public int mConsumed;
+    field public boolean mFinished;
+    field public boolean mFocusable;
+    field public boolean mIgnoreConsumed;
+  }
+
+  public class LinearSmoothScroller extends androidx.recyclerview.widget.RecyclerView.SmoothScroller {
+    ctor public LinearSmoothScroller(android.content.Context!);
+    method public int calculateDtToFit(int, int, int, int, int);
+    method public int calculateDxToMakeVisible(android.view.View!, int);
+    method public int calculateDyToMakeVisible(android.view.View!, int);
+    method protected float calculateSpeedPerPixel(android.util.DisplayMetrics!);
+    method protected int calculateTimeForDeceleration(int);
+    method protected int calculateTimeForScrolling(int);
+    method protected int getHorizontalSnapPreference();
+    method protected int getVerticalSnapPreference();
+    method protected void onSeekTargetStep(int, int, androidx.recyclerview.widget.RecyclerView.State!, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action!);
+    method protected void onStart();
+    method protected void onStop();
+    method protected void onTargetFound(android.view.View!, androidx.recyclerview.widget.RecyclerView.State!, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action!);
+    method protected void updateActionForInterimTarget(androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action!);
+    field public static final int SNAP_TO_ANY = 0; // 0x0
+    field public static final int SNAP_TO_END = 1; // 0x1
+    field public static final int SNAP_TO_START = -1; // 0xffffffff
+    field protected final android.view.animation.DecelerateInterpolator! mDecelerateInterpolator;
+    field protected int mInterimTargetDx;
+    field protected int mInterimTargetDy;
+    field protected final android.view.animation.LinearInterpolator! mLinearInterpolator;
+    field protected android.graphics.PointF! mTargetVector;
+  }
+
+  public class LinearSnapHelper extends androidx.recyclerview.widget.SnapHelper {
+    ctor public LinearSnapHelper();
+    method public int[]! calculateDistanceToFinalSnap(androidx.recyclerview.widget.RecyclerView.LayoutManager, android.view.View);
+    method public android.view.View! findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public int findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int, int);
+  }
+
+  public abstract class ListAdapter<T, VH extends androidx.recyclerview.widget.RecyclerView.ViewHolder> extends androidx.recyclerview.widget.RecyclerView.Adapter<VH> {
+    ctor protected ListAdapter(androidx.recyclerview.widget.DiffUtil.ItemCallback<T!>);
+    ctor protected ListAdapter(androidx.recyclerview.widget.AsyncDifferConfig<T!>);
+    method public java.util.List<T!> getCurrentList();
+    method protected T! getItem(int);
+    method public int getItemCount();
+    method public void onCurrentListChanged(java.util.List<T!>, java.util.List<T!>);
+    method public void submitList(java.util.List<T!>?);
+    method public void submitList(java.util.List<T!>?, Runnable?);
+  }
+
+  public interface ListUpdateCallback {
+    method public void onChanged(int, int, Object?);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public abstract class OrientationHelper {
+    method public static androidx.recyclerview.widget.OrientationHelper! createHorizontalHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public static androidx.recyclerview.widget.OrientationHelper! createOrientationHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int);
+    method public static androidx.recyclerview.widget.OrientationHelper! createVerticalHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public abstract int getDecoratedEnd(android.view.View!);
+    method public abstract int getDecoratedMeasurement(android.view.View!);
+    method public abstract int getDecoratedMeasurementInOther(android.view.View!);
+    method public abstract int getDecoratedStart(android.view.View!);
+    method public abstract int getEnd();
+    method public abstract int getEndAfterPadding();
+    method public abstract int getEndPadding();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutManager! getLayoutManager();
+    method public abstract int getMode();
+    method public abstract int getModeInOther();
+    method public abstract int getStartAfterPadding();
+    method public abstract int getTotalSpace();
+    method public int getTotalSpaceChange();
+    method public abstract int getTransformedEndWithDecoration(android.view.View!);
+    method public abstract int getTransformedStartWithDecoration(android.view.View!);
+    method public abstract void offsetChild(android.view.View!, int);
+    method public abstract void offsetChildren(int);
+    method public void onLayoutComplete();
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+    field protected final androidx.recyclerview.widget.RecyclerView.LayoutManager! mLayoutManager;
+  }
+
+  public class PagerSnapHelper extends androidx.recyclerview.widget.SnapHelper {
+    ctor public PagerSnapHelper();
+    method public int[]? calculateDistanceToFinalSnap(androidx.recyclerview.widget.RecyclerView.LayoutManager, android.view.View);
+    method protected androidx.recyclerview.widget.LinearSmoothScroller! createSnapScroller(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public android.view.View? findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public int findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int, int);
+  }
+
+  public class RecyclerView extends android.view.ViewGroup implements androidx.core.view.NestedScrollingChild2 androidx.core.view.NestedScrollingChild3 androidx.core.view.ScrollingView {
+    ctor public RecyclerView(android.content.Context);
+    ctor public RecyclerView(android.content.Context, android.util.AttributeSet?);
+    ctor public RecyclerView(android.content.Context, android.util.AttributeSet?, int);
+    method public void addItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration, int);
+    method public void addItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration);
+    method public void addOnChildAttachStateChangeListener(androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener);
+    method public void addOnItemTouchListener(androidx.recyclerview.widget.RecyclerView.OnItemTouchListener);
+    method public void addOnScrollListener(androidx.recyclerview.widget.RecyclerView.OnScrollListener);
+    method public void clearOnChildAttachStateChangeListeners();
+    method public void clearOnScrollListeners();
+    method public int computeHorizontalScrollExtent();
+    method public int computeHorizontalScrollOffset();
+    method public int computeHorizontalScrollRange();
+    method public int computeVerticalScrollExtent();
+    method public int computeVerticalScrollOffset();
+    method public int computeVerticalScrollRange();
+    method public boolean dispatchNestedPreScroll(int, int, int[]!, int[]!, int);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]!, int);
+    method public final void dispatchNestedScroll(int, int, int, int, int[]!, int, int[]);
+    method public boolean drawChild(android.graphics.Canvas!, android.view.View!, long);
+    method public android.view.View? findChildViewUnder(float, float);
+    method public android.view.View? findContainingItemView(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? findContainingViewHolder(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? findViewHolderForAdapterPosition(int);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder! findViewHolderForItemId(long);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? findViewHolderForLayoutPosition(int);
+    method @Deprecated public androidx.recyclerview.widget.RecyclerView.ViewHolder? findViewHolderForPosition(int);
+    method public boolean fling(int, int);
+    method public androidx.recyclerview.widget.RecyclerView.Adapter? getAdapter();
+    method public int getChildAdapterPosition(android.view.View);
+    method public long getChildItemId(android.view.View);
+    method public int getChildLayoutPosition(android.view.View);
+    method @Deprecated public int getChildPosition(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder! getChildViewHolder(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate? getCompatAccessibilityDelegate();
+    method public void getDecoratedBoundsWithMargins(android.view.View, android.graphics.Rect);
+    method public androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory getEdgeEffectFactory();
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator? getItemAnimator();
+    method public androidx.recyclerview.widget.RecyclerView.ItemDecoration getItemDecorationAt(int);
+    method public int getItemDecorationCount();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutManager? getLayoutManager();
+    method public int getMaxFlingVelocity();
+    method public int getMinFlingVelocity();
+    method public androidx.recyclerview.widget.RecyclerView.OnFlingListener? getOnFlingListener();
+    method public boolean getPreserveFocusAfterLayout();
+    method public androidx.recyclerview.widget.RecyclerView.RecycledViewPool getRecycledViewPool();
+    method public int getScrollState();
+    method public boolean hasFixedSize();
+    method public boolean hasNestedScrollingParent(int);
+    method public boolean hasPendingAdapterUpdates();
+    method public void invalidateItemDecorations();
+    method public boolean isAnimating();
+    method public boolean isComputingLayout();
+    method @Deprecated public boolean isLayoutFrozen();
+    method public final boolean isLayoutSuppressed();
+    method public void offsetChildrenHorizontal(@Px int);
+    method public void offsetChildrenVertical(@Px int);
+    method public void onChildAttachedToWindow(android.view.View);
+    method public void onChildDetachedFromWindow(android.view.View);
+    method public void onDraw(android.graphics.Canvas!);
+    method public void onScrollStateChanged(int);
+    method public void onScrolled(@Px int, @Px int);
+    method public void removeItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration);
+    method public void removeItemDecorationAt(int);
+    method public void removeOnChildAttachStateChangeListener(androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener);
+    method public void removeOnItemTouchListener(androidx.recyclerview.widget.RecyclerView.OnItemTouchListener);
+    method public void removeOnScrollListener(androidx.recyclerview.widget.RecyclerView.OnScrollListener);
+    method public void scrollToPosition(int);
+    method public void setAccessibilityDelegateCompat(androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate?);
+    method public void setAdapter(androidx.recyclerview.widget.RecyclerView.Adapter?);
+    method public void setChildDrawingOrderCallback(androidx.recyclerview.widget.RecyclerView.ChildDrawingOrderCallback?);
+    method public void setEdgeEffectFactory(androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory);
+    method public void setHasFixedSize(boolean);
+    method public void setItemAnimator(androidx.recyclerview.widget.RecyclerView.ItemAnimator?);
+    method public void setItemViewCacheSize(int);
+    method @Deprecated public void setLayoutFrozen(boolean);
+    method public void setLayoutManager(androidx.recyclerview.widget.RecyclerView.LayoutManager?);
+    method @Deprecated public void setLayoutTransition(android.animation.LayoutTransition!);
+    method public void setOnFlingListener(androidx.recyclerview.widget.RecyclerView.OnFlingListener?);
+    method @Deprecated public void setOnScrollListener(androidx.recyclerview.widget.RecyclerView.OnScrollListener?);
+    method public void setPreserveFocusAfterLayout(boolean);
+    method public void setRecycledViewPool(androidx.recyclerview.widget.RecyclerView.RecycledViewPool?);
+    method public void setRecyclerListener(androidx.recyclerview.widget.RecyclerView.RecyclerListener?);
+    method public void setScrollingTouchSlop(int);
+    method public void setViewCacheExtension(androidx.recyclerview.widget.RecyclerView.ViewCacheExtension?);
+    method public void smoothScrollBy(@Px int, @Px int);
+    method public void smoothScrollBy(@Px int, @Px int, android.view.animation.Interpolator?);
+    method public void smoothScrollBy(@Px int, @Px int, android.view.animation.Interpolator?, int);
+    method public void smoothScrollToPosition(int);
+    method public boolean startNestedScroll(int, int);
+    method public void stopNestedScroll(int);
+    method public void stopScroll();
+    method public final void suppressLayout(boolean);
+    method public void swapAdapter(androidx.recyclerview.widget.RecyclerView.Adapter?, boolean);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int INVALID_TYPE = -1; // 0xffffffff
+    field public static final long NO_ID = -1L; // 0xffffffffffffffffL
+    field public static final int NO_POSITION = -1; // 0xffffffff
+    field public static final int SCROLL_STATE_DRAGGING = 1; // 0x1
+    field public static final int SCROLL_STATE_IDLE = 0; // 0x0
+    field public static final int SCROLL_STATE_SETTLING = 2; // 0x2
+    field public static final int TOUCH_SLOP_DEFAULT = 0; // 0x0
+    field public static final int TOUCH_SLOP_PAGING = 1; // 0x1
+    field public static final int UNDEFINED_DURATION = -2147483648; // 0x80000000
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public abstract static class RecyclerView.Adapter<VH extends androidx.recyclerview.widget.RecyclerView.ViewHolder> {
+    ctor public RecyclerView.Adapter();
+    method public final void bindViewHolder(VH, int);
+    method public final VH createViewHolder(android.view.ViewGroup, int);
+    method public abstract int getItemCount();
+    method public long getItemId(int);
+    method public int getItemViewType(int);
+    method public final boolean hasObservers();
+    method public final boolean hasStableIds();
+    method public final void notifyDataSetChanged();
+    method public final void notifyItemChanged(int);
+    method public final void notifyItemChanged(int, Object?);
+    method public final void notifyItemInserted(int);
+    method public final void notifyItemMoved(int, int);
+    method public final void notifyItemRangeChanged(int, int);
+    method public final void notifyItemRangeChanged(int, int, Object?);
+    method public final void notifyItemRangeInserted(int, int);
+    method public final void notifyItemRangeRemoved(int, int);
+    method public final void notifyItemRemoved(int);
+    method public void onAttachedToRecyclerView(androidx.recyclerview.widget.RecyclerView);
+    method public abstract void onBindViewHolder(VH, int);
+    method public void onBindViewHolder(VH, int, java.util.List<java.lang.Object!>);
+    method public abstract VH onCreateViewHolder(android.view.ViewGroup, int);
+    method public void onDetachedFromRecyclerView(androidx.recyclerview.widget.RecyclerView);
+    method public boolean onFailedToRecycleView(VH);
+    method public void onViewAttachedToWindow(VH);
+    method public void onViewDetachedFromWindow(VH);
+    method public void onViewRecycled(VH);
+    method public void registerAdapterDataObserver(androidx.recyclerview.widget.RecyclerView.AdapterDataObserver);
+    method public void setHasStableIds(boolean);
+    method public void unregisterAdapterDataObserver(androidx.recyclerview.widget.RecyclerView.AdapterDataObserver);
+  }
+
+  public abstract static class RecyclerView.AdapterDataObserver {
+    ctor public RecyclerView.AdapterDataObserver();
+    method public void onChanged();
+    method public void onItemRangeChanged(int, int);
+    method public void onItemRangeChanged(int, int, Object?);
+    method public void onItemRangeInserted(int, int);
+    method public void onItemRangeMoved(int, int, int);
+    method public void onItemRangeRemoved(int, int);
+  }
+
+  public static interface RecyclerView.ChildDrawingOrderCallback {
+    method public int onGetChildDrawingOrder(int, int);
+  }
+
+  public static class RecyclerView.EdgeEffectFactory {
+    ctor public RecyclerView.EdgeEffectFactory();
+    method protected android.widget.EdgeEffect createEdgeEffect(androidx.recyclerview.widget.RecyclerView, @androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.EdgeDirection int);
+    field public static final int DIRECTION_BOTTOM = 3; // 0x3
+    field public static final int DIRECTION_LEFT = 0; // 0x0
+    field public static final int DIRECTION_RIGHT = 2; // 0x2
+    field public static final int DIRECTION_TOP = 1; // 0x1
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_LEFT, androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_TOP, androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_RIGHT, androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_BOTTOM}) public static @interface RecyclerView.EdgeEffectFactory.EdgeDirection {
+  }
+
+  public abstract static class RecyclerView.ItemAnimator {
+    ctor public RecyclerView.ItemAnimator();
+    method public abstract boolean animateAppearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateDisappearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?);
+    method public abstract boolean animatePersistence(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public boolean canReuseUpdatedViewHolder(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public boolean canReuseUpdatedViewHolder(androidx.recyclerview.widget.RecyclerView.ViewHolder, java.util.List<java.lang.Object!>);
+    method public final void dispatchAnimationFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public final void dispatchAnimationStarted(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public final void dispatchAnimationsFinished();
+    method public abstract void endAnimation(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public abstract void endAnimations();
+    method public long getAddDuration();
+    method public long getChangeDuration();
+    method public long getMoveDuration();
+    method public long getRemoveDuration();
+    method public abstract boolean isRunning();
+    method public final boolean isRunning(androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemAnimatorFinishedListener?);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo obtainHolderInfo();
+    method public void onAnimationFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onAnimationStarted(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo recordPostLayoutInformation(androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo recordPreLayoutInformation(androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.ViewHolder, @androidx.recyclerview.widget.RecyclerView.ItemAnimator.AdapterChanges int, java.util.List<java.lang.Object!>);
+    method public abstract void runPendingAnimations();
+    method public void setAddDuration(long);
+    method public void setChangeDuration(long);
+    method public void setMoveDuration(long);
+    method public void setRemoveDuration(long);
+    field public static final int FLAG_APPEARED_IN_PRE_LAYOUT = 4096; // 0x1000
+    field public static final int FLAG_CHANGED = 2; // 0x2
+    field public static final int FLAG_INVALIDATED = 4; // 0x4
+    field public static final int FLAG_MOVED = 2048; // 0x800
+    field public static final int FLAG_REMOVED = 8; // 0x8
+  }
+
+  @IntDef(flag=true, value={androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_CHANGED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_REMOVED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_MOVED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_INVALIDATED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_APPEARED_IN_PRE_LAYOUT}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RecyclerView.ItemAnimator.AdapterChanges {
+  }
+
+  public static interface RecyclerView.ItemAnimator.ItemAnimatorFinishedListener {
+    method public void onAnimationsFinished();
+  }
+
+  public static class RecyclerView.ItemAnimator.ItemHolderInfo {
+    ctor public RecyclerView.ItemAnimator.ItemHolderInfo();
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo setFrom(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo setFrom(androidx.recyclerview.widget.RecyclerView.ViewHolder, @androidx.recyclerview.widget.RecyclerView.ItemAnimator.AdapterChanges int);
+    field public int bottom;
+    field @androidx.recyclerview.widget.RecyclerView.ItemAnimator.AdapterChanges public int changeFlags;
+    field public int left;
+    field public int right;
+    field public int top;
+  }
+
+  public abstract static class RecyclerView.ItemDecoration {
+    ctor public RecyclerView.ItemDecoration();
+    method @Deprecated public void getItemOffsets(android.graphics.Rect, int, androidx.recyclerview.widget.RecyclerView);
+    method public void getItemOffsets(android.graphics.Rect, android.view.View, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State);
+    method public void onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State);
+    method @Deprecated public void onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView);
+    method public void onDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State);
+    method @Deprecated public void onDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView);
+  }
+
+  public abstract static class RecyclerView.LayoutManager {
+    ctor public RecyclerView.LayoutManager();
+    method public void addDisappearingView(android.view.View!);
+    method public void addDisappearingView(android.view.View!, int);
+    method public void addView(android.view.View!);
+    method public void addView(android.view.View!, int);
+    method public void assertInLayoutOrScroll(String!);
+    method public void assertNotInLayoutOrScroll(String!);
+    method public void attachView(android.view.View, int, androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public void attachView(android.view.View, int);
+    method public void attachView(android.view.View);
+    method public void calculateItemDecorationsForChild(android.view.View, android.graphics.Rect);
+    method public boolean canScrollHorizontally();
+    method public boolean canScrollVertically();
+    method public boolean checkLayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public static int chooseSize(int, int, int);
+    method public void collectAdjacentPrefetchPositions(int, int, androidx.recyclerview.widget.RecyclerView.State!, androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry!);
+    method public void collectInitialPrefetchPositions(int, androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry!);
+    method public int computeHorizontalScrollExtent(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeHorizontalScrollOffset(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeHorizontalScrollRange(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeVerticalScrollExtent(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeVerticalScrollOffset(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeVerticalScrollRange(androidx.recyclerview.widget.RecyclerView.State);
+    method public void detachAndScrapAttachedViews(androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void detachAndScrapView(android.view.View, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void detachAndScrapViewAt(int, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void detachView(android.view.View);
+    method public void detachViewAt(int);
+    method public void endAnimation(android.view.View!);
+    method public android.view.View? findContainingItemView(android.view.View);
+    method public android.view.View? findViewByPosition(int);
+    method public abstract androidx.recyclerview.widget.RecyclerView.LayoutParams! generateDefaultLayoutParams();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateLayoutParams(android.content.Context!, android.util.AttributeSet!);
+    method public int getBaseline();
+    method public int getBottomDecorationHeight(android.view.View);
+    method public android.view.View? getChildAt(int);
+    method public int getChildCount();
+    method @Deprecated public static int getChildMeasureSpec(int, int, int, boolean);
+    method public static int getChildMeasureSpec(int, int, int, int, boolean);
+    method public boolean getClipToPadding();
+    method public int getColumnCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public int getDecoratedBottom(android.view.View);
+    method public void getDecoratedBoundsWithMargins(android.view.View, android.graphics.Rect);
+    method public int getDecoratedLeft(android.view.View);
+    method public int getDecoratedMeasuredHeight(android.view.View);
+    method public int getDecoratedMeasuredWidth(android.view.View);
+    method public int getDecoratedRight(android.view.View);
+    method public int getDecoratedTop(android.view.View);
+    method public android.view.View? getFocusedChild();
+    method @Px public int getHeight();
+    method public int getHeightMode();
+    method public int getItemCount();
+    method public int getItemViewType(android.view.View);
+    method public int getLayoutDirection();
+    method public int getLeftDecorationWidth(android.view.View);
+    method @Px public int getMinimumHeight();
+    method @Px public int getMinimumWidth();
+    method @Px public int getPaddingBottom();
+    method @Px public int getPaddingEnd();
+    method @Px public int getPaddingLeft();
+    method @Px public int getPaddingRight();
+    method @Px public int getPaddingStart();
+    method @Px public int getPaddingTop();
+    method public int getPosition(android.view.View);
+    method public static androidx.recyclerview.widget.RecyclerView.LayoutManager.Properties! getProperties(android.content.Context, android.util.AttributeSet?, int, int);
+    method public int getRightDecorationWidth(android.view.View);
+    method public int getRowCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public int getSelectionModeForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public int getTopDecorationHeight(android.view.View);
+    method public void getTransformedBoundingBox(android.view.View, boolean, android.graphics.Rect);
+    method @Px public int getWidth();
+    method public int getWidthMode();
+    method public boolean hasFocus();
+    method public void ignoreView(android.view.View);
+    method public boolean isAttachedToWindow();
+    method public boolean isAutoMeasureEnabled();
+    method public boolean isFocused();
+    method public final boolean isItemPrefetchEnabled();
+    method public boolean isLayoutHierarchical(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public boolean isMeasurementCacheEnabled();
+    method public boolean isSmoothScrolling();
+    method public boolean isViewPartiallyVisible(android.view.View, boolean, boolean);
+    method public void layoutDecorated(android.view.View, int, int, int, int);
+    method public void layoutDecoratedWithMargins(android.view.View, int, int, int, int);
+    method public void measureChild(android.view.View, int, int);
+    method public void measureChildWithMargins(android.view.View, int, int);
+    method public void moveView(int, int);
+    method public void offsetChildrenHorizontal(@Px int);
+    method public void offsetChildrenVertical(@Px int);
+    method public void onAdapterChanged(androidx.recyclerview.widget.RecyclerView.Adapter?, androidx.recyclerview.widget.RecyclerView.Adapter?);
+    method public boolean onAddFocusables(androidx.recyclerview.widget.RecyclerView, java.util.ArrayList<android.view.View!>, int, int);
+    method @CallSuper public void onAttachedToWindow(androidx.recyclerview.widget.RecyclerView!);
+    method @Deprecated public void onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView!);
+    method @CallSuper public void onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView!, androidx.recyclerview.widget.RecyclerView.Recycler!);
+    method public android.view.View? onFocusSearchFailed(android.view.View, int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public void onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityEvent(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityNodeInfo(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method public void onInitializeAccessibilityNodeInfoForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method public android.view.View? onInterceptFocusSearch(android.view.View, int);
+    method public void onItemsAdded(androidx.recyclerview.widget.RecyclerView, int, int);
+    method public void onItemsChanged(androidx.recyclerview.widget.RecyclerView);
+    method public void onItemsMoved(androidx.recyclerview.widget.RecyclerView, int, int, int);
+    method public void onItemsRemoved(androidx.recyclerview.widget.RecyclerView, int, int);
+    method public void onItemsUpdated(androidx.recyclerview.widget.RecyclerView, int, int);
+    method public void onItemsUpdated(androidx.recyclerview.widget.RecyclerView, int, int, Object?);
+    method public void onLayoutChildren(androidx.recyclerview.widget.RecyclerView.Recycler!, androidx.recyclerview.widget.RecyclerView.State!);
+    method public void onLayoutCompleted(androidx.recyclerview.widget.RecyclerView.State!);
+    method public void onMeasure(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, int, int);
+    method @Deprecated public boolean onRequestChildFocus(androidx.recyclerview.widget.RecyclerView, android.view.View, android.view.View?);
+    method public boolean onRequestChildFocus(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State, android.view.View, android.view.View?);
+    method public void onRestoreInstanceState(android.os.Parcelable!);
+    method public android.os.Parcelable? onSaveInstanceState();
+    method public void onScrollStateChanged(int);
+    method public boolean performAccessibilityAction(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, int, android.os.Bundle?);
+    method public boolean performAccessibilityActionForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, int, android.os.Bundle?);
+    method public void postOnAnimation(Runnable!);
+    method public void removeAllViews();
+    method public void removeAndRecycleAllViews(androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void removeAndRecycleView(android.view.View, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void removeAndRecycleViewAt(int, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public boolean removeCallbacks(Runnable!);
+    method public void removeDetachedView(android.view.View);
+    method public void removeView(android.view.View!);
+    method public void removeViewAt(int);
+    method public boolean requestChildRectangleOnScreen(androidx.recyclerview.widget.RecyclerView, android.view.View, android.graphics.Rect, boolean);
+    method public boolean requestChildRectangleOnScreen(androidx.recyclerview.widget.RecyclerView, android.view.View, android.graphics.Rect, boolean, boolean);
+    method public void requestLayout();
+    method public void requestSimpleAnimationsInNextLayout();
+    method public int scrollHorizontallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler!, androidx.recyclerview.widget.RecyclerView.State!);
+    method public void scrollToPosition(int);
+    method public int scrollVerticallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler!, androidx.recyclerview.widget.RecyclerView.State!);
+    method @Deprecated public void setAutoMeasureEnabled(boolean);
+    method public final void setItemPrefetchEnabled(boolean);
+    method public void setMeasuredDimension(android.graphics.Rect!, int, int);
+    method public void setMeasuredDimension(int, int);
+    method public void setMeasurementCacheEnabled(boolean);
+    method public void smoothScrollToPosition(androidx.recyclerview.widget.RecyclerView!, androidx.recyclerview.widget.RecyclerView.State!, int);
+    method public void startSmoothScroll(androidx.recyclerview.widget.RecyclerView.SmoothScroller!);
+    method public void stopIgnoringView(android.view.View);
+    method public boolean supportsPredictiveItemAnimations();
+  }
+
+  public static interface RecyclerView.LayoutManager.LayoutPrefetchRegistry {
+    method public void addPosition(int, int);
+  }
+
+  public static class RecyclerView.LayoutManager.Properties {
+    ctor public RecyclerView.LayoutManager.Properties();
+    field public int orientation;
+    field public boolean reverseLayout;
+    field public int spanCount;
+    field public boolean stackFromEnd;
+  }
+
+  public static class RecyclerView.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+    ctor public RecyclerView.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public RecyclerView.LayoutParams(int, int);
+    ctor public RecyclerView.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public RecyclerView.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public RecyclerView.LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public int getViewAdapterPosition();
+    method public int getViewLayoutPosition();
+    method @Deprecated public int getViewPosition();
+    method public boolean isItemChanged();
+    method public boolean isItemRemoved();
+    method public boolean isViewInvalid();
+    method public boolean viewNeedsUpdate();
+  }
+
+  public static interface RecyclerView.OnChildAttachStateChangeListener {
+    method public void onChildViewAttachedToWindow(android.view.View);
+    method public void onChildViewDetachedFromWindow(android.view.View);
+  }
+
+  public abstract static class RecyclerView.OnFlingListener {
+    ctor public RecyclerView.OnFlingListener();
+    method public abstract boolean onFling(int, int);
+  }
+
+  public static interface RecyclerView.OnItemTouchListener {
+    method public boolean onInterceptTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+    method public void onRequestDisallowInterceptTouchEvent(boolean);
+    method public void onTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+  }
+
+  public abstract static class RecyclerView.OnScrollListener {
+    ctor public RecyclerView.OnScrollListener();
+    method public void onScrollStateChanged(androidx.recyclerview.widget.RecyclerView, int);
+    method public void onScrolled(androidx.recyclerview.widget.RecyclerView, int, int);
+  }
+
+  public static class RecyclerView.RecycledViewPool {
+    ctor public RecyclerView.RecycledViewPool();
+    method public void clear();
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? getRecycledView(int);
+    method public int getRecycledViewCount(int);
+    method public void putRecycledView(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void setMaxRecycledViews(int, int);
+  }
+
+  public final class RecyclerView.Recycler {
+    ctor public RecyclerView.Recycler();
+    method public void bindViewToPosition(android.view.View, int);
+    method public void clear();
+    method public int convertPreLayoutPositionToPostLayout(int);
+    method public java.util.List<androidx.recyclerview.widget.RecyclerView.ViewHolder!> getScrapList();
+    method public android.view.View getViewForPosition(int);
+    method public void recycleView(android.view.View);
+    method public void setViewCacheSize(int);
+  }
+
+  public static interface RecyclerView.RecyclerListener {
+    method public void onViewRecycled(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+  }
+
+  public static class RecyclerView.SimpleOnItemTouchListener implements androidx.recyclerview.widget.RecyclerView.OnItemTouchListener {
+    ctor public RecyclerView.SimpleOnItemTouchListener();
+    method public boolean onInterceptTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+    method public void onRequestDisallowInterceptTouchEvent(boolean);
+    method public void onTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+  }
+
+  public abstract static class RecyclerView.SmoothScroller {
+    ctor public RecyclerView.SmoothScroller();
+    method public android.graphics.PointF? computeScrollVectorForPosition(int);
+    method public android.view.View! findViewByPosition(int);
+    method public int getChildCount();
+    method public int getChildPosition(android.view.View!);
+    method public androidx.recyclerview.widget.RecyclerView.LayoutManager? getLayoutManager();
+    method public int getTargetPosition();
+    method @Deprecated public void instantScrollToPosition(int);
+    method public boolean isPendingInitialRun();
+    method public boolean isRunning();
+    method protected void normalize(android.graphics.PointF);
+    method protected void onChildAttachedToWindow(android.view.View!);
+    method protected abstract void onSeekTargetStep(@Px int, @Px int, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action);
+    method protected abstract void onStart();
+    method protected abstract void onStop();
+    method protected abstract void onTargetFound(android.view.View, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action);
+    method public void setTargetPosition(int);
+    method protected final void stop();
+  }
+
+  public static class RecyclerView.SmoothScroller.Action {
+    ctor public RecyclerView.SmoothScroller.Action(@Px int, @Px int);
+    ctor public RecyclerView.SmoothScroller.Action(@Px int, @Px int, int);
+    ctor public RecyclerView.SmoothScroller.Action(@Px int, @Px int, int, android.view.animation.Interpolator?);
+    method public int getDuration();
+    method @Px public int getDx();
+    method @Px public int getDy();
+    method public android.view.animation.Interpolator? getInterpolator();
+    method public void jumpTo(int);
+    method public void setDuration(int);
+    method public void setDx(@Px int);
+    method public void setDy(@Px int);
+    method public void setInterpolator(android.view.animation.Interpolator?);
+    method public void update(@Px int, @Px int, int, android.view.animation.Interpolator?);
+    field public static final int UNDEFINED_DURATION = -2147483648; // 0x80000000
+  }
+
+  public static interface RecyclerView.SmoothScroller.ScrollVectorProvider {
+    method public android.graphics.PointF? computeScrollVectorForPosition(int);
+  }
+
+  public static class RecyclerView.State {
+    ctor public RecyclerView.State();
+    method public boolean didStructureChange();
+    method public <T> T! get(int);
+    method public int getItemCount();
+    method public int getRemainingScrollHorizontal();
+    method public int getRemainingScrollVertical();
+    method public int getTargetScrollPosition();
+    method public boolean hasTargetScrollPosition();
+    method public boolean isMeasuring();
+    method public boolean isPreLayout();
+    method public void put(int, Object!);
+    method public void remove(int);
+    method public boolean willRunPredictiveAnimations();
+    method public boolean willRunSimpleAnimations();
+  }
+
+  public abstract static class RecyclerView.ViewCacheExtension {
+    ctor public RecyclerView.ViewCacheExtension();
+    method public abstract android.view.View? getViewForPositionAndType(androidx.recyclerview.widget.RecyclerView.Recycler, int, int);
+  }
+
+  public abstract static class RecyclerView.ViewHolder {
+    ctor public RecyclerView.ViewHolder(android.view.View);
+    method public final int getAdapterPosition();
+    method public final long getItemId();
+    method public final int getItemViewType();
+    method public final int getLayoutPosition();
+    method public final int getOldPosition();
+    method @Deprecated public final int getPosition();
+    method public final boolean isRecyclable();
+    method public final void setIsRecyclable(boolean);
+    field public final android.view.View itemView;
+  }
+
+  public class RecyclerViewAccessibilityDelegate extends androidx.core.view.AccessibilityDelegateCompat {
+    ctor public RecyclerViewAccessibilityDelegate(androidx.recyclerview.widget.RecyclerView);
+    method public androidx.core.view.AccessibilityDelegateCompat getItemDelegate();
+  }
+
+  public static class RecyclerViewAccessibilityDelegate.ItemDelegate extends androidx.core.view.AccessibilityDelegateCompat {
+    ctor public RecyclerViewAccessibilityDelegate.ItemDelegate(androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate);
+  }
+
+  public abstract class SimpleItemAnimator extends androidx.recyclerview.widget.RecyclerView.ItemAnimator {
+    ctor public SimpleItemAnimator();
+    method public abstract boolean animateAdd(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public boolean animateAppearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder!, androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animateDisappearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?);
+    method public abstract boolean animateMove(androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animatePersistence(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateRemove(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchAddFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchAddStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchChangeFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public final void dispatchChangeStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public final void dispatchMoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchMoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchRemoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchRemoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public boolean getSupportsChangeAnimations();
+    method public void onAddFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onAddStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onChangeFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public void onChangeStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public void onMoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onMoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onRemoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onRemoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void setSupportsChangeAnimations(boolean);
+  }
+
+  public abstract class SnapHelper extends androidx.recyclerview.widget.RecyclerView.OnFlingListener {
+    ctor public SnapHelper();
+    method public void attachToRecyclerView(androidx.recyclerview.widget.RecyclerView?) throws java.lang.IllegalStateException;
+    method public abstract int[]? calculateDistanceToFinalSnap(androidx.recyclerview.widget.RecyclerView.LayoutManager, android.view.View);
+    method public int[]! calculateScrollDistance(int, int);
+    method protected androidx.recyclerview.widget.RecyclerView.SmoothScroller? createScroller(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method @Deprecated protected androidx.recyclerview.widget.LinearSmoothScroller? createSnapScroller(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public abstract android.view.View? findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public abstract int findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int, int);
+    method public boolean onFling(int, int);
+  }
+
+  public class SortedList<T> {
+    ctor public SortedList(Class<T!>, androidx.recyclerview.widget.SortedList.Callback<T!>);
+    ctor public SortedList(Class<T!>, androidx.recyclerview.widget.SortedList.Callback<T!>, int);
+    method public int add(T!);
+    method public void addAll(T![], boolean);
+    method public void addAll(T!...);
+    method public void addAll(java.util.Collection<T!>);
+    method public void beginBatchedUpdates();
+    method public void clear();
+    method public void endBatchedUpdates();
+    method public T! get(int) throws java.lang.IndexOutOfBoundsException;
+    method public int indexOf(T!);
+    method public void recalculatePositionOfItemAt(int);
+    method public boolean remove(T!);
+    method public T! removeItemAt(int);
+    method public void replaceAll(T![], boolean);
+    method public void replaceAll(T!...);
+    method public void replaceAll(java.util.Collection<T!>);
+    method public int size();
+    method public void updateItemAt(int, T!);
+    field public static final int INVALID_POSITION = -1; // 0xffffffff
+  }
+
+  public static class SortedList.BatchedCallback<T2> extends androidx.recyclerview.widget.SortedList.Callback<T2> {
+    ctor public SortedList.BatchedCallback(androidx.recyclerview.widget.SortedList.Callback<T2!>!);
+    method public boolean areContentsTheSame(T2!, T2!);
+    method public boolean areItemsTheSame(T2!, T2!);
+    method public int compare(T2!, T2!);
+    method public void dispatchLastEvent();
+    method public void onChanged(int, int);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public abstract static class SortedList.Callback<T2> implements java.util.Comparator<T2> androidx.recyclerview.widget.ListUpdateCallback {
+    ctor public SortedList.Callback();
+    method public abstract boolean areContentsTheSame(T2!, T2!);
+    method public abstract boolean areItemsTheSame(T2!, T2!);
+    method public abstract int compare(T2!, T2!);
+    method public Object? getChangePayload(T2!, T2!);
+    method public abstract void onChanged(int, int);
+    method public void onChanged(int, int, Object!);
+  }
+
+  public abstract class SortedListAdapterCallback<T2> extends androidx.recyclerview.widget.SortedList.Callback<T2> {
+    ctor public SortedListAdapterCallback(androidx.recyclerview.widget.RecyclerView.Adapter!);
+    method public void onChanged(int, int);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public class StaggeredGridLayoutManager extends androidx.recyclerview.widget.RecyclerView.LayoutManager implements androidx.recyclerview.widget.RecyclerView.SmoothScroller.ScrollVectorProvider {
+    ctor public StaggeredGridLayoutManager(android.content.Context!, android.util.AttributeSet!, int, int);
+    ctor public StaggeredGridLayoutManager(int, int);
+    method public android.graphics.PointF! computeScrollVectorForPosition(int);
+    method public int[]! findFirstCompletelyVisibleItemPositions(int[]!);
+    method public int[]! findFirstVisibleItemPositions(int[]!);
+    method public int[]! findLastCompletelyVisibleItemPositions(int[]!);
+    method public int[]! findLastVisibleItemPositions(int[]!);
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateDefaultLayoutParams();
+    method public int getGapStrategy();
+    method public int getOrientation();
+    method public boolean getReverseLayout();
+    method public int getSpanCount();
+    method public void invalidateSpanAssignments();
+    method public void scrollToPositionWithOffset(int, int);
+    method public void setGapStrategy(int);
+    method public void setOrientation(int);
+    method public void setReverseLayout(boolean);
+    method public void setSpanCount(int);
+    field @Deprecated public static final int GAP_HANDLING_LAZY = 1; // 0x1
+    field public static final int GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS = 2; // 0x2
+    field public static final int GAP_HANDLING_NONE = 0; // 0x0
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public static class StaggeredGridLayoutManager.LayoutParams extends androidx.recyclerview.widget.RecyclerView.LayoutParams {
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public StaggeredGridLayoutManager.LayoutParams(int, int);
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public StaggeredGridLayoutManager.LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public final int getSpanIndex();
+    method public boolean isFullSpan();
+    method public void setFullSpan(boolean);
+    field public static final int INVALID_SPAN_ID = -1; // 0xffffffff
+  }
+
+}
+
diff --git a/recyclerview/recyclerview/api/api_lint.ignore b/recyclerview/recyclerview/api/api_lint.ignore
index 7aa0720a..4579639 100644
--- a/recyclerview/recyclerview/api/api_lint.ignore
+++ b/recyclerview/recyclerview/api/api_lint.ignore
@@ -59,3 +59,703 @@
 
 MethodNameUnits: androidx.recyclerview.widget.OrientationHelper#getTotalSpace():
     Expected method name units to be `Bytes`, was `Space` in `getTotalSpace`
+
+
+MissingNullability: androidx.recyclerview.widget.AdapterListUpdateCallback#onChanged(int, int, Object) parameter #2:
+    Missing nullability on parameter `payload` in method `onChanged`
+MissingNullability: androidx.recyclerview.widget.AsyncDifferConfig.Builder#setBackgroundThreadExecutor(java.util.concurrent.Executor) parameter #0:
+    Missing nullability on parameter `executor` in method `setBackgroundThreadExecutor`
+MissingNullability: androidx.recyclerview.widget.BatchingListUpdateCallback#onChanged(int, int, Object) parameter #2:
+    Missing nullability on parameter `payload` in method `onChanged`
+MissingNullability: androidx.recyclerview.widget.DefaultItemAnimator#animateAdd(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `animateAdd`
+MissingNullability: androidx.recyclerview.widget.DefaultItemAnimator#animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, int, int, int) parameter #0:
+    Missing nullability on parameter `oldHolder` in method `animateChange`
+MissingNullability: androidx.recyclerview.widget.DefaultItemAnimator#animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, int, int, int) parameter #1:
+    Missing nullability on parameter `newHolder` in method `animateChange`
+MissingNullability: androidx.recyclerview.widget.DefaultItemAnimator#animateMove(androidx.recyclerview.widget.RecyclerView.ViewHolder, int, int, int, int) parameter #0:
+    Missing nullability on parameter `holder` in method `animateMove`
+MissingNullability: androidx.recyclerview.widget.DefaultItemAnimator#animateRemove(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `animateRemove`
+MissingNullability: androidx.recyclerview.widget.DefaultItemAnimator#endAnimation(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `item` in method `endAnimation`
+MissingNullability: androidx.recyclerview.widget.DividerItemDecoration#DividerItemDecoration(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `DividerItemDecoration`
+MissingNullability: androidx.recyclerview.widget.DividerItemDecoration#getItemOffsets(android.graphics.Rect, android.view.View, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `outRect` in method `getItemOffsets`
+MissingNullability: androidx.recyclerview.widget.DividerItemDecoration#getItemOffsets(android.graphics.Rect, android.view.View, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `view` in method `getItemOffsets`
+MissingNullability: androidx.recyclerview.widget.DividerItemDecoration#getItemOffsets(android.graphics.Rect, android.view.View, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `parent` in method `getItemOffsets`
+MissingNullability: androidx.recyclerview.widget.DividerItemDecoration#getItemOffsets(android.graphics.Rect, android.view.View, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #3:
+    Missing nullability on parameter `state` in method `getItemOffsets`
+MissingNullability: androidx.recyclerview.widget.DividerItemDecoration#onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `c` in method `onDraw`
+MissingNullability: androidx.recyclerview.widget.DividerItemDecoration#onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `parent` in method `onDraw`
+MissingNullability: androidx.recyclerview.widget.DividerItemDecoration#onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `state` in method `onDraw`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#GridLayoutManager(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `GridLayoutManager`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#GridLayoutManager(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `GridLayoutManager`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#GridLayoutManager(android.content.Context, int) parameter #0:
+    Missing nullability on parameter `context` in method `GridLayoutManager`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#GridLayoutManager(android.content.Context, int, int, boolean) parameter #0:
+    Missing nullability on parameter `context` in method `GridLayoutManager`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#checkLayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams) parameter #0:
+    Missing nullability on parameter `lp` in method `checkLayoutParams`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#computeHorizontalScrollOffset(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `computeHorizontalScrollOffset`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#computeHorizontalScrollRange(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `computeHorizontalScrollRange`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#computeVerticalScrollOffset(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `computeVerticalScrollOffset`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#computeVerticalScrollRange(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `computeVerticalScrollRange`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#generateLayoutParams(android.content.Context, android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#generateLayoutParams(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `c` in method `generateLayoutParams`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#generateLayoutParams(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#generateLayoutParams(android.view.ViewGroup.LayoutParams):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `lp` in method `generateLayoutParams`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#getColumnCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `recycler` in method `getColumnCountForAccessibility`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#getColumnCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `state` in method `getColumnCountForAccessibility`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#getRowCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `recycler` in method `getRowCountForAccessibility`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#getRowCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `state` in method `getRowCountForAccessibility`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#getSpanSizeLookup():
+    Missing nullability on method `getSpanSizeLookup` return
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onFocusSearchFailed(android.view.View, int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State):
+    Missing nullability on method `onFocusSearchFailed` return
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onFocusSearchFailed(android.view.View, int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `focused` in method `onFocusSearchFailed`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onFocusSearchFailed(android.view.View, int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `recycler` in method `onFocusSearchFailed`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onFocusSearchFailed(android.view.View, int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #3:
+    Missing nullability on parameter `state` in method `onFocusSearchFailed`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onInitializeAccessibilityNodeInfoForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #0:
+    Missing nullability on parameter `recycler` in method `onInitializeAccessibilityNodeInfoForItem`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onInitializeAccessibilityNodeInfoForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #1:
+    Missing nullability on parameter `state` in method `onInitializeAccessibilityNodeInfoForItem`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onInitializeAccessibilityNodeInfoForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #2:
+    Missing nullability on parameter `host` in method `onInitializeAccessibilityNodeInfoForItem`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onInitializeAccessibilityNodeInfoForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #3:
+    Missing nullability on parameter `info` in method `onInitializeAccessibilityNodeInfoForItem`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onItemsAdded(androidx.recyclerview.widget.RecyclerView, int, int) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `onItemsAdded`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onItemsChanged(androidx.recyclerview.widget.RecyclerView) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `onItemsChanged`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onItemsMoved(androidx.recyclerview.widget.RecyclerView, int, int, int) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `onItemsMoved`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onItemsRemoved(androidx.recyclerview.widget.RecyclerView, int, int) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `onItemsRemoved`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onItemsUpdated(androidx.recyclerview.widget.RecyclerView, int, int, Object) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `onItemsUpdated`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onItemsUpdated(androidx.recyclerview.widget.RecyclerView, int, int, Object) parameter #3:
+    Missing nullability on parameter `payload` in method `onItemsUpdated`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onLayoutChildren(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `recycler` in method `onLayoutChildren`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onLayoutChildren(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `state` in method `onLayoutChildren`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#onLayoutCompleted(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `onLayoutCompleted`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#scrollHorizontallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `recycler` in method `scrollHorizontallyBy`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#scrollHorizontallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `state` in method `scrollHorizontallyBy`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#scrollVerticallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `recycler` in method `scrollVerticallyBy`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#scrollVerticallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `state` in method `scrollVerticallyBy`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#setMeasuredDimension(android.graphics.Rect, int, int) parameter #0:
+    Missing nullability on parameter `childrenBounds` in method `setMeasuredDimension`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager#setSpanSizeLookup(androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup) parameter #0:
+    Missing nullability on parameter `spanSizeLookup` in method `setSpanSizeLookup`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `c` in method `LayoutParams`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `LayoutParams`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager.LayoutParams#LayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager.LayoutParams#LayoutParams(android.view.ViewGroup.MarginLayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.recyclerview.widget.GridLayoutManager.LayoutParams#LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.recyclerview.widget.ItemTouchHelper#getItemOffsets(android.graphics.Rect, android.view.View, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `outRect` in method `getItemOffsets`
+MissingNullability: androidx.recyclerview.widget.ItemTouchHelper#getItemOffsets(android.graphics.Rect, android.view.View, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `view` in method `getItemOffsets`
+MissingNullability: androidx.recyclerview.widget.ItemTouchHelper#getItemOffsets(android.graphics.Rect, android.view.View, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `parent` in method `getItemOffsets`
+MissingNullability: androidx.recyclerview.widget.ItemTouchHelper#getItemOffsets(android.graphics.Rect, android.view.View, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #3:
+    Missing nullability on parameter `state` in method `getItemOffsets`
+MissingNullability: androidx.recyclerview.widget.ItemTouchHelper#onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `c` in method `onDraw`
+MissingNullability: androidx.recyclerview.widget.ItemTouchHelper#onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `parent` in method `onDraw`
+MissingNullability: androidx.recyclerview.widget.ItemTouchHelper#onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `state` in method `onDraw`
+MissingNullability: androidx.recyclerview.widget.ItemTouchHelper#onDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `c` in method `onDrawOver`
+MissingNullability: androidx.recyclerview.widget.ItemTouchHelper#onDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `parent` in method `onDrawOver`
+MissingNullability: androidx.recyclerview.widget.ItemTouchHelper#onDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `state` in method `onDrawOver`
+MissingNullability: androidx.recyclerview.widget.ItemTouchHelper.Callback#chooseDropTarget(androidx.recyclerview.widget.RecyclerView.ViewHolder, java.util.List<androidx.recyclerview.widget.RecyclerView.ViewHolder>, int, int):
+    Missing nullability on method `chooseDropTarget` return
+MissingNullability: androidx.recyclerview.widget.ItemTouchHelper.Callback#onChildDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, float, float, int, boolean) parameter #2:
+    Missing nullability on parameter `viewHolder` in method `onChildDrawOver`
+MissingNullability: androidx.recyclerview.widget.ItemTouchUIUtil#clearView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `clearView`
+MissingNullability: androidx.recyclerview.widget.ItemTouchUIUtil#onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, android.view.View, float, float, int, boolean) parameter #0:
+    Missing nullability on parameter `c` in method `onDraw`
+MissingNullability: androidx.recyclerview.widget.ItemTouchUIUtil#onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, android.view.View, float, float, int, boolean) parameter #1:
+    Missing nullability on parameter `recyclerView` in method `onDraw`
+MissingNullability: androidx.recyclerview.widget.ItemTouchUIUtil#onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, android.view.View, float, float, int, boolean) parameter #2:
+    Missing nullability on parameter `view` in method `onDraw`
+MissingNullability: androidx.recyclerview.widget.ItemTouchUIUtil#onDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, android.view.View, float, float, int, boolean) parameter #0:
+    Missing nullability on parameter `c` in method `onDrawOver`
+MissingNullability: androidx.recyclerview.widget.ItemTouchUIUtil#onDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, android.view.View, float, float, int, boolean) parameter #1:
+    Missing nullability on parameter `recyclerView` in method `onDrawOver`
+MissingNullability: androidx.recyclerview.widget.ItemTouchUIUtil#onDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, android.view.View, float, float, int, boolean) parameter #2:
+    Missing nullability on parameter `view` in method `onDrawOver`
+MissingNullability: androidx.recyclerview.widget.ItemTouchUIUtil#onSelected(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onSelected`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#LinearLayoutManager(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `LinearLayoutManager`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#LinearLayoutManager(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `LinearLayoutManager`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#LinearLayoutManager(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `LinearLayoutManager`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#LinearLayoutManager(android.content.Context, int, boolean) parameter #0:
+    Missing nullability on parameter `context` in method `LinearLayoutManager`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#assertNotInLayoutOrScroll(String) parameter #0:
+    Missing nullability on parameter `message` in method `assertNotInLayoutOrScroll`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#collectAdjacentPrefetchPositions(int, int, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry) parameter #2:
+    Missing nullability on parameter `state` in method `collectAdjacentPrefetchPositions`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#collectAdjacentPrefetchPositions(int, int, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry) parameter #3:
+    Missing nullability on parameter `layoutPrefetchRegistry` in method `collectAdjacentPrefetchPositions`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#collectInitialPrefetchPositions(int, androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry) parameter #1:
+    Missing nullability on parameter `layoutPrefetchRegistry` in method `collectInitialPrefetchPositions`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#computeHorizontalScrollExtent(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `computeHorizontalScrollExtent`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#computeHorizontalScrollOffset(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `computeHorizontalScrollOffset`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#computeHorizontalScrollRange(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `computeHorizontalScrollRange`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#computeScrollVectorForPosition(int):
+    Missing nullability on method `computeScrollVectorForPosition` return
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#computeVerticalScrollExtent(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `computeVerticalScrollExtent`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#computeVerticalScrollOffset(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `computeVerticalScrollOffset`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#computeVerticalScrollRange(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `computeVerticalScrollRange`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#findViewByPosition(int):
+    Missing nullability on method `findViewByPosition` return
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#getExtraLayoutSpace(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `getExtraLayoutSpace`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.Recycler) parameter #0:
+    Missing nullability on parameter `view` in method `onDetachedFromWindow`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.Recycler) parameter #1:
+    Missing nullability on parameter `recycler` in method `onDetachedFromWindow`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#onFocusSearchFailed(android.view.View, int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State):
+    Missing nullability on method `onFocusSearchFailed` return
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#onFocusSearchFailed(android.view.View, int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `focused` in method `onFocusSearchFailed`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#onFocusSearchFailed(android.view.View, int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `recycler` in method `onFocusSearchFailed`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#onFocusSearchFailed(android.view.View, int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #3:
+    Missing nullability on parameter `state` in method `onFocusSearchFailed`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `event` in method `onInitializeAccessibilityEvent`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#onLayoutChildren(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `recycler` in method `onLayoutChildren`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#onLayoutChildren(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `state` in method `onLayoutChildren`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#onLayoutCompleted(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `onLayoutCompleted`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#scrollHorizontallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `recycler` in method `scrollHorizontallyBy`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#scrollHorizontallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `state` in method `scrollHorizontallyBy`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#scrollVerticallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `recycler` in method `scrollVerticallyBy`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#scrollVerticallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `state` in method `scrollVerticallyBy`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#smoothScrollToPosition(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State, int) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `smoothScrollToPosition`
+MissingNullability: androidx.recyclerview.widget.LinearLayoutManager#smoothScrollToPosition(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State, int) parameter #1:
+    Missing nullability on parameter `state` in method `smoothScrollToPosition`
+MissingNullability: androidx.recyclerview.widget.LinearSmoothScroller#LinearSmoothScroller(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `LinearSmoothScroller`
+MissingNullability: androidx.recyclerview.widget.LinearSmoothScroller#calculateDxToMakeVisible(android.view.View, int) parameter #0:
+    Missing nullability on parameter `view` in method `calculateDxToMakeVisible`
+MissingNullability: androidx.recyclerview.widget.LinearSmoothScroller#calculateDyToMakeVisible(android.view.View, int) parameter #0:
+    Missing nullability on parameter `view` in method `calculateDyToMakeVisible`
+MissingNullability: androidx.recyclerview.widget.LinearSmoothScroller#calculateSpeedPerPixel(android.util.DisplayMetrics) parameter #0:
+    Missing nullability on parameter `displayMetrics` in method `calculateSpeedPerPixel`
+MissingNullability: androidx.recyclerview.widget.LinearSmoothScroller#mDecelerateInterpolator:
+    Missing nullability on field `mDecelerateInterpolator` in class `class androidx.recyclerview.widget.LinearSmoothScroller`
+MissingNullability: androidx.recyclerview.widget.LinearSmoothScroller#mLinearInterpolator:
+    Missing nullability on field `mLinearInterpolator` in class `class androidx.recyclerview.widget.LinearSmoothScroller`
+MissingNullability: androidx.recyclerview.widget.LinearSmoothScroller#mTargetVector:
+    Missing nullability on field `mTargetVector` in class `class androidx.recyclerview.widget.LinearSmoothScroller`
+MissingNullability: androidx.recyclerview.widget.LinearSmoothScroller#onSeekTargetStep(int, int, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action) parameter #2:
+    Missing nullability on parameter `state` in method `onSeekTargetStep`
+MissingNullability: androidx.recyclerview.widget.LinearSmoothScroller#onSeekTargetStep(int, int, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action) parameter #3:
+    Missing nullability on parameter `action` in method `onSeekTargetStep`
+MissingNullability: androidx.recyclerview.widget.LinearSmoothScroller#onTargetFound(android.view.View, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action) parameter #0:
+    Missing nullability on parameter `targetView` in method `onTargetFound`
+MissingNullability: androidx.recyclerview.widget.LinearSmoothScroller#onTargetFound(android.view.View, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action) parameter #1:
+    Missing nullability on parameter `state` in method `onTargetFound`
+MissingNullability: androidx.recyclerview.widget.LinearSmoothScroller#onTargetFound(android.view.View, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action) parameter #2:
+    Missing nullability on parameter `action` in method `onTargetFound`
+MissingNullability: androidx.recyclerview.widget.LinearSmoothScroller#updateActionForInterimTarget(androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action) parameter #0:
+    Missing nullability on parameter `action` in method `updateActionForInterimTarget`
+MissingNullability: androidx.recyclerview.widget.LinearSnapHelper#calculateDistanceToFinalSnap(androidx.recyclerview.widget.RecyclerView.LayoutManager, android.view.View):
+    Missing nullability on method `calculateDistanceToFinalSnap` return
+MissingNullability: androidx.recyclerview.widget.LinearSnapHelper#findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager):
+    Missing nullability on method `findSnapView` return
+MissingNullability: androidx.recyclerview.widget.LinearSnapHelper#findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager) parameter #0:
+    Missing nullability on parameter `layoutManager` in method `findSnapView`
+MissingNullability: androidx.recyclerview.widget.LinearSnapHelper#findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager, int, int) parameter #0:
+    Missing nullability on parameter `layoutManager` in method `findTargetSnapPosition`
+MissingNullability: androidx.recyclerview.widget.OrientationHelper#createHorizontalHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager):
+    Missing nullability on method `createHorizontalHelper` return
+MissingNullability: androidx.recyclerview.widget.OrientationHelper#createHorizontalHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager) parameter #0:
+    Missing nullability on parameter `layoutManager` in method `createHorizontalHelper`
+MissingNullability: androidx.recyclerview.widget.OrientationHelper#createOrientationHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager, int):
+    Missing nullability on method `createOrientationHelper` return
+MissingNullability: androidx.recyclerview.widget.OrientationHelper#createOrientationHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager, int) parameter #0:
+    Missing nullability on parameter `layoutManager` in method `createOrientationHelper`
+MissingNullability: androidx.recyclerview.widget.OrientationHelper#createVerticalHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager):
+    Missing nullability on method `createVerticalHelper` return
+MissingNullability: androidx.recyclerview.widget.OrientationHelper#createVerticalHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager) parameter #0:
+    Missing nullability on parameter `layoutManager` in method `createVerticalHelper`
+MissingNullability: androidx.recyclerview.widget.OrientationHelper#getDecoratedEnd(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getDecoratedEnd`
+MissingNullability: androidx.recyclerview.widget.OrientationHelper#getDecoratedMeasurement(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getDecoratedMeasurement`
+MissingNullability: androidx.recyclerview.widget.OrientationHelper#getDecoratedMeasurementInOther(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getDecoratedMeasurementInOther`
+MissingNullability: androidx.recyclerview.widget.OrientationHelper#getDecoratedStart(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getDecoratedStart`
+MissingNullability: androidx.recyclerview.widget.OrientationHelper#getLayoutManager():
+    Missing nullability on method `getLayoutManager` return
+MissingNullability: androidx.recyclerview.widget.OrientationHelper#getTransformedEndWithDecoration(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getTransformedEndWithDecoration`
+MissingNullability: androidx.recyclerview.widget.OrientationHelper#getTransformedStartWithDecoration(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getTransformedStartWithDecoration`
+MissingNullability: androidx.recyclerview.widget.OrientationHelper#mLayoutManager:
+    Missing nullability on field `mLayoutManager` in class `class androidx.recyclerview.widget.OrientationHelper`
+MissingNullability: androidx.recyclerview.widget.OrientationHelper#offsetChild(android.view.View, int) parameter #0:
+    Missing nullability on parameter `view` in method `offsetChild`
+MissingNullability: androidx.recyclerview.widget.PagerSnapHelper#createSnapScroller(androidx.recyclerview.widget.RecyclerView.LayoutManager):
+    Missing nullability on method `createSnapScroller` return
+MissingNullability: androidx.recyclerview.widget.PagerSnapHelper#createSnapScroller(androidx.recyclerview.widget.RecyclerView.LayoutManager) parameter #0:
+    Missing nullability on parameter `layoutManager` in method `createSnapScroller`
+MissingNullability: androidx.recyclerview.widget.PagerSnapHelper#findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager) parameter #0:
+    Missing nullability on parameter `layoutManager` in method `findSnapView`
+MissingNullability: androidx.recyclerview.widget.PagerSnapHelper#findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager, int, int) parameter #0:
+    Missing nullability on parameter `layoutManager` in method `findTargetSnapPosition`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#addFocusables(java.util.ArrayList<android.view.View>, int, int) parameter #0:
+    Missing nullability on parameter `views` in method `addFocusables`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#checkLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `checkLayoutParams`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#dispatchNestedPreScroll(int, int, int[], int[]) parameter #2:
+    Missing nullability on parameter `consumed` in method `dispatchNestedPreScroll`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#dispatchNestedPreScroll(int, int, int[], int[]) parameter #3:
+    Missing nullability on parameter `offsetInWindow` in method `dispatchNestedPreScroll`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#dispatchNestedPreScroll(int, int, int[], int[], int) parameter #2:
+    Missing nullability on parameter `consumed` in method `dispatchNestedPreScroll`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#dispatchNestedPreScroll(int, int, int[], int[], int) parameter #3:
+    Missing nullability on parameter `offsetInWindow` in method `dispatchNestedPreScroll`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#dispatchNestedScroll(int, int, int, int, int[]) parameter #4:
+    Missing nullability on parameter `offsetInWindow` in method `dispatchNestedScroll`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#dispatchNestedScroll(int, int, int, int, int[], int) parameter #4:
+    Missing nullability on parameter `offsetInWindow` in method `dispatchNestedScroll`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#dispatchNestedScroll(int, int, int, int, int[], int, int[]) parameter #4:
+    Missing nullability on parameter `offsetInWindow` in method `dispatchNestedScroll`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `event` in method `dispatchPopulateAccessibilityEvent`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#dispatchRestoreInstanceState(android.util.SparseArray<android.os.Parcelable>) parameter #0:
+    Missing nullability on parameter `container` in method `dispatchRestoreInstanceState`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#dispatchSaveInstanceState(android.util.SparseArray<android.os.Parcelable>) parameter #0:
+    Missing nullability on parameter `container` in method `dispatchSaveInstanceState`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `c` in method `draw`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#drawChild(android.graphics.Canvas, android.view.View, long) parameter #0:
+    Missing nullability on parameter `canvas` in method `drawChild`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#drawChild(android.graphics.Canvas, android.view.View, long) parameter #1:
+    Missing nullability on parameter `child` in method `drawChild`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#findViewHolderForItemId(long):
+    Missing nullability on method `findViewHolderForItemId` return
+MissingNullability: androidx.recyclerview.widget.RecyclerView#focusSearch(android.view.View, int):
+    Missing nullability on method `focusSearch` return
+MissingNullability: androidx.recyclerview.widget.RecyclerView#focusSearch(android.view.View, int) parameter #0:
+    Missing nullability on parameter `focused` in method `focusSearch`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.recyclerview.widget.RecyclerView#generateLayoutParams(android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.recyclerview.widget.RecyclerView#generateLayoutParams(android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#generateLayoutParams(android.view.ViewGroup.LayoutParams):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.recyclerview.widget.RecyclerView#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `generateLayoutParams`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#getAccessibilityClassName():
+    Missing nullability on method `getAccessibilityClassName` return
+MissingNullability: androidx.recyclerview.widget.RecyclerView#getChildViewHolder(android.view.View):
+    Missing nullability on method `getChildViewHolder` return
+MissingNullability: androidx.recyclerview.widget.RecyclerView#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `c` in method `onDraw`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#onGenericMotionEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `event` in method `onGenericMotionEvent`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `e` in method `onInterceptTouchEvent`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#onRequestFocusInDescendants(int, android.graphics.Rect) parameter #1:
+    Missing nullability on parameter `previouslyFocusedRect` in method `onRequestFocusInDescendants`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.recyclerview.widget.RecyclerView#onTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `e` in method `onTouchEvent`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#removeDetachedView(android.view.View, boolean) parameter #0:
+    Missing nullability on parameter `child` in method `removeDetachedView`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#requestChildFocus(android.view.View, android.view.View) parameter #0:
+    Missing nullability on parameter `child` in method `requestChildFocus`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#requestChildFocus(android.view.View, android.view.View) parameter #1:
+    Missing nullability on parameter `focused` in method `requestChildFocus`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#requestChildRectangleOnScreen(android.view.View, android.graphics.Rect, boolean) parameter #0:
+    Missing nullability on parameter `child` in method `requestChildRectangleOnScreen`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#requestChildRectangleOnScreen(android.view.View, android.graphics.Rect, boolean) parameter #1:
+    Missing nullability on parameter `rect` in method `requestChildRectangleOnScreen`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#sendAccessibilityEventUnchecked(android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `event` in method `sendAccessibilityEventUnchecked`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#setLayoutTransition(android.animation.LayoutTransition) parameter #0:
+    Missing nullability on parameter `transition` in method `setLayoutTransition`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#addDisappearingView(android.view.View) parameter #0:
+    Missing nullability on parameter `child` in method `addDisappearingView`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#addDisappearingView(android.view.View, int) parameter #0:
+    Missing nullability on parameter `child` in method `addDisappearingView`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#addView(android.view.View) parameter #0:
+    Missing nullability on parameter `child` in method `addView`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#addView(android.view.View, int) parameter #0:
+    Missing nullability on parameter `child` in method `addView`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#assertInLayoutOrScroll(String) parameter #0:
+    Missing nullability on parameter `message` in method `assertInLayoutOrScroll`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#assertNotInLayoutOrScroll(String) parameter #0:
+    Missing nullability on parameter `message` in method `assertNotInLayoutOrScroll`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#attachView(android.view.View, int, androidx.recyclerview.widget.RecyclerView.LayoutParams) parameter #2:
+    Missing nullability on parameter `lp` in method `attachView`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#checkLayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams) parameter #0:
+    Missing nullability on parameter `lp` in method `checkLayoutParams`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#collectAdjacentPrefetchPositions(int, int, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry) parameter #2:
+    Missing nullability on parameter `state` in method `collectAdjacentPrefetchPositions`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#collectAdjacentPrefetchPositions(int, int, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry) parameter #3:
+    Missing nullability on parameter `layoutPrefetchRegistry` in method `collectAdjacentPrefetchPositions`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#collectInitialPrefetchPositions(int, androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry) parameter #1:
+    Missing nullability on parameter `layoutPrefetchRegistry` in method `collectInitialPrefetchPositions`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#endAnimation(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `endAnimation`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#generateLayoutParams(android.content.Context, android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#generateLayoutParams(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `c` in method `generateLayoutParams`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#generateLayoutParams(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#generateLayoutParams(android.view.ViewGroup.LayoutParams):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `lp` in method `generateLayoutParams`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#getProperties(android.content.Context, android.util.AttributeSet, int, int):
+    Missing nullability on method `getProperties` return
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#onAttachedToWindow(androidx.recyclerview.widget.RecyclerView) parameter #0:
+    Missing nullability on parameter `view` in method `onAttachedToWindow`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView) parameter #0:
+    Missing nullability on parameter `view` in method `onDetachedFromWindow`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.Recycler) parameter #0:
+    Missing nullability on parameter `view` in method `onDetachedFromWindow`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.Recycler) parameter #1:
+    Missing nullability on parameter `recycler` in method `onDetachedFromWindow`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#onLayoutChildren(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `recycler` in method `onLayoutChildren`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#onLayoutChildren(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `state` in method `onLayoutChildren`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#onLayoutCompleted(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `onLayoutCompleted`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#postOnAnimation(Runnable) parameter #0:
+    Missing nullability on parameter `action` in method `postOnAnimation`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#removeCallbacks(Runnable) parameter #0:
+    Missing nullability on parameter `action` in method `removeCallbacks`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#removeView(android.view.View) parameter #0:
+    Missing nullability on parameter `child` in method `removeView`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#scrollHorizontallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `recycler` in method `scrollHorizontallyBy`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#scrollHorizontallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `state` in method `scrollHorizontallyBy`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#scrollVerticallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `recycler` in method `scrollVerticallyBy`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#scrollVerticallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `state` in method `scrollVerticallyBy`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#setMeasuredDimension(android.graphics.Rect, int, int) parameter #0:
+    Missing nullability on parameter `childrenBounds` in method `setMeasuredDimension`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#smoothScrollToPosition(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State, int) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `smoothScrollToPosition`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#smoothScrollToPosition(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State, int) parameter #1:
+    Missing nullability on parameter `state` in method `smoothScrollToPosition`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutManager#startSmoothScroll(androidx.recyclerview.widget.RecyclerView.SmoothScroller) parameter #0:
+    Missing nullability on parameter `smoothScroller` in method `startSmoothScroll`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `c` in method `LayoutParams`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `LayoutParams`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutParams#LayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutParams#LayoutParams(android.view.ViewGroup.MarginLayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.LayoutParams#LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.RecycledViewPool#putRecycledView(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `scrap` in method `putRecycledView`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.SmoothScroller#findViewByPosition(int):
+    Missing nullability on method `findViewByPosition` return
+MissingNullability: androidx.recyclerview.widget.RecyclerView.SmoothScroller#getChildPosition(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `getChildPosition`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.SmoothScroller#onChildAttachedToWindow(android.view.View) parameter #0:
+    Missing nullability on parameter `child` in method `onChildAttachedToWindow`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.State#put(int, Object) parameter #1:
+    Missing nullability on parameter `data` in method `put`
+MissingNullability: androidx.recyclerview.widget.RecyclerView.State#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.recyclerview.widget.RecyclerView.ViewHolder#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate#onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `host` in method `onInitializeAccessibilityEvent`
+MissingNullability: androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate#onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #1:
+    Missing nullability on parameter `event` in method `onInitializeAccessibilityEvent`
+MissingNullability: androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate#onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #0:
+    Missing nullability on parameter `host` in method `onInitializeAccessibilityNodeInfo`
+MissingNullability: androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate#onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #1:
+    Missing nullability on parameter `info` in method `onInitializeAccessibilityNodeInfo`
+MissingNullability: androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate#performAccessibilityAction(android.view.View, int, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `host` in method `performAccessibilityAction`
+MissingNullability: androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate#performAccessibilityAction(android.view.View, int, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `args` in method `performAccessibilityAction`
+MissingNullability: androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate.ItemDelegate#onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #0:
+    Missing nullability on parameter `host` in method `onInitializeAccessibilityNodeInfo`
+MissingNullability: androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate.ItemDelegate#onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #1:
+    Missing nullability on parameter `info` in method `onInitializeAccessibilityNodeInfo`
+MissingNullability: androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate.ItemDelegate#performAccessibilityAction(android.view.View, int, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `host` in method `performAccessibilityAction`
+MissingNullability: androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate.ItemDelegate#performAccessibilityAction(android.view.View, int, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `args` in method `performAccessibilityAction`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#animateAdd(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `animateAdd`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, int, int, int) parameter #0:
+    Missing nullability on parameter `oldHolder` in method `animateChange`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, int, int, int) parameter #1:
+    Missing nullability on parameter `newHolder` in method `animateChange`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#animateMove(androidx.recyclerview.widget.RecyclerView.ViewHolder, int, int, int, int) parameter #0:
+    Missing nullability on parameter `holder` in method `animateMove`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#animateRemove(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `holder` in method `animateRemove`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#dispatchAddFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `item` in method `dispatchAddFinished`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#dispatchAddStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `item` in method `dispatchAddStarting`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#dispatchChangeFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `item` in method `dispatchChangeFinished`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#dispatchChangeStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `item` in method `dispatchChangeStarting`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#dispatchMoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `item` in method `dispatchMoveFinished`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#dispatchMoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `item` in method `dispatchMoveStarting`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#dispatchRemoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `item` in method `dispatchRemoveFinished`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#dispatchRemoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `item` in method `dispatchRemoveStarting`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#onAddFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `item` in method `onAddFinished`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#onAddStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `item` in method `onAddStarting`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#onChangeFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `item` in method `onChangeFinished`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#onChangeStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder, boolean) parameter #0:
+    Missing nullability on parameter `item` in method `onChangeStarting`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#onMoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `item` in method `onMoveFinished`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#onMoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `item` in method `onMoveStarting`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#onRemoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `item` in method `onRemoveFinished`
+MissingNullability: androidx.recyclerview.widget.SimpleItemAnimator#onRemoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder) parameter #0:
+    Missing nullability on parameter `item` in method `onRemoveStarting`
+MissingNullability: androidx.recyclerview.widget.SnapHelper#calculateScrollDistance(int, int):
+    Missing nullability on method `calculateScrollDistance` return
+MissingNullability: androidx.recyclerview.widget.SnapHelper#createScroller(androidx.recyclerview.widget.RecyclerView.LayoutManager) parameter #0:
+    Missing nullability on parameter `layoutManager` in method `createScroller`
+MissingNullability: androidx.recyclerview.widget.SnapHelper#createSnapScroller(androidx.recyclerview.widget.RecyclerView.LayoutManager) parameter #0:
+    Missing nullability on parameter `layoutManager` in method `createSnapScroller`
+MissingNullability: androidx.recyclerview.widget.SnapHelper#findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager) parameter #0:
+    Missing nullability on parameter `layoutManager` in method `findSnapView`
+MissingNullability: androidx.recyclerview.widget.SnapHelper#findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager, int, int) parameter #0:
+    Missing nullability on parameter `layoutManager` in method `findTargetSnapPosition`
+MissingNullability: androidx.recyclerview.widget.SortedList.BatchedCallback#BatchedCallback(androidx.recyclerview.widget.SortedList.Callback<T2>) parameter #0:
+    Missing nullability on parameter `wrappedCallback` in method `BatchedCallback`
+MissingNullability: androidx.recyclerview.widget.SortedList.BatchedCallback#onChanged(int, int, Object) parameter #2:
+    Missing nullability on parameter `payload` in method `onChanged`
+MissingNullability: androidx.recyclerview.widget.SortedList.Callback#onChanged(int, int, Object) parameter #2:
+    Missing nullability on parameter `payload` in method `onChanged`
+MissingNullability: androidx.recyclerview.widget.SortedListAdapterCallback#SortedListAdapterCallback(androidx.recyclerview.widget.RecyclerView.Adapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `SortedListAdapterCallback`
+MissingNullability: androidx.recyclerview.widget.SortedListAdapterCallback#onChanged(int, int, Object) parameter #2:
+    Missing nullability on parameter `payload` in method `onChanged`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#StaggeredGridLayoutManager(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `StaggeredGridLayoutManager`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#StaggeredGridLayoutManager(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `StaggeredGridLayoutManager`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#assertNotInLayoutOrScroll(String) parameter #0:
+    Missing nullability on parameter `message` in method `assertNotInLayoutOrScroll`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#checkLayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams) parameter #0:
+    Missing nullability on parameter `lp` in method `checkLayoutParams`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#computeHorizontalScrollExtent(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `computeHorizontalScrollExtent`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#computeHorizontalScrollOffset(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `computeHorizontalScrollOffset`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#computeHorizontalScrollRange(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `computeHorizontalScrollRange`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#computeScrollVectorForPosition(int):
+    Missing nullability on method `computeScrollVectorForPosition` return
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#computeVerticalScrollExtent(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `computeVerticalScrollExtent`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#computeVerticalScrollOffset(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `computeVerticalScrollOffset`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#computeVerticalScrollRange(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `computeVerticalScrollRange`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#findFirstCompletelyVisibleItemPositions(int[]):
+    Missing nullability on method `findFirstCompletelyVisibleItemPositions` return
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#findFirstCompletelyVisibleItemPositions(int[]) parameter #0:
+    Missing nullability on parameter `into` in method `findFirstCompletelyVisibleItemPositions`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#findFirstVisibleItemPositions(int[]):
+    Missing nullability on method `findFirstVisibleItemPositions` return
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#findFirstVisibleItemPositions(int[]) parameter #0:
+    Missing nullability on parameter `into` in method `findFirstVisibleItemPositions`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#findLastCompletelyVisibleItemPositions(int[]):
+    Missing nullability on method `findLastCompletelyVisibleItemPositions` return
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#findLastCompletelyVisibleItemPositions(int[]) parameter #0:
+    Missing nullability on parameter `into` in method `findLastCompletelyVisibleItemPositions`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#findLastVisibleItemPositions(int[]):
+    Missing nullability on method `findLastVisibleItemPositions` return
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#findLastVisibleItemPositions(int[]) parameter #0:
+    Missing nullability on parameter `into` in method `findLastVisibleItemPositions`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#generateLayoutParams(android.content.Context, android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#generateLayoutParams(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `c` in method `generateLayoutParams`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#generateLayoutParams(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#generateLayoutParams(android.view.ViewGroup.LayoutParams):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `lp` in method `generateLayoutParams`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#getColumnCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `recycler` in method `getColumnCountForAccessibility`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#getColumnCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `state` in method `getColumnCountForAccessibility`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#getRowCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `recycler` in method `getRowCountForAccessibility`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#getRowCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `state` in method `getRowCountForAccessibility`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.Recycler) parameter #0:
+    Missing nullability on parameter `view` in method `onDetachedFromWindow`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.Recycler) parameter #1:
+    Missing nullability on parameter `recycler` in method `onDetachedFromWindow`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onFocusSearchFailed(android.view.View, int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `focused` in method `onFocusSearchFailed`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onFocusSearchFailed(android.view.View, int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `recycler` in method `onFocusSearchFailed`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onFocusSearchFailed(android.view.View, int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #3:
+    Missing nullability on parameter `state` in method `onFocusSearchFailed`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `event` in method `onInitializeAccessibilityEvent`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onInitializeAccessibilityNodeInfoForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #0:
+    Missing nullability on parameter `recycler` in method `onInitializeAccessibilityNodeInfoForItem`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onInitializeAccessibilityNodeInfoForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #1:
+    Missing nullability on parameter `state` in method `onInitializeAccessibilityNodeInfoForItem`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onInitializeAccessibilityNodeInfoForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #2:
+    Missing nullability on parameter `host` in method `onInitializeAccessibilityNodeInfoForItem`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onInitializeAccessibilityNodeInfoForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat) parameter #3:
+    Missing nullability on parameter `info` in method `onInitializeAccessibilityNodeInfoForItem`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onItemsAdded(androidx.recyclerview.widget.RecyclerView, int, int) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `onItemsAdded`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onItemsChanged(androidx.recyclerview.widget.RecyclerView) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `onItemsChanged`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onItemsMoved(androidx.recyclerview.widget.RecyclerView, int, int, int) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `onItemsMoved`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onItemsRemoved(androidx.recyclerview.widget.RecyclerView, int, int) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `onItemsRemoved`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onItemsUpdated(androidx.recyclerview.widget.RecyclerView, int, int, Object) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `onItemsUpdated`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onItemsUpdated(androidx.recyclerview.widget.RecyclerView, int, int, Object) parameter #3:
+    Missing nullability on parameter `payload` in method `onItemsUpdated`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onLayoutChildren(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `recycler` in method `onLayoutChildren`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onLayoutChildren(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `state` in method `onLayoutChildren`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onLayoutCompleted(androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `state` in method `onLayoutCompleted`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#scrollHorizontallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `recycler` in method `scrollHorizontallyBy`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#scrollHorizontallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `state` in method `scrollHorizontallyBy`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#scrollVerticallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `recycler` in method `scrollVerticallyBy`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#scrollVerticallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `state` in method `scrollVerticallyBy`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#setMeasuredDimension(android.graphics.Rect, int, int) parameter #0:
+    Missing nullability on parameter `childrenBounds` in method `setMeasuredDimension`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#smoothScrollToPosition(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State, int) parameter #0:
+    Missing nullability on parameter `recyclerView` in method `smoothScrollToPosition`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager#smoothScrollToPosition(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State, int) parameter #1:
+    Missing nullability on parameter `state` in method `smoothScrollToPosition`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `c` in method `LayoutParams`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `LayoutParams`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager.LayoutParams#LayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager.LayoutParams#LayoutParams(android.view.ViewGroup.MarginLayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
+MissingNullability: androidx.recyclerview.widget.StaggeredGridLayoutManager.LayoutParams#LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams) parameter #0:
+    Missing nullability on parameter `source` in method `LayoutParams`
diff --git a/recyclerview/recyclerview/api/res-1.1.0-beta03.txt b/recyclerview/recyclerview/api/res-1.1.0-beta03.txt
new file mode 100644
index 0000000..475bfc43
--- /dev/null
+++ b/recyclerview/recyclerview/api/res-1.1.0-beta03.txt
@@ -0,0 +1,9 @@
+attr fastScrollEnabled
+attr fastScrollHorizontalThumbDrawable
+attr fastScrollHorizontalTrackDrawable
+attr fastScrollVerticalThumbDrawable
+attr fastScrollVerticalTrackDrawable
+attr layoutManager
+attr reverseLayout
+attr spanCount
+attr stackFromEnd
diff --git a/recyclerview/recyclerview/api/restricted_1.1.0-beta03.txt b/recyclerview/recyclerview/api/restricted_1.1.0-beta03.txt
new file mode 100644
index 0000000..0690168
--- /dev/null
+++ b/recyclerview/recyclerview/api/restricted_1.1.0-beta03.txt
@@ -0,0 +1,1043 @@
+// Signature format: 3.0
+package androidx.recyclerview.widget {
+
+  public final class AdapterListUpdateCallback implements androidx.recyclerview.widget.ListUpdateCallback {
+    ctor public AdapterListUpdateCallback(androidx.recyclerview.widget.RecyclerView.Adapter);
+    method public void onChanged(int, int, Object!);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public final class AsyncDifferConfig<T> {
+    method public java.util.concurrent.Executor getBackgroundThreadExecutor();
+    method public androidx.recyclerview.widget.DiffUtil.ItemCallback<T!> getDiffCallback();
+  }
+
+  public static final class AsyncDifferConfig.Builder<T> {
+    ctor public AsyncDifferConfig.Builder(androidx.recyclerview.widget.DiffUtil.ItemCallback<T!>);
+    method public androidx.recyclerview.widget.AsyncDifferConfig<T!> build();
+    method public androidx.recyclerview.widget.AsyncDifferConfig.Builder<T!> setBackgroundThreadExecutor(java.util.concurrent.Executor!);
+  }
+
+  public class AsyncListDiffer<T> {
+    ctor public AsyncListDiffer(androidx.recyclerview.widget.RecyclerView.Adapter, androidx.recyclerview.widget.DiffUtil.ItemCallback<T!>);
+    ctor public AsyncListDiffer(androidx.recyclerview.widget.ListUpdateCallback, androidx.recyclerview.widget.AsyncDifferConfig<T!>);
+    method public void addListListener(androidx.recyclerview.widget.AsyncListDiffer.ListListener<T!>);
+    method public java.util.List<T!> getCurrentList();
+    method public void removeListListener(androidx.recyclerview.widget.AsyncListDiffer.ListListener<T!>);
+    method public void submitList(java.util.List<T!>?);
+    method public void submitList(java.util.List<T!>?, Runnable?);
+  }
+
+  public static interface AsyncListDiffer.ListListener<T> {
+    method public void onCurrentListChanged(java.util.List<T!>, java.util.List<T!>);
+  }
+
+  public class AsyncListUtil<T> {
+    ctor public AsyncListUtil(Class<T!>, int, androidx.recyclerview.widget.AsyncListUtil.DataCallback<T!>, androidx.recyclerview.widget.AsyncListUtil.ViewCallback);
+    method public T? getItem(int);
+    method public int getItemCount();
+    method public void onRangeChanged();
+    method public void refresh();
+  }
+
+  public abstract static class AsyncListUtil.DataCallback<T> {
+    ctor public AsyncListUtil.DataCallback();
+    method @WorkerThread public abstract void fillData(T![], int, int);
+    method @WorkerThread public int getMaxCachedTiles();
+    method @WorkerThread public void recycleData(T![], int);
+    method @WorkerThread public abstract int refreshData();
+  }
+
+  public abstract static class AsyncListUtil.ViewCallback {
+    ctor public AsyncListUtil.ViewCallback();
+    method @UiThread public void extendRangeInto(int[], int[], int);
+    method @UiThread public abstract void getItemRangeInto(int[]);
+    method @UiThread public abstract void onDataRefresh();
+    method @UiThread public abstract void onItemLoaded(int);
+    field public static final int HINT_SCROLL_ASC = 2; // 0x2
+    field public static final int HINT_SCROLL_DESC = 1; // 0x1
+    field public static final int HINT_SCROLL_NONE = 0; // 0x0
+  }
+
+  public class BatchingListUpdateCallback implements androidx.recyclerview.widget.ListUpdateCallback {
+    ctor public BatchingListUpdateCallback(androidx.recyclerview.widget.ListUpdateCallback);
+    method public void dispatchLastEvent();
+    method public void onChanged(int, int, Object!);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public class DefaultItemAnimator extends androidx.recyclerview.widget.SimpleItemAnimator {
+    ctor public DefaultItemAnimator();
+    method public boolean animateAdd(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder!, androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animateMove(androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animateRemove(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void endAnimation(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void endAnimations();
+    method public boolean isRunning();
+    method public void runPendingAnimations();
+  }
+
+  public class DiffUtil {
+    method public static androidx.recyclerview.widget.DiffUtil.DiffResult calculateDiff(androidx.recyclerview.widget.DiffUtil.Callback);
+    method public static androidx.recyclerview.widget.DiffUtil.DiffResult calculateDiff(androidx.recyclerview.widget.DiffUtil.Callback, boolean);
+  }
+
+  public abstract static class DiffUtil.Callback {
+    ctor public DiffUtil.Callback();
+    method public abstract boolean areContentsTheSame(int, int);
+    method public abstract boolean areItemsTheSame(int, int);
+    method public Object? getChangePayload(int, int);
+    method public abstract int getNewListSize();
+    method public abstract int getOldListSize();
+  }
+
+  public static class DiffUtil.DiffResult {
+    method public int convertNewPositionToOld(@IntRange(from=0) int);
+    method public int convertOldPositionToNew(@IntRange(from=0) int);
+    method public void dispatchUpdatesTo(androidx.recyclerview.widget.RecyclerView.Adapter);
+    method public void dispatchUpdatesTo(androidx.recyclerview.widget.ListUpdateCallback);
+    field public static final int NO_POSITION = -1; // 0xffffffff
+  }
+
+  public abstract static class DiffUtil.ItemCallback<T> {
+    ctor public DiffUtil.ItemCallback();
+    method public abstract boolean areContentsTheSame(T, T);
+    method public abstract boolean areItemsTheSame(T, T);
+    method public Object? getChangePayload(T, T);
+  }
+
+  public class DividerItemDecoration extends androidx.recyclerview.widget.RecyclerView.ItemDecoration {
+    ctor public DividerItemDecoration(android.content.Context!, int);
+    method public android.graphics.drawable.Drawable? getDrawable();
+    method public void setDrawable(android.graphics.drawable.Drawable);
+    method public void setOrientation(int);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public class GridLayoutManager extends androidx.recyclerview.widget.LinearLayoutManager {
+    ctor public GridLayoutManager(android.content.Context!, android.util.AttributeSet!, int, int);
+    ctor public GridLayoutManager(android.content.Context!, int);
+    ctor public GridLayoutManager(android.content.Context!, int, @androidx.recyclerview.widget.RecyclerView.Orientation int, boolean);
+    method public int getSpanCount();
+    method public androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup! getSpanSizeLookup();
+    method public boolean isUsingSpansToEstimateScrollbarDimensions();
+    method public void setSpanCount(int);
+    method public void setSpanSizeLookup(androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup!);
+    method public void setUsingSpansToEstimateScrollbarDimensions(boolean);
+    field public static final int DEFAULT_SPAN_COUNT = -1; // 0xffffffff
+  }
+
+  public static final class GridLayoutManager.DefaultSpanSizeLookup extends androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup {
+    ctor public GridLayoutManager.DefaultSpanSizeLookup();
+    method public int getSpanSize(int);
+  }
+
+  public static class GridLayoutManager.LayoutParams extends androidx.recyclerview.widget.RecyclerView.LayoutParams {
+    ctor public GridLayoutManager.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public GridLayoutManager.LayoutParams(int, int);
+    ctor public GridLayoutManager.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public GridLayoutManager.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public GridLayoutManager.LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public int getSpanIndex();
+    method public int getSpanSize();
+    field public static final int INVALID_SPAN_ID = -1; // 0xffffffff
+  }
+
+  public abstract static class GridLayoutManager.SpanSizeLookup {
+    ctor public GridLayoutManager.SpanSizeLookup();
+    method public int getSpanGroupIndex(int, int);
+    method public int getSpanIndex(int, int);
+    method public abstract int getSpanSize(int);
+    method public void invalidateSpanGroupIndexCache();
+    method public void invalidateSpanIndexCache();
+    method public boolean isSpanGroupIndexCacheEnabled();
+    method public boolean isSpanIndexCacheEnabled();
+    method public void setSpanGroupIndexCacheEnabled(boolean);
+    method public void setSpanIndexCacheEnabled(boolean);
+  }
+
+  public class ItemTouchHelper extends androidx.recyclerview.widget.RecyclerView.ItemDecoration implements androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener {
+    ctor public ItemTouchHelper(androidx.recyclerview.widget.ItemTouchHelper.Callback);
+    method public void attachToRecyclerView(androidx.recyclerview.widget.RecyclerView?);
+    method public void onChildViewAttachedToWindow(android.view.View);
+    method public void onChildViewDetachedFromWindow(android.view.View);
+    method public void startDrag(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void startSwipe(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    field public static final int ACTION_STATE_DRAG = 2; // 0x2
+    field public static final int ACTION_STATE_IDLE = 0; // 0x0
+    field public static final int ACTION_STATE_SWIPE = 1; // 0x1
+    field public static final int ANIMATION_TYPE_DRAG = 8; // 0x8
+    field public static final int ANIMATION_TYPE_SWIPE_CANCEL = 4; // 0x4
+    field public static final int ANIMATION_TYPE_SWIPE_SUCCESS = 2; // 0x2
+    field public static final int DOWN = 2; // 0x2
+    field public static final int END = 32; // 0x20
+    field public static final int LEFT = 4; // 0x4
+    field public static final int RIGHT = 8; // 0x8
+    field public static final int START = 16; // 0x10
+    field public static final int UP = 1; // 0x1
+  }
+
+  public abstract static class ItemTouchHelper.Callback {
+    ctor public ItemTouchHelper.Callback();
+    method public boolean canDropOver(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder! chooseDropTarget(androidx.recyclerview.widget.RecyclerView.ViewHolder, java.util.List<androidx.recyclerview.widget.RecyclerView.ViewHolder!>, int, int);
+    method public void clearView(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public int convertToAbsoluteDirection(int, int);
+    method public static int convertToRelativeDirection(int, int);
+    method public long getAnimationDuration(androidx.recyclerview.widget.RecyclerView, int, float, float);
+    method public int getBoundingBoxMargin();
+    method public static androidx.recyclerview.widget.ItemTouchUIUtil getDefaultUIUtil();
+    method public float getMoveThreshold(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public abstract int getMovementFlags(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public float getSwipeEscapeVelocity(float);
+    method public float getSwipeThreshold(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public float getSwipeVelocityThreshold(float);
+    method public int interpolateOutOfBoundsScroll(androidx.recyclerview.widget.RecyclerView, int, int, int, long);
+    method public boolean isItemViewSwipeEnabled();
+    method public boolean isLongPressDragEnabled();
+    method public static int makeFlag(int, int);
+    method public static int makeMovementFlags(int, int);
+    method public void onChildDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, float, float, int, boolean);
+    method public void onChildDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder!, float, float, int, boolean);
+    method public abstract boolean onMove(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onMoved(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, int, int);
+    method public void onSelectedChanged(androidx.recyclerview.widget.RecyclerView.ViewHolder?, int);
+    method public abstract void onSwiped(androidx.recyclerview.widget.RecyclerView.ViewHolder, int);
+    field public static final int DEFAULT_DRAG_ANIMATION_DURATION = 200; // 0xc8
+    field public static final int DEFAULT_SWIPE_ANIMATION_DURATION = 250; // 0xfa
+  }
+
+  public abstract static class ItemTouchHelper.SimpleCallback extends androidx.recyclerview.widget.ItemTouchHelper.Callback {
+    ctor public ItemTouchHelper.SimpleCallback(int, int);
+    method public int getDragDirs(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public int getMovementFlags(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public int getSwipeDirs(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void setDefaultDragDirs(int);
+    method public void setDefaultSwipeDirs(int);
+  }
+
+  public static interface ItemTouchHelper.ViewDropHandler {
+    method public void prepareForDrop(android.view.View, android.view.View, int, int);
+  }
+
+  public interface ItemTouchUIUtil {
+    method public void clearView(android.view.View!);
+    method public void onDraw(android.graphics.Canvas!, androidx.recyclerview.widget.RecyclerView!, android.view.View!, float, float, int, boolean);
+    method public void onDrawOver(android.graphics.Canvas!, androidx.recyclerview.widget.RecyclerView!, android.view.View!, float, float, int, boolean);
+    method public void onSelected(android.view.View!);
+  }
+
+  public class LinearLayoutManager extends androidx.recyclerview.widget.RecyclerView.LayoutManager implements androidx.recyclerview.widget.ItemTouchHelper.ViewDropHandler androidx.recyclerview.widget.RecyclerView.SmoothScroller.ScrollVectorProvider {
+    ctor public LinearLayoutManager(android.content.Context!);
+    ctor public LinearLayoutManager(android.content.Context!, @androidx.recyclerview.widget.RecyclerView.Orientation int, boolean);
+    ctor public LinearLayoutManager(android.content.Context!, android.util.AttributeSet!, int, int);
+    method protected void calculateExtraLayoutSpace(androidx.recyclerview.widget.RecyclerView.State, int[]);
+    method public android.graphics.PointF! computeScrollVectorForPosition(int);
+    method public int findFirstCompletelyVisibleItemPosition();
+    method public int findFirstVisibleItemPosition();
+    method public int findLastCompletelyVisibleItemPosition();
+    method public int findLastVisibleItemPosition();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateDefaultLayoutParams();
+    method @Deprecated protected int getExtraLayoutSpace(androidx.recyclerview.widget.RecyclerView.State!);
+    method public int getInitialPrefetchItemCount();
+    method @androidx.recyclerview.widget.RecyclerView.Orientation public int getOrientation();
+    method public boolean getRecycleChildrenOnDetach();
+    method public boolean getReverseLayout();
+    method public boolean getStackFromEnd();
+    method protected boolean isLayoutRTL();
+    method public boolean isSmoothScrollbarEnabled();
+    method public void prepareForDrop(android.view.View, android.view.View, int, int);
+    method public void scrollToPositionWithOffset(int, int);
+    method public void setInitialPrefetchItemCount(int);
+    method public void setOrientation(@androidx.recyclerview.widget.RecyclerView.Orientation int);
+    method public void setRecycleChildrenOnDetach(boolean);
+    method public void setReverseLayout(boolean);
+    method public void setSmoothScrollbarEnabled(boolean);
+    method public void setStackFromEnd(boolean);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int INVALID_OFFSET = -2147483648; // 0x80000000
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  protected static class LinearLayoutManager.LayoutChunkResult {
+    ctor protected LinearLayoutManager.LayoutChunkResult();
+    field public int mConsumed;
+    field public boolean mFinished;
+    field public boolean mFocusable;
+    field public boolean mIgnoreConsumed;
+  }
+
+
+  public class LinearSmoothScroller extends androidx.recyclerview.widget.RecyclerView.SmoothScroller {
+    ctor public LinearSmoothScroller(android.content.Context!);
+    method public int calculateDtToFit(int, int, int, int, int);
+    method public int calculateDxToMakeVisible(android.view.View!, int);
+    method public int calculateDyToMakeVisible(android.view.View!, int);
+    method protected float calculateSpeedPerPixel(android.util.DisplayMetrics!);
+    method protected int calculateTimeForDeceleration(int);
+    method protected int calculateTimeForScrolling(int);
+    method protected int getHorizontalSnapPreference();
+    method protected int getVerticalSnapPreference();
+    method protected void onSeekTargetStep(int, int, androidx.recyclerview.widget.RecyclerView.State!, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action!);
+    method protected void onStart();
+    method protected void onStop();
+    method protected void onTargetFound(android.view.View!, androidx.recyclerview.widget.RecyclerView.State!, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action!);
+    method protected void updateActionForInterimTarget(androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action!);
+    field public static final int SNAP_TO_ANY = 0; // 0x0
+    field public static final int SNAP_TO_END = 1; // 0x1
+    field public static final int SNAP_TO_START = -1; // 0xffffffff
+    field protected final android.view.animation.DecelerateInterpolator! mDecelerateInterpolator;
+    field protected int mInterimTargetDx;
+    field protected int mInterimTargetDy;
+    field protected final android.view.animation.LinearInterpolator! mLinearInterpolator;
+    field protected android.graphics.PointF! mTargetVector;
+  }
+
+  public class LinearSnapHelper extends androidx.recyclerview.widget.SnapHelper {
+    ctor public LinearSnapHelper();
+    method public int[]! calculateDistanceToFinalSnap(androidx.recyclerview.widget.RecyclerView.LayoutManager, android.view.View);
+    method public android.view.View! findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public int findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int, int);
+  }
+
+  public abstract class ListAdapter<T, VH extends androidx.recyclerview.widget.RecyclerView.ViewHolder> extends androidx.recyclerview.widget.RecyclerView.Adapter<VH> {
+    ctor protected ListAdapter(androidx.recyclerview.widget.DiffUtil.ItemCallback<T!>);
+    ctor protected ListAdapter(androidx.recyclerview.widget.AsyncDifferConfig<T!>);
+    method public java.util.List<T!> getCurrentList();
+    method protected T! getItem(int);
+    method public int getItemCount();
+    method public void onCurrentListChanged(java.util.List<T!>, java.util.List<T!>);
+    method public void submitList(java.util.List<T!>?);
+    method public void submitList(java.util.List<T!>?, Runnable?);
+  }
+
+  public interface ListUpdateCallback {
+    method public void onChanged(int, int, Object?);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public abstract class OrientationHelper {
+    method public static androidx.recyclerview.widget.OrientationHelper! createHorizontalHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public static androidx.recyclerview.widget.OrientationHelper! createOrientationHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager!, @androidx.recyclerview.widget.RecyclerView.Orientation int);
+    method public static androidx.recyclerview.widget.OrientationHelper! createVerticalHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public abstract int getDecoratedEnd(android.view.View!);
+    method public abstract int getDecoratedMeasurement(android.view.View!);
+    method public abstract int getDecoratedMeasurementInOther(android.view.View!);
+    method public abstract int getDecoratedStart(android.view.View!);
+    method public abstract int getEnd();
+    method public abstract int getEndAfterPadding();
+    method public abstract int getEndPadding();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutManager! getLayoutManager();
+    method public abstract int getMode();
+    method public abstract int getModeInOther();
+    method public abstract int getStartAfterPadding();
+    method public abstract int getTotalSpace();
+    method public int getTotalSpaceChange();
+    method public abstract int getTransformedEndWithDecoration(android.view.View!);
+    method public abstract int getTransformedStartWithDecoration(android.view.View!);
+    method public abstract void offsetChild(android.view.View!, int);
+    method public abstract void offsetChildren(int);
+    method public void onLayoutComplete();
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+    field protected final androidx.recyclerview.widget.RecyclerView.LayoutManager! mLayoutManager;
+  }
+
+  public class PagerSnapHelper extends androidx.recyclerview.widget.SnapHelper {
+    ctor public PagerSnapHelper();
+    method public int[]? calculateDistanceToFinalSnap(androidx.recyclerview.widget.RecyclerView.LayoutManager, android.view.View);
+    method protected androidx.recyclerview.widget.LinearSmoothScroller! createSnapScroller(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public android.view.View? findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public int findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int, int);
+  }
+
+  public class RecyclerView extends android.view.ViewGroup implements androidx.core.view.NestedScrollingChild2 androidx.core.view.NestedScrollingChild3 androidx.core.view.ScrollingView {
+    ctor public RecyclerView(android.content.Context);
+    ctor public RecyclerView(android.content.Context, android.util.AttributeSet?);
+    ctor public RecyclerView(android.content.Context, android.util.AttributeSet?, int);
+    method public void addItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration, int);
+    method public void addItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration);
+    method public void addOnChildAttachStateChangeListener(androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener);
+    method public void addOnItemTouchListener(androidx.recyclerview.widget.RecyclerView.OnItemTouchListener);
+    method public void addOnScrollListener(androidx.recyclerview.widget.RecyclerView.OnScrollListener);
+    method public void clearOnChildAttachStateChangeListeners();
+    method public void clearOnScrollListeners();
+    method public int computeHorizontalScrollExtent();
+    method public int computeHorizontalScrollOffset();
+    method public int computeHorizontalScrollRange();
+    method public int computeVerticalScrollExtent();
+    method public int computeVerticalScrollOffset();
+    method public int computeVerticalScrollRange();
+    method public boolean dispatchNestedPreScroll(int, int, int[]!, int[]!, int);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]!, int);
+    method public final void dispatchNestedScroll(int, int, int, int, int[]!, int, int[]);
+    method public boolean drawChild(android.graphics.Canvas!, android.view.View!, long);
+    method public android.view.View? findChildViewUnder(float, float);
+    method public android.view.View? findContainingItemView(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? findContainingViewHolder(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? findViewHolderForAdapterPosition(int);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder! findViewHolderForItemId(long);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? findViewHolderForLayoutPosition(int);
+    method @Deprecated public androidx.recyclerview.widget.RecyclerView.ViewHolder? findViewHolderForPosition(int);
+    method public boolean fling(int, int);
+    method public androidx.recyclerview.widget.RecyclerView.Adapter? getAdapter();
+    method public int getChildAdapterPosition(android.view.View);
+    method public long getChildItemId(android.view.View);
+    method public int getChildLayoutPosition(android.view.View);
+    method @Deprecated public int getChildPosition(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder! getChildViewHolder(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate? getCompatAccessibilityDelegate();
+    method public void getDecoratedBoundsWithMargins(android.view.View, android.graphics.Rect);
+    method public androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory getEdgeEffectFactory();
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator? getItemAnimator();
+    method public androidx.recyclerview.widget.RecyclerView.ItemDecoration getItemDecorationAt(int);
+    method public int getItemDecorationCount();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutManager? getLayoutManager();
+    method public int getMaxFlingVelocity();
+    method public int getMinFlingVelocity();
+    method public androidx.recyclerview.widget.RecyclerView.OnFlingListener? getOnFlingListener();
+    method public boolean getPreserveFocusAfterLayout();
+    method public androidx.recyclerview.widget.RecyclerView.RecycledViewPool getRecycledViewPool();
+    method public int getScrollState();
+    method public boolean hasFixedSize();
+    method public boolean hasNestedScrollingParent(int);
+    method public boolean hasPendingAdapterUpdates();
+    method public void invalidateItemDecorations();
+    method public boolean isAnimating();
+    method public boolean isComputingLayout();
+    method @Deprecated public boolean isLayoutFrozen();
+    method public final boolean isLayoutSuppressed();
+    method public void offsetChildrenHorizontal(@Px int);
+    method public void offsetChildrenVertical(@Px int);
+    method public void onChildAttachedToWindow(android.view.View);
+    method public void onChildDetachedFromWindow(android.view.View);
+    method public void onDraw(android.graphics.Canvas!);
+    method public void onScrollStateChanged(int);
+    method public void onScrolled(@Px int, @Px int);
+    method public void removeItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration);
+    method public void removeItemDecorationAt(int);
+    method public void removeOnChildAttachStateChangeListener(androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener);
+    method public void removeOnItemTouchListener(androidx.recyclerview.widget.RecyclerView.OnItemTouchListener);
+    method public void removeOnScrollListener(androidx.recyclerview.widget.RecyclerView.OnScrollListener);
+    method public void scrollToPosition(int);
+    method public void setAccessibilityDelegateCompat(androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate?);
+    method public void setAdapter(androidx.recyclerview.widget.RecyclerView.Adapter?);
+    method public void setChildDrawingOrderCallback(androidx.recyclerview.widget.RecyclerView.ChildDrawingOrderCallback?);
+    method public void setEdgeEffectFactory(androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory);
+    method public void setHasFixedSize(boolean);
+    method public void setItemAnimator(androidx.recyclerview.widget.RecyclerView.ItemAnimator?);
+    method public void setItemViewCacheSize(int);
+    method @Deprecated public void setLayoutFrozen(boolean);
+    method public void setLayoutManager(androidx.recyclerview.widget.RecyclerView.LayoutManager?);
+    method @Deprecated public void setLayoutTransition(android.animation.LayoutTransition!);
+    method public void setOnFlingListener(androidx.recyclerview.widget.RecyclerView.OnFlingListener?);
+    method @Deprecated public void setOnScrollListener(androidx.recyclerview.widget.RecyclerView.OnScrollListener?);
+    method public void setPreserveFocusAfterLayout(boolean);
+    method public void setRecycledViewPool(androidx.recyclerview.widget.RecyclerView.RecycledViewPool?);
+    method public void setRecyclerListener(androidx.recyclerview.widget.RecyclerView.RecyclerListener?);
+    method public void setScrollingTouchSlop(int);
+    method public void setViewCacheExtension(androidx.recyclerview.widget.RecyclerView.ViewCacheExtension?);
+    method public void smoothScrollBy(@Px int, @Px int);
+    method public void smoothScrollBy(@Px int, @Px int, android.view.animation.Interpolator?);
+    method public void smoothScrollBy(@Px int, @Px int, android.view.animation.Interpolator?, int);
+    method public void smoothScrollToPosition(int);
+    method public boolean startNestedScroll(int, int);
+    method public void stopNestedScroll(int);
+    method public void stopScroll();
+    method public final void suppressLayout(boolean);
+    method public void swapAdapter(androidx.recyclerview.widget.RecyclerView.Adapter?, boolean);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int INVALID_TYPE = -1; // 0xffffffff
+    field public static final long NO_ID = -1L; // 0xffffffffffffffffL
+    field public static final int NO_POSITION = -1; // 0xffffffff
+    field public static final int SCROLL_STATE_DRAGGING = 1; // 0x1
+    field public static final int SCROLL_STATE_IDLE = 0; // 0x0
+    field public static final int SCROLL_STATE_SETTLING = 2; // 0x2
+    field public static final int TOUCH_SLOP_DEFAULT = 0; // 0x0
+    field public static final int TOUCH_SLOP_PAGING = 1; // 0x1
+    field public static final int UNDEFINED_DURATION = -2147483648; // 0x80000000
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public abstract static class RecyclerView.Adapter<VH extends androidx.recyclerview.widget.RecyclerView.ViewHolder> {
+    ctor public RecyclerView.Adapter();
+    method public final void bindViewHolder(VH, int);
+    method public final VH createViewHolder(android.view.ViewGroup, int);
+    method public abstract int getItemCount();
+    method public long getItemId(int);
+    method public int getItemViewType(int);
+    method public final boolean hasObservers();
+    method public final boolean hasStableIds();
+    method public final void notifyDataSetChanged();
+    method public final void notifyItemChanged(int);
+    method public final void notifyItemChanged(int, Object?);
+    method public final void notifyItemInserted(int);
+    method public final void notifyItemMoved(int, int);
+    method public final void notifyItemRangeChanged(int, int);
+    method public final void notifyItemRangeChanged(int, int, Object?);
+    method public final void notifyItemRangeInserted(int, int);
+    method public final void notifyItemRangeRemoved(int, int);
+    method public final void notifyItemRemoved(int);
+    method public void onAttachedToRecyclerView(androidx.recyclerview.widget.RecyclerView);
+    method public abstract void onBindViewHolder(VH, int);
+    method public void onBindViewHolder(VH, int, java.util.List<java.lang.Object!>);
+    method public abstract VH onCreateViewHolder(android.view.ViewGroup, int);
+    method public void onDetachedFromRecyclerView(androidx.recyclerview.widget.RecyclerView);
+    method public boolean onFailedToRecycleView(VH);
+    method public void onViewAttachedToWindow(VH);
+    method public void onViewDetachedFromWindow(VH);
+    method public void onViewRecycled(VH);
+    method public void registerAdapterDataObserver(androidx.recyclerview.widget.RecyclerView.AdapterDataObserver);
+    method public void setHasStableIds(boolean);
+    method public void unregisterAdapterDataObserver(androidx.recyclerview.widget.RecyclerView.AdapterDataObserver);
+  }
+
+  public abstract static class RecyclerView.AdapterDataObserver {
+    ctor public RecyclerView.AdapterDataObserver();
+    method public void onChanged();
+    method public void onItemRangeChanged(int, int);
+    method public void onItemRangeChanged(int, int, Object?);
+    method public void onItemRangeInserted(int, int);
+    method public void onItemRangeMoved(int, int, int);
+    method public void onItemRangeRemoved(int, int);
+  }
+
+  public static interface RecyclerView.ChildDrawingOrderCallback {
+    method public int onGetChildDrawingOrder(int, int);
+  }
+
+  public static class RecyclerView.EdgeEffectFactory {
+    ctor public RecyclerView.EdgeEffectFactory();
+    method protected android.widget.EdgeEffect createEdgeEffect(androidx.recyclerview.widget.RecyclerView, @androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.EdgeDirection int);
+    field public static final int DIRECTION_BOTTOM = 3; // 0x3
+    field public static final int DIRECTION_LEFT = 0; // 0x0
+    field public static final int DIRECTION_RIGHT = 2; // 0x2
+    field public static final int DIRECTION_TOP = 1; // 0x1
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_LEFT, androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_TOP, androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_RIGHT, androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_BOTTOM}) public static @interface RecyclerView.EdgeEffectFactory.EdgeDirection {
+  }
+
+  public abstract static class RecyclerView.ItemAnimator {
+    ctor public RecyclerView.ItemAnimator();
+    method public abstract boolean animateAppearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateDisappearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?);
+    method public abstract boolean animatePersistence(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public boolean canReuseUpdatedViewHolder(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public boolean canReuseUpdatedViewHolder(androidx.recyclerview.widget.RecyclerView.ViewHolder, java.util.List<java.lang.Object!>);
+    method public final void dispatchAnimationFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public final void dispatchAnimationStarted(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public final void dispatchAnimationsFinished();
+    method public abstract void endAnimation(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public abstract void endAnimations();
+    method public long getAddDuration();
+    method public long getChangeDuration();
+    method public long getMoveDuration();
+    method public long getRemoveDuration();
+    method public abstract boolean isRunning();
+    method public final boolean isRunning(androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemAnimatorFinishedListener?);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo obtainHolderInfo();
+    method public void onAnimationFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onAnimationStarted(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo recordPostLayoutInformation(androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo recordPreLayoutInformation(androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.ViewHolder, @androidx.recyclerview.widget.RecyclerView.ItemAnimator.AdapterChanges int, java.util.List<java.lang.Object!>);
+    method public abstract void runPendingAnimations();
+    method public void setAddDuration(long);
+    method public void setChangeDuration(long);
+    method public void setMoveDuration(long);
+    method public void setRemoveDuration(long);
+    field public static final int FLAG_APPEARED_IN_PRE_LAYOUT = 4096; // 0x1000
+    field public static final int FLAG_CHANGED = 2; // 0x2
+    field public static final int FLAG_INVALIDATED = 4; // 0x4
+    field public static final int FLAG_MOVED = 2048; // 0x800
+    field public static final int FLAG_REMOVED = 8; // 0x8
+  }
+
+  @IntDef(flag=true, value={androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_CHANGED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_REMOVED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_MOVED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_INVALIDATED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_APPEARED_IN_PRE_LAYOUT}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RecyclerView.ItemAnimator.AdapterChanges {
+  }
+
+  public static interface RecyclerView.ItemAnimator.ItemAnimatorFinishedListener {
+    method public void onAnimationsFinished();
+  }
+
+  public static class RecyclerView.ItemAnimator.ItemHolderInfo {
+    ctor public RecyclerView.ItemAnimator.ItemHolderInfo();
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo setFrom(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo setFrom(androidx.recyclerview.widget.RecyclerView.ViewHolder, @androidx.recyclerview.widget.RecyclerView.ItemAnimator.AdapterChanges int);
+    field public int bottom;
+    field @androidx.recyclerview.widget.RecyclerView.ItemAnimator.AdapterChanges public int changeFlags;
+    field public int left;
+    field public int right;
+    field public int top;
+  }
+
+  public abstract static class RecyclerView.ItemDecoration {
+    ctor public RecyclerView.ItemDecoration();
+    method @Deprecated public void getItemOffsets(android.graphics.Rect, int, androidx.recyclerview.widget.RecyclerView);
+    method public void getItemOffsets(android.graphics.Rect, android.view.View, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State);
+    method public void onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State);
+    method @Deprecated public void onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView);
+    method public void onDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State);
+    method @Deprecated public void onDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView);
+  }
+
+  public abstract static class RecyclerView.LayoutManager {
+    ctor public RecyclerView.LayoutManager();
+    method public void addDisappearingView(android.view.View!);
+    method public void addDisappearingView(android.view.View!, int);
+    method public void addView(android.view.View!);
+    method public void addView(android.view.View!, int);
+    method public void assertInLayoutOrScroll(String!);
+    method public void assertNotInLayoutOrScroll(String!);
+    method public void attachView(android.view.View, int, androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public void attachView(android.view.View, int);
+    method public void attachView(android.view.View);
+    method public void calculateItemDecorationsForChild(android.view.View, android.graphics.Rect);
+    method public boolean canScrollHorizontally();
+    method public boolean canScrollVertically();
+    method public boolean checkLayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public static int chooseSize(int, int, int);
+    method public void collectAdjacentPrefetchPositions(int, int, androidx.recyclerview.widget.RecyclerView.State!, androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry!);
+    method public void collectInitialPrefetchPositions(int, androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry!);
+    method public int computeHorizontalScrollExtent(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeHorizontalScrollOffset(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeHorizontalScrollRange(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeVerticalScrollExtent(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeVerticalScrollOffset(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeVerticalScrollRange(androidx.recyclerview.widget.RecyclerView.State);
+    method public void detachAndScrapAttachedViews(androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void detachAndScrapView(android.view.View, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void detachAndScrapViewAt(int, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void detachView(android.view.View);
+    method public void detachViewAt(int);
+    method public void endAnimation(android.view.View!);
+    method public android.view.View? findContainingItemView(android.view.View);
+    method public android.view.View? findViewByPosition(int);
+    method public abstract androidx.recyclerview.widget.RecyclerView.LayoutParams! generateDefaultLayoutParams();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateLayoutParams(android.content.Context!, android.util.AttributeSet!);
+    method public int getBaseline();
+    method public int getBottomDecorationHeight(android.view.View);
+    method public android.view.View? getChildAt(int);
+    method public int getChildCount();
+    method @Deprecated public static int getChildMeasureSpec(int, int, int, boolean);
+    method public static int getChildMeasureSpec(int, int, int, int, boolean);
+    method public boolean getClipToPadding();
+    method public int getColumnCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public int getDecoratedBottom(android.view.View);
+    method public void getDecoratedBoundsWithMargins(android.view.View, android.graphics.Rect);
+    method public int getDecoratedLeft(android.view.View);
+    method public int getDecoratedMeasuredHeight(android.view.View);
+    method public int getDecoratedMeasuredWidth(android.view.View);
+    method public int getDecoratedRight(android.view.View);
+    method public int getDecoratedTop(android.view.View);
+    method public android.view.View? getFocusedChild();
+    method @Px public int getHeight();
+    method public int getHeightMode();
+    method public int getItemCount();
+    method public int getItemViewType(android.view.View);
+    method public int getLayoutDirection();
+    method public int getLeftDecorationWidth(android.view.View);
+    method @Px public int getMinimumHeight();
+    method @Px public int getMinimumWidth();
+    method @Px public int getPaddingBottom();
+    method @Px public int getPaddingEnd();
+    method @Px public int getPaddingLeft();
+    method @Px public int getPaddingRight();
+    method @Px public int getPaddingStart();
+    method @Px public int getPaddingTop();
+    method public int getPosition(android.view.View);
+    method public static androidx.recyclerview.widget.RecyclerView.LayoutManager.Properties! getProperties(android.content.Context, android.util.AttributeSet?, int, int);
+    method public int getRightDecorationWidth(android.view.View);
+    method public int getRowCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public int getSelectionModeForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public int getTopDecorationHeight(android.view.View);
+    method public void getTransformedBoundingBox(android.view.View, boolean, android.graphics.Rect);
+    method @Px public int getWidth();
+    method public int getWidthMode();
+    method public boolean hasFocus();
+    method public void ignoreView(android.view.View);
+    method public boolean isAttachedToWindow();
+    method public boolean isAutoMeasureEnabled();
+    method public boolean isFocused();
+    method public final boolean isItemPrefetchEnabled();
+    method public boolean isLayoutHierarchical(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public boolean isMeasurementCacheEnabled();
+    method public boolean isSmoothScrolling();
+    method public boolean isViewPartiallyVisible(android.view.View, boolean, boolean);
+    method public void layoutDecorated(android.view.View, int, int, int, int);
+    method public void layoutDecoratedWithMargins(android.view.View, int, int, int, int);
+    method public void measureChild(android.view.View, int, int);
+    method public void measureChildWithMargins(android.view.View, int, int);
+    method public void moveView(int, int);
+    method public void offsetChildrenHorizontal(@Px int);
+    method public void offsetChildrenVertical(@Px int);
+    method public void onAdapterChanged(androidx.recyclerview.widget.RecyclerView.Adapter?, androidx.recyclerview.widget.RecyclerView.Adapter?);
+    method public boolean onAddFocusables(androidx.recyclerview.widget.RecyclerView, java.util.ArrayList<android.view.View!>, int, int);
+    method @CallSuper public void onAttachedToWindow(androidx.recyclerview.widget.RecyclerView!);
+    method @Deprecated public void onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView!);
+    method @CallSuper public void onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView!, androidx.recyclerview.widget.RecyclerView.Recycler!);
+    method public android.view.View? onFocusSearchFailed(android.view.View, int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public void onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityEvent(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityNodeInfo(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method public void onInitializeAccessibilityNodeInfoForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method public android.view.View? onInterceptFocusSearch(android.view.View, int);
+    method public void onItemsAdded(androidx.recyclerview.widget.RecyclerView, int, int);
+    method public void onItemsChanged(androidx.recyclerview.widget.RecyclerView);
+    method public void onItemsMoved(androidx.recyclerview.widget.RecyclerView, int, int, int);
+    method public void onItemsRemoved(androidx.recyclerview.widget.RecyclerView, int, int);
+    method public void onItemsUpdated(androidx.recyclerview.widget.RecyclerView, int, int);
+    method public void onItemsUpdated(androidx.recyclerview.widget.RecyclerView, int, int, Object?);
+    method public void onLayoutChildren(androidx.recyclerview.widget.RecyclerView.Recycler!, androidx.recyclerview.widget.RecyclerView.State!);
+    method public void onLayoutCompleted(androidx.recyclerview.widget.RecyclerView.State!);
+    method public void onMeasure(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, int, int);
+    method @Deprecated public boolean onRequestChildFocus(androidx.recyclerview.widget.RecyclerView, android.view.View, android.view.View?);
+    method public boolean onRequestChildFocus(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State, android.view.View, android.view.View?);
+    method public void onRestoreInstanceState(android.os.Parcelable!);
+    method public android.os.Parcelable? onSaveInstanceState();
+    method public void onScrollStateChanged(int);
+    method public boolean performAccessibilityAction(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, int, android.os.Bundle?);
+    method public boolean performAccessibilityActionForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, int, android.os.Bundle?);
+    method public void postOnAnimation(Runnable!);
+    method public void removeAllViews();
+    method public void removeAndRecycleAllViews(androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void removeAndRecycleView(android.view.View, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void removeAndRecycleViewAt(int, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public boolean removeCallbacks(Runnable!);
+    method public void removeDetachedView(android.view.View);
+    method public void removeView(android.view.View!);
+    method public void removeViewAt(int);
+    method public boolean requestChildRectangleOnScreen(androidx.recyclerview.widget.RecyclerView, android.view.View, android.graphics.Rect, boolean);
+    method public boolean requestChildRectangleOnScreen(androidx.recyclerview.widget.RecyclerView, android.view.View, android.graphics.Rect, boolean, boolean);
+    method public void requestLayout();
+    method public void requestSimpleAnimationsInNextLayout();
+    method public int scrollHorizontallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler!, androidx.recyclerview.widget.RecyclerView.State!);
+    method public void scrollToPosition(int);
+    method public int scrollVerticallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler!, androidx.recyclerview.widget.RecyclerView.State!);
+    method @Deprecated public void setAutoMeasureEnabled(boolean);
+    method public final void setItemPrefetchEnabled(boolean);
+    method public void setMeasuredDimension(android.graphics.Rect!, int, int);
+    method public void setMeasuredDimension(int, int);
+    method public void setMeasurementCacheEnabled(boolean);
+    method public void smoothScrollToPosition(androidx.recyclerview.widget.RecyclerView!, androidx.recyclerview.widget.RecyclerView.State!, int);
+    method public void startSmoothScroll(androidx.recyclerview.widget.RecyclerView.SmoothScroller!);
+    method public void stopIgnoringView(android.view.View);
+    method public boolean supportsPredictiveItemAnimations();
+  }
+
+  public static interface RecyclerView.LayoutManager.LayoutPrefetchRegistry {
+    method public void addPosition(int, int);
+  }
+
+  public static class RecyclerView.LayoutManager.Properties {
+    ctor public RecyclerView.LayoutManager.Properties();
+    field public int orientation;
+    field public boolean reverseLayout;
+    field public int spanCount;
+    field public boolean stackFromEnd;
+  }
+
+  public static class RecyclerView.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+    ctor public RecyclerView.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public RecyclerView.LayoutParams(int, int);
+    ctor public RecyclerView.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public RecyclerView.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public RecyclerView.LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public int getViewAdapterPosition();
+    method public int getViewLayoutPosition();
+    method @Deprecated public int getViewPosition();
+    method public boolean isItemChanged();
+    method public boolean isItemRemoved();
+    method public boolean isViewInvalid();
+    method public boolean viewNeedsUpdate();
+  }
+
+  public static interface RecyclerView.OnChildAttachStateChangeListener {
+    method public void onChildViewAttachedToWindow(android.view.View);
+    method public void onChildViewDetachedFromWindow(android.view.View);
+  }
+
+  public abstract static class RecyclerView.OnFlingListener {
+    ctor public RecyclerView.OnFlingListener();
+    method public abstract boolean onFling(int, int);
+  }
+
+  public static interface RecyclerView.OnItemTouchListener {
+    method public boolean onInterceptTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+    method public void onRequestDisallowInterceptTouchEvent(boolean);
+    method public void onTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+  }
+
+  public abstract static class RecyclerView.OnScrollListener {
+    ctor public RecyclerView.OnScrollListener();
+    method public void onScrollStateChanged(androidx.recyclerview.widget.RecyclerView, int);
+    method public void onScrolled(androidx.recyclerview.widget.RecyclerView, int, int);
+  }
+
+  @IntDef({androidx.recyclerview.widget.RecyclerView.HORIZONTAL, androidx.recyclerview.widget.RecyclerView.VERTICAL}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RecyclerView.Orientation {
+  }
+
+  public static class RecyclerView.RecycledViewPool {
+    ctor public RecyclerView.RecycledViewPool();
+    method public void clear();
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? getRecycledView(int);
+    method public int getRecycledViewCount(int);
+    method public void putRecycledView(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void setMaxRecycledViews(int, int);
+  }
+
+  public final class RecyclerView.Recycler {
+    ctor public RecyclerView.Recycler();
+    method public void bindViewToPosition(android.view.View, int);
+    method public void clear();
+    method public int convertPreLayoutPositionToPostLayout(int);
+    method public java.util.List<androidx.recyclerview.widget.RecyclerView.ViewHolder!> getScrapList();
+    method public android.view.View getViewForPosition(int);
+    method public void recycleView(android.view.View);
+    method public void setViewCacheSize(int);
+  }
+
+  public static interface RecyclerView.RecyclerListener {
+    method public void onViewRecycled(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+  }
+
+
+  public static class RecyclerView.SimpleOnItemTouchListener implements androidx.recyclerview.widget.RecyclerView.OnItemTouchListener {
+    ctor public RecyclerView.SimpleOnItemTouchListener();
+    method public boolean onInterceptTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+    method public void onRequestDisallowInterceptTouchEvent(boolean);
+    method public void onTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+  }
+
+  public abstract static class RecyclerView.SmoothScroller {
+    ctor public RecyclerView.SmoothScroller();
+    method public android.graphics.PointF? computeScrollVectorForPosition(int);
+    method public android.view.View! findViewByPosition(int);
+    method public int getChildCount();
+    method public int getChildPosition(android.view.View!);
+    method public androidx.recyclerview.widget.RecyclerView.LayoutManager? getLayoutManager();
+    method public int getTargetPosition();
+    method @Deprecated public void instantScrollToPosition(int);
+    method public boolean isPendingInitialRun();
+    method public boolean isRunning();
+    method protected void normalize(android.graphics.PointF);
+    method protected void onChildAttachedToWindow(android.view.View!);
+    method protected abstract void onSeekTargetStep(@Px int, @Px int, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action);
+    method protected abstract void onStart();
+    method protected abstract void onStop();
+    method protected abstract void onTargetFound(android.view.View, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action);
+    method public void setTargetPosition(int);
+    method protected final void stop();
+  }
+
+  public static class RecyclerView.SmoothScroller.Action {
+    ctor public RecyclerView.SmoothScroller.Action(@Px int, @Px int);
+    ctor public RecyclerView.SmoothScroller.Action(@Px int, @Px int, int);
+    ctor public RecyclerView.SmoothScroller.Action(@Px int, @Px int, int, android.view.animation.Interpolator?);
+    method public int getDuration();
+    method @Px public int getDx();
+    method @Px public int getDy();
+    method public android.view.animation.Interpolator? getInterpolator();
+    method public void jumpTo(int);
+    method public void setDuration(int);
+    method public void setDx(@Px int);
+    method public void setDy(@Px int);
+    method public void setInterpolator(android.view.animation.Interpolator?);
+    method public void update(@Px int, @Px int, int, android.view.animation.Interpolator?);
+    field public static final int UNDEFINED_DURATION = -2147483648; // 0x80000000
+  }
+
+  public static interface RecyclerView.SmoothScroller.ScrollVectorProvider {
+    method public android.graphics.PointF? computeScrollVectorForPosition(int);
+  }
+
+  public static class RecyclerView.State {
+    ctor public RecyclerView.State();
+    method public boolean didStructureChange();
+    method public <T> T! get(int);
+    method public int getItemCount();
+    method public int getRemainingScrollHorizontal();
+    method public int getRemainingScrollVertical();
+    method public int getTargetScrollPosition();
+    method public boolean hasTargetScrollPosition();
+    method public boolean isMeasuring();
+    method public boolean isPreLayout();
+    method public void put(int, Object!);
+    method public void remove(int);
+    method public boolean willRunPredictiveAnimations();
+    method public boolean willRunSimpleAnimations();
+  }
+
+  public abstract static class RecyclerView.ViewCacheExtension {
+    ctor public RecyclerView.ViewCacheExtension();
+    method public abstract android.view.View? getViewForPositionAndType(androidx.recyclerview.widget.RecyclerView.Recycler, int, int);
+  }
+
+  public abstract static class RecyclerView.ViewHolder {
+    ctor public RecyclerView.ViewHolder(android.view.View);
+    method public final int getAdapterPosition();
+    method public final long getItemId();
+    method public final int getItemViewType();
+    method public final int getLayoutPosition();
+    method public final int getOldPosition();
+    method @Deprecated public final int getPosition();
+    method public final boolean isRecyclable();
+    method public final void setIsRecyclable(boolean);
+    field public final android.view.View itemView;
+  }
+
+  public class RecyclerViewAccessibilityDelegate extends androidx.core.view.AccessibilityDelegateCompat {
+    ctor public RecyclerViewAccessibilityDelegate(androidx.recyclerview.widget.RecyclerView);
+    method public androidx.core.view.AccessibilityDelegateCompat getItemDelegate();
+  }
+
+  public static class RecyclerViewAccessibilityDelegate.ItemDelegate extends androidx.core.view.AccessibilityDelegateCompat {
+    ctor public RecyclerViewAccessibilityDelegate.ItemDelegate(androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate);
+  }
+
+  public abstract class SimpleItemAnimator extends androidx.recyclerview.widget.RecyclerView.ItemAnimator {
+    ctor public SimpleItemAnimator();
+    method public abstract boolean animateAdd(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public boolean animateAppearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder!, androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animateDisappearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?);
+    method public abstract boolean animateMove(androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animatePersistence(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateRemove(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchAddFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchAddStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchChangeFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public final void dispatchChangeStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public final void dispatchMoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchMoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchRemoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchRemoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public boolean getSupportsChangeAnimations();
+    method public void onAddFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onAddStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onChangeFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public void onChangeStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public void onMoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onMoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onRemoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onRemoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void setSupportsChangeAnimations(boolean);
+  }
+
+  public abstract class SnapHelper extends androidx.recyclerview.widget.RecyclerView.OnFlingListener {
+    ctor public SnapHelper();
+    method public void attachToRecyclerView(androidx.recyclerview.widget.RecyclerView?) throws java.lang.IllegalStateException;
+    method public abstract int[]? calculateDistanceToFinalSnap(androidx.recyclerview.widget.RecyclerView.LayoutManager, android.view.View);
+    method public int[]! calculateScrollDistance(int, int);
+    method protected androidx.recyclerview.widget.RecyclerView.SmoothScroller? createScroller(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method @Deprecated protected androidx.recyclerview.widget.LinearSmoothScroller? createSnapScroller(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public abstract android.view.View? findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public abstract int findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int, int);
+    method public boolean onFling(int, int);
+  }
+
+  public class SortedList<T> {
+    ctor public SortedList(Class<T!>, androidx.recyclerview.widget.SortedList.Callback<T!>);
+    ctor public SortedList(Class<T!>, androidx.recyclerview.widget.SortedList.Callback<T!>, int);
+    method public int add(T!);
+    method public void addAll(T![], boolean);
+    method public void addAll(T!...);
+    method public void addAll(java.util.Collection<T!>);
+    method public void beginBatchedUpdates();
+    method public void clear();
+    method public void endBatchedUpdates();
+    method public T! get(int) throws java.lang.IndexOutOfBoundsException;
+    method public int indexOf(T!);
+    method public void recalculatePositionOfItemAt(int);
+    method public boolean remove(T!);
+    method public T! removeItemAt(int);
+    method public void replaceAll(T![], boolean);
+    method public void replaceAll(T!...);
+    method public void replaceAll(java.util.Collection<T!>);
+    method public int size();
+    method public void updateItemAt(int, T!);
+    field public static final int INVALID_POSITION = -1; // 0xffffffff
+  }
+
+  public static class SortedList.BatchedCallback<T2> extends androidx.recyclerview.widget.SortedList.Callback<T2> {
+    ctor public SortedList.BatchedCallback(androidx.recyclerview.widget.SortedList.Callback<T2!>!);
+    method public boolean areContentsTheSame(T2!, T2!);
+    method public boolean areItemsTheSame(T2!, T2!);
+    method public int compare(T2!, T2!);
+    method public void dispatchLastEvent();
+    method public void onChanged(int, int);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public abstract static class SortedList.Callback<T2> implements java.util.Comparator<T2> androidx.recyclerview.widget.ListUpdateCallback {
+    ctor public SortedList.Callback();
+    method public abstract boolean areContentsTheSame(T2!, T2!);
+    method public abstract boolean areItemsTheSame(T2!, T2!);
+    method public abstract int compare(T2!, T2!);
+    method public Object? getChangePayload(T2!, T2!);
+    method public abstract void onChanged(int, int);
+    method public void onChanged(int, int, Object!);
+  }
+
+  public abstract class SortedListAdapterCallback<T2> extends androidx.recyclerview.widget.SortedList.Callback<T2> {
+    ctor public SortedListAdapterCallback(androidx.recyclerview.widget.RecyclerView.Adapter!);
+    method public void onChanged(int, int);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public class StaggeredGridLayoutManager extends androidx.recyclerview.widget.RecyclerView.LayoutManager implements androidx.recyclerview.widget.RecyclerView.SmoothScroller.ScrollVectorProvider {
+    ctor public StaggeredGridLayoutManager(android.content.Context!, android.util.AttributeSet!, int, int);
+    ctor public StaggeredGridLayoutManager(int, int);
+    method public android.graphics.PointF! computeScrollVectorForPosition(int);
+    method public int[]! findFirstCompletelyVisibleItemPositions(int[]!);
+    method public int[]! findFirstVisibleItemPositions(int[]!);
+    method public int[]! findLastCompletelyVisibleItemPositions(int[]!);
+    method public int[]! findLastVisibleItemPositions(int[]!);
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateDefaultLayoutParams();
+    method public int getGapStrategy();
+    method public int getOrientation();
+    method public boolean getReverseLayout();
+    method public int getSpanCount();
+    method public void invalidateSpanAssignments();
+    method public void scrollToPositionWithOffset(int, int);
+    method public void setGapStrategy(int);
+    method public void setOrientation(int);
+    method public void setReverseLayout(boolean);
+    method public void setSpanCount(int);
+    field @Deprecated public static final int GAP_HANDLING_LAZY = 1; // 0x1
+    field public static final int GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS = 2; // 0x2
+    field public static final int GAP_HANDLING_NONE = 0; // 0x0
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public static class StaggeredGridLayoutManager.LayoutParams extends androidx.recyclerview.widget.RecyclerView.LayoutParams {
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public StaggeredGridLayoutManager.LayoutParams(int, int);
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public StaggeredGridLayoutManager.LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public final int getSpanIndex();
+    method public boolean isFullSpan();
+    method public void setFullSpan(boolean);
+    field public static final int INVALID_SPAN_ID = -1; // 0xffffffff
+  }
+
+
+}
+
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearLayoutManagerExtraLayoutSpaceTest.java b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearLayoutManagerExtraLayoutSpaceTest.java
index 70b1225..8f87cf5 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearLayoutManagerExtraLayoutSpaceTest.java
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearLayoutManagerExtraLayoutSpaceTest.java
@@ -69,6 +69,7 @@
 
     private int mCurrPosition = 0;
     private ScrollDirection mLastScrollDirection = TOWARDS_END;
+    private LastScrollDeltaTracker mLastScrollTracker = new LastScrollDeltaTracker();
 
     public LinearLayoutManagerExtraLayoutSpaceTest(Config config, int extraLayoutSpaceLegacy,
             int extraLayoutSpace) {
@@ -116,6 +117,7 @@
         mLayoutManager = (ExtraLayoutSpaceLayoutManager) super.mLayoutManager;
         mLayoutManager.mExtraLayoutSpaceLegacy = mExtraLayoutSpaceLegacy;
         mLayoutManager.mExtraLayoutSpace = mExtraLayoutSpace;
+        mRecyclerView.addOnScrollListener(mLastScrollTracker);
 
         // Verify start position
         verifyStartPosition();
@@ -142,6 +144,13 @@
 
         // Perform the scroll
         scrollToPosition(mCurrPosition, smoothScroll);
+        int direction = Integer.signum(mCurrPosition - prevPosition);
+        if (smoothScroll) {
+            // TODO(b/139350295): fix the overshoot instead of detecting it
+            while (!isLastScrollDirectionCorrect(direction)) {
+                correctLastScrollDirection();
+            }
+        }
 
         // Update expected results
         // Alignment means the side of the viewport to which mCurrPosition is aligned
@@ -155,6 +164,25 @@
         verify(getExpectedExtraSpace(smoothScroll), getAvailableSpace(alignment));
     }
 
+    private boolean isLastScrollDirectionCorrect(int expectedDirection) {
+        int lastDirection = mLastScrollTracker.get(mConfig.mOrientation);
+        int reversedModifier = isReversed() ? -1 : 1;
+        return lastDirection * reversedModifier * expectedDirection >= 0;
+    }
+
+    private void correctLastScrollDirection() throws Throwable {
+        final int dx = Integer.signum(mLastScrollTracker.getX());
+        final int dy = Integer.signum(mLastScrollTracker.getY());
+
+        mLayoutManager.expectIdleState(1);
+        mRecyclerView.smoothScrollBy(dx, dy);
+        mLayoutManager.waitForSnap(10);
+
+        mLayoutManager.expectIdleState(1);
+        mRecyclerView.smoothScrollBy(-dx, -dy);
+        mLayoutManager.waitForSnap(10);
+    }
+
     private void scrollToPosition(final int position, final boolean smoothScroll) throws Throwable {
         mActivityRule.runOnUiThread(new Runnable() {
             @Override
@@ -269,6 +297,29 @@
         );
     }
 
+
+    private class LastScrollDeltaTracker extends RecyclerView.OnScrollListener {
+        public final int[] mLastScrollDelta = new int[2];
+
+        @Override
+        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
+            mLastScrollDelta[0] = dx;
+            mLastScrollDelta[1] = dy;
+        }
+
+        public int getX() {
+            return mLastScrollDelta[0];
+        }
+
+        public int getY() {
+            return mLastScrollDelta[1];
+        }
+
+        public int get(int orientation) {
+            return mLastScrollDelta[orientation];
+        }
+    }
+
     class ExtraLayoutSpaceLayoutManager extends WrappedLinearLayoutManager {
         int mExtraLayoutSpaceLegacy = -1;
         int[] mExtraLayoutSpace = null;
diff --git a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java
index 0d1f6d9..735a0b1 100644
--- a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java
+++ b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java
@@ -6298,8 +6298,7 @@
                         mAccessibilityDelegate.mItemDelegate;
                 // If there was already an a11y delegate set on the itemView, store it in the
                 // itemDelegate and then set the itemDelegate as the a11y delegate.
-                itemDelegate.setOriginalDelegateForItem(itemView,
-                        ViewCompat.getAccessibilityDelegate(itemView));
+                itemDelegate.saveOriginalDelegate(itemView);
                 ViewCompat.setAccessibilityDelegate(itemView, itemDelegate);
             }
         }
diff --git a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerViewAccessibilityDelegate.java b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerViewAccessibilityDelegate.java
index 920929b..5257490 100644
--- a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerViewAccessibilityDelegate.java
+++ b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerViewAccessibilityDelegate.java
@@ -22,6 +22,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.core.view.AccessibilityDelegateCompat;
+import androidx.core.view.ViewCompat;
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
 
 import java.util.Map;
@@ -108,13 +109,20 @@
             mRecyclerViewDelegate = recyclerViewDelegate;
         }
 
-        void setOriginalDelegateForItem(View itemView, AccessibilityDelegateCompat delegate) {
-            if (delegate != null) {
+        /**
+         * Saves a reference to the original delegate of the itemView so that it's behavior can be
+         * combined with the ItemDelegate's behavior.
+         */
+        void saveOriginalDelegate(View itemView) {
+            AccessibilityDelegateCompat delegate = ViewCompat.getAccessibilityDelegate(itemView);
+            if (delegate != null && delegate != this) {
                 mOriginalItemDelegates.put(itemView, delegate);
             }
-
         }
 
+        /**
+         * @return The delegate associated with itemView before the view was bound.
+         */
         AccessibilityDelegateCompat getAndRemoveOriginalDelegateForItem(View itemView) {
             return mOriginalItemDelegates.remove(itemView);
         }
diff --git a/remotecallback/api/api_lint.ignore b/remotecallback/api/api_lint.ignore
index 9d77312..7c6cae1 100644
--- a/remotecallback/api/api_lint.ignore
+++ b/remotecallback/api/api_lint.ignore
@@ -15,6 +15,78 @@
     Inconsistent class name; should be `<Foo>Provider`, was `ContentProviderWithCallbacks`
 
 
+MissingNullability: androidx.remotecallback.AppWidgetProviderWithCallbacks#createRemoteCallback(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `createRemoteCallback`
+MissingNullability: androidx.remotecallback.AppWidgetProviderWithCallbacks#onReceive(android.content.Context, android.content.Intent) parameter #0:
+    Missing nullability on parameter `context` in method `onReceive`
+MissingNullability: androidx.remotecallback.AppWidgetProviderWithCallbacks#onReceive(android.content.Context, android.content.Intent) parameter #1:
+    Missing nullability on parameter `intent` in method `onReceive`
+MissingNullability: androidx.remotecallback.BroadcastReceiverWithCallbacks#createRemoteCallback(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `createRemoteCallback`
+MissingNullability: androidx.remotecallback.BroadcastReceiverWithCallbacks#onReceive(android.content.Context, android.content.Intent) parameter #0:
+    Missing nullability on parameter `context` in method `onReceive`
+MissingNullability: androidx.remotecallback.BroadcastReceiverWithCallbacks#onReceive(android.content.Context, android.content.Intent) parameter #1:
+    Missing nullability on parameter `intent` in method `onReceive`
+MissingNullability: androidx.remotecallback.CallbackHandlerRegistry#invokeCallback(android.content.Context, T, android.content.Intent) parameter #0:
+    Missing nullability on parameter `context` in method `invokeCallback`
+MissingNullability: androidx.remotecallback.CallbackHandlerRegistry#invokeCallback(android.content.Context, T, android.content.Intent) parameter #2:
+    Missing nullability on parameter `intent` in method `invokeCallback`
+MissingNullability: androidx.remotecallback.CallbackHandlerRegistry#invokeCallback(android.content.Context, T, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `context` in method `invokeCallback`
+MissingNullability: androidx.remotecallback.CallbackHandlerRegistry#invokeCallback(android.content.Context, T, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `bundle` in method `invokeCallback`
+MissingNullability: androidx.remotecallback.CallbackHandlerRegistry#registerCallbackHandler(Class<T>, String, androidx.remotecallback.CallbackHandlerRegistry.CallbackHandler<T>) parameter #0:
+    Missing nullability on parameter `cls` in method `registerCallbackHandler`
+MissingNullability: androidx.remotecallback.CallbackHandlerRegistry#registerCallbackHandler(Class<T>, String, androidx.remotecallback.CallbackHandlerRegistry.CallbackHandler<T>) parameter #1:
+    Missing nullability on parameter `method` in method `registerCallbackHandler`
+MissingNullability: androidx.remotecallback.CallbackHandlerRegistry#registerCallbackHandler(Class<T>, String, androidx.remotecallback.CallbackHandlerRegistry.CallbackHandler<T>) parameter #2:
+    Missing nullability on parameter `handler` in method `registerCallbackHandler`
+MissingNullability: androidx.remotecallback.CallbackHandlerRegistry#stubToRemoteCallback(androidx.remotecallback.CallbackReceiver, Class<? extends androidx.remotecallback.CallbackReceiver>, android.os.Bundle, String):
+    Missing nullability on method `stubToRemoteCallback` return
+MissingNullability: androidx.remotecallback.CallbackHandlerRegistry#stubToRemoteCallback(androidx.remotecallback.CallbackReceiver, Class<? extends androidx.remotecallback.CallbackReceiver>, android.os.Bundle, String) parameter #0:
+    Missing nullability on parameter `receiver` in method `stubToRemoteCallback`
+MissingNullability: androidx.remotecallback.CallbackHandlerRegistry#stubToRemoteCallback(androidx.remotecallback.CallbackReceiver, Class<? extends androidx.remotecallback.CallbackReceiver>, android.os.Bundle, String) parameter #1:
+    Missing nullability on parameter `cls` in method `stubToRemoteCallback`
+MissingNullability: androidx.remotecallback.CallbackHandlerRegistry#stubToRemoteCallback(androidx.remotecallback.CallbackReceiver, Class<? extends androidx.remotecallback.CallbackReceiver>, android.os.Bundle, String) parameter #2:
+    Missing nullability on parameter `args` in method `stubToRemoteCallback`
+MissingNullability: androidx.remotecallback.CallbackHandlerRegistry#stubToRemoteCallback(androidx.remotecallback.CallbackReceiver, Class<? extends androidx.remotecallback.CallbackReceiver>, android.os.Bundle, String) parameter #3:
+    Missing nullability on parameter `method` in method `stubToRemoteCallback`
+MissingNullability: androidx.remotecallback.CallbackHandlerRegistry.CallbackHandler#executeCallback(android.content.Context, T, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `context` in method `executeCallback`
+MissingNullability: androidx.remotecallback.CallbackHandlerRegistry.CallbackHandler#executeCallback(android.content.Context, T, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `arguments` in method `executeCallback`
+MissingNullability: androidx.remotecallback.CallbackReceiver#createRemoteCallback(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `createRemoteCallback`
+MissingNullability: androidx.remotecallback.ContentProviderWithCallbacks#attachInfo(android.content.Context, android.content.pm.ProviderInfo) parameter #0:
+    Missing nullability on parameter `context` in method `attachInfo`
+MissingNullability: androidx.remotecallback.ContentProviderWithCallbacks#attachInfo(android.content.Context, android.content.pm.ProviderInfo) parameter #1:
+    Missing nullability on parameter `info` in method `attachInfo`
+MissingNullability: androidx.remotecallback.ContentProviderWithCallbacks#call(String, String, android.os.Bundle):
+    Missing nullability on method `call` return
+MissingNullability: androidx.remotecallback.ContentProviderWithCallbacks#call(String, String, android.os.Bundle) parameter #0:
+    Missing nullability on parameter `method` in method `call`
+MissingNullability: androidx.remotecallback.ContentProviderWithCallbacks#call(String, String, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `arg` in method `call`
+MissingNullability: androidx.remotecallback.ContentProviderWithCallbacks#call(String, String, android.os.Bundle) parameter #2:
+    Missing nullability on parameter `extras` in method `call`
+MissingNullability: androidx.remotecallback.ContentProviderWithCallbacks#createRemoteCallback(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `createRemoteCallback`
+MissingNullability: androidx.remotecallback.ExternalInput#value():
+    Missing nullability on method `value` return
+MissingNullability: androidx.remotecallback.RemoteCallback#LOCAL:
+    Missing nullability on field `LOCAL` in class `class androidx.remotecallback.RemoteCallback`
+MissingNullability: androidx.remotecallback.RemoteCallback#create(Class<T>, android.content.Context) parameter #0:
+    Missing nullability on parameter `cls` in method `create`
+MissingNullability: androidx.remotecallback.RemoteCallback#create(Class<T>, android.content.Context) parameter #1:
+    Missing nullability on parameter `context` in method `create`
+MissingNullability: androidx.remotecallback.RemoteCallback#getArgumentBundle():
+    Missing nullability on method `getArgumentBundle` return
+MissingNullability: androidx.remotecallback.RemoteCallback#getMethodName():
+    Missing nullability on method `getMethodName` return
+MissingNullability: androidx.remotecallback.RemoteCallback#toPendingIntent():
+    Missing nullability on method `toPendingIntent` return
+
+
 SingularCallback: androidx.remotecallback.AppWidgetProviderWithCallbacks:
     Callback class names should be singular: AppWidgetProviderWithCallbacks
 SingularCallback: androidx.remotecallback.BroadcastReceiverWithCallbacks:
diff --git a/room/benchmark/src/androidTest/java/androidx/room/benchmark/RelationBenchmark.kt b/room/benchmark/src/androidTest/java/androidx/room/benchmark/RelationBenchmark.kt
index 0fea703..1000c14 100644
--- a/room/benchmark/src/androidTest/java/androidx/room/benchmark/RelationBenchmark.kt
+++ b/room/benchmark/src/androidTest/java/androidx/room/benchmark/RelationBenchmark.kt
@@ -90,7 +90,7 @@
         @JvmStatic
         @Parameterized.Parameters(name = "parentSampleSize={0}, childSampleSize={1}")
         fun data() = arrayOf(100, 500, 1000).flatMap { parentSampleSize ->
-            arrayOf(10, 100).map { childSampleSize ->
+            arrayOf(10).map { childSampleSize ->
                 arrayOf(parentSampleSize, childSampleSize)
             }
         }
diff --git a/room/common/api/2.2.0-alpha03.ignore b/room/common/api/2.2.0-alpha03.ignore
new file mode 100644
index 0000000..51b51d5
--- /dev/null
+++ b/room/common/api/2.2.0-alpha03.ignore
@@ -0,0 +1,13 @@
+// Baseline format: 1.0
+ChangedType: androidx.room.Database#entities():
+    Method androidx.room.Database.entities has changed return type from Class[] to Class<?>[]
+ChangedType: androidx.room.Database#views():
+    Method androidx.room.Database.views has changed return type from Class[] to Class<?>[]
+ChangedType: androidx.room.ForeignKey#entity():
+    Method androidx.room.ForeignKey.entity has changed return type from Class to Class<?>
+ChangedType: androidx.room.Fts4#contentEntity():
+    Method androidx.room.Fts4.contentEntity has changed return type from Class to Class<?>
+ChangedType: androidx.room.RawQuery#observedEntities():
+    Method androidx.room.RawQuery.observedEntities has changed return type from Class[] to Class<?>[]
+ChangedType: androidx.room.Relation#entity():
+    Method androidx.room.Relation.entity has changed return type from Class to Class<?>
diff --git a/room/common/api/2.2.0-alpha03.txt b/room/common/api/2.2.0-alpha03.txt
new file mode 100644
index 0000000..238967d
--- /dev/null
+++ b/room/common/api/2.2.0-alpha03.txt
@@ -0,0 +1,197 @@
+// Signature format: 3.0
+package androidx.room {
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ColumnInfo {
+    method @androidx.room.ColumnInfo.Collate public abstract int collate() default androidx.room.ColumnInfo.UNSPECIFIED;
+    method public abstract String defaultValue() default androidx.room.ColumnInfo.VALUE_UNSPECIFIED;
+    method public abstract boolean index() default false;
+    method public abstract String name() default androidx.room.ColumnInfo.INHERIT_FIELD_NAME;
+    method @androidx.room.ColumnInfo.SQLiteTypeAffinity public abstract int typeAffinity() default androidx.room.ColumnInfo.UNDEFINED;
+    field public static final int BINARY = 2; // 0x2
+    field public static final int BLOB = 5; // 0x5
+    field public static final String INHERIT_FIELD_NAME = "[field-name]";
+    field public static final int INTEGER = 3; // 0x3
+    field @RequiresApi(21) public static final int LOCALIZED = 5; // 0x5
+    field public static final int NOCASE = 3; // 0x3
+    field public static final int REAL = 4; // 0x4
+    field public static final int RTRIM = 4; // 0x4
+    field public static final int TEXT = 2; // 0x2
+    field public static final int UNDEFINED = 1; // 0x1
+    field @RequiresApi(21) public static final int UNICODE = 6; // 0x6
+    field public static final int UNSPECIFIED = 1; // 0x1
+    field public static final String VALUE_UNSPECIFIED = "[value-unspecified]";
+  }
+
+  @IntDef({androidx.room.ColumnInfo.UNSPECIFIED, androidx.room.ColumnInfo.BINARY, androidx.room.ColumnInfo.NOCASE, androidx.room.ColumnInfo.RTRIM, androidx.room.ColumnInfo.LOCALIZED, androidx.room.ColumnInfo.UNICODE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface ColumnInfo.Collate {
+  }
+
+  @IntDef({androidx.room.ColumnInfo.UNDEFINED, androidx.room.ColumnInfo.TEXT, androidx.room.ColumnInfo.INTEGER, androidx.room.ColumnInfo.REAL, androidx.room.ColumnInfo.BLOB}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface ColumnInfo.SQLiteTypeAffinity {
+  }
+
+  @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Dao {
+  }
+
+  @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Database {
+    method public abstract Class<?>[] entities();
+    method public abstract boolean exportSchema() default true;
+    method public abstract int version();
+    method public abstract Class<?>[] views() default {};
+  }
+
+  @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface DatabaseView {
+    method public abstract String value() default "";
+    method public abstract String viewName() default "";
+  }
+
+  @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Delete {
+    method public abstract Class<?> entity() default java.lang.Object.class;
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Embedded {
+    method public abstract String prefix() default "";
+  }
+
+  @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Entity {
+    method public abstract androidx.room.ForeignKey[] foreignKeys() default {};
+    method public abstract String[] ignoredColumns() default {};
+    method public abstract androidx.room.Index[] indices() default {};
+    method public abstract boolean inheritSuperIndices() default false;
+    method public abstract String[] primaryKeys() default {};
+    method public abstract String tableName() default "";
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ForeignKey {
+    method public abstract String[] childColumns();
+    method public abstract boolean deferred() default false;
+    method public abstract Class<?> entity();
+    method @androidx.room.ForeignKey.Action public abstract int onDelete() default androidx.room.ForeignKey.NO_ACTION;
+    method @androidx.room.ForeignKey.Action public abstract int onUpdate() default androidx.room.ForeignKey.NO_ACTION;
+    method public abstract String[] parentColumns();
+    field public static final int CASCADE = 5; // 0x5
+    field public static final int NO_ACTION = 1; // 0x1
+    field public static final int RESTRICT = 2; // 0x2
+    field public static final int SET_DEFAULT = 4; // 0x4
+    field public static final int SET_NULL = 3; // 0x3
+  }
+
+  @IntDef({androidx.room.ForeignKey.NO_ACTION, androidx.room.ForeignKey.RESTRICT, androidx.room.ForeignKey.SET_NULL, androidx.room.ForeignKey.SET_DEFAULT, androidx.room.ForeignKey.CASCADE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface ForeignKey.Action {
+  }
+
+  @RequiresApi(16) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Fts3 {
+    method public abstract String tokenizer() default androidx.room.FtsOptions.TOKENIZER_SIMPLE;
+    method public abstract String[] tokenizerArgs() default {};
+  }
+
+  @RequiresApi(16) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Fts4 {
+    method public abstract Class<?> contentEntity() default java.lang.Object.class;
+    method public abstract String languageId() default "";
+    method public abstract androidx.room.FtsOptions.MatchInfo matchInfo() default androidx.room.FtsOptions.MatchInfo.FTS4;
+    method public abstract String[] notIndexed() default {};
+    method public abstract androidx.room.FtsOptions.Order order() default androidx.room.FtsOptions.Order.ASC;
+    method public abstract int[] prefix() default {};
+    method public abstract String tokenizer() default androidx.room.FtsOptions.TOKENIZER_SIMPLE;
+    method public abstract String[] tokenizerArgs() default {};
+  }
+
+  public class FtsOptions {
+    field public static final String TOKENIZER_ICU = "icu";
+    field public static final String TOKENIZER_PORTER = "porter";
+    field public static final String TOKENIZER_SIMPLE = "simple";
+    field @RequiresApi(21) public static final String TOKENIZER_UNICODE61 = "unicode61";
+  }
+
+  public enum FtsOptions.MatchInfo {
+    enum_constant public static final androidx.room.FtsOptions.MatchInfo FTS3;
+    enum_constant public static final androidx.room.FtsOptions.MatchInfo FTS4;
+  }
+
+  public enum FtsOptions.Order {
+    enum_constant public static final androidx.room.FtsOptions.Order ASC;
+    enum_constant public static final androidx.room.FtsOptions.Order DESC;
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.CONSTRUCTOR}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Ignore {
+  }
+
+  @java.lang.annotation.Target({}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Index {
+    method public abstract String name() default "";
+    method public abstract boolean unique() default false;
+    method public abstract String[] value();
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Insert {
+    method public abstract Class<?> entity() default java.lang.Object.class;
+    method @androidx.room.OnConflictStrategy public abstract int onConflict() default androidx.room.OnConflictStrategy.ABORT;
+  }
+
+  @java.lang.annotation.Target({}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Junction {
+    method public abstract String entityColumn() default "";
+    method public abstract String parentColumn() default "";
+    method public abstract Class<?> value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @IntDef({androidx.room.OnConflictStrategy.REPLACE, androidx.room.OnConflictStrategy.ROLLBACK, androidx.room.OnConflictStrategy.ABORT, androidx.room.OnConflictStrategy.FAIL, androidx.room.OnConflictStrategy.IGNORE}) public @interface OnConflictStrategy {
+    field public static final int ABORT = 3; // 0x3
+    field @Deprecated public static final int FAIL = 4; // 0x4
+    field public static final int IGNORE = 5; // 0x5
+    field public static final int REPLACE = 1; // 0x1
+    field @Deprecated public static final int ROLLBACK = 2; // 0x2
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface PrimaryKey {
+    method public abstract boolean autoGenerate() default false;
+  }
+
+  @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Query {
+    method public abstract String value();
+  }
+
+  @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface RawQuery {
+    method public abstract Class<?>[] observedEntities() default {};
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Relation {
+    method public abstract androidx.room.Junction associateBy() default @androidx.room.Junction;
+    method public abstract Class<?> entity() default java.lang.Object.class;
+    method public abstract String entityColumn();
+    method public abstract String parentColumn();
+    method public abstract String[] projection() default {};
+  }
+
+  public class RoomWarnings {
+    ctor @Deprecated public RoomWarnings();
+    field public static final String CANNOT_CREATE_VERIFICATION_DATABASE = "ROOM_CANNOT_CREATE_VERIFICATION_DATABASE";
+    field public static final String CURSOR_MISMATCH = "ROOM_CURSOR_MISMATCH";
+    field public static final String DEFAULT_CONSTRUCTOR = "ROOM_DEFAULT_CONSTRUCTOR";
+    field public static final String INDEX_FROM_EMBEDDED_ENTITY_IS_DROPPED = "ROOM_EMBEDDED_ENTITY_INDEX_IS_DROPPED";
+    field public static final String INDEX_FROM_EMBEDDED_FIELD_IS_DROPPED = "ROOM_EMBEDDED_INDEX_IS_DROPPED";
+    field public static final String INDEX_FROM_PARENT_FIELD_IS_DROPPED = "ROOM_PARENT_FIELD_INDEX_IS_DROPPED";
+    field public static final String INDEX_FROM_PARENT_IS_DROPPED = "ROOM_PARENT_INDEX_IS_DROPPED";
+    field public static final String MISSING_INDEX_ON_FOREIGN_KEY_CHILD = "ROOM_MISSING_FOREIGN_KEY_CHILD_INDEX";
+    field public static final String MISSING_JAVA_TMP_DIR = "ROOM_MISSING_JAVA_TMP_DIR";
+    field public static final String MISSING_SCHEMA_LOCATION = "ROOM_MISSING_SCHEMA_LOCATION";
+    field public static final String PRIMARY_KEY_FROM_EMBEDDED_IS_DROPPED = "ROOM_EMBEDDED_PRIMARY_KEY_IS_DROPPED";
+    field public static final String RELATION_QUERY_WITHOUT_TRANSACTION = "ROOM_RELATION_QUERY_WITHOUT_TRANSACTION";
+    field public static final String RELATION_TYPE_MISMATCH = "ROOM_RELATION_TYPE_MISMATCH";
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface SkipQueryVerification {
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Transaction {
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface TypeConverter {
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface TypeConverters {
+    method public abstract Class<?>[] value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Update {
+    method public abstract Class<?> entity() default java.lang.Object.class;
+    method @androidx.room.OnConflictStrategy public abstract int onConflict() default androidx.room.OnConflictStrategy.ABORT;
+  }
+
+}
+
diff --git a/room/common/api/api_lint.ignore b/room/common/api/api_lint.ignore
index d34c89c2..067aa3a 100644
--- a/room/common/api/api_lint.ignore
+++ b/room/common/api/api_lint.ignore
@@ -1,3 +1,87 @@
 // Baseline format: 1.0
 AcronymName: androidx.room.ColumnInfo.SQLiteTypeAffinity:
     Acronyms should not be capitalized in class names: was `SQLiteTypeAffinity`, should this be `SqLiteTypeAffinity`?
+
+
+MissingNullability: androidx.room.ColumnInfo#defaultValue():
+    Missing nullability on method `defaultValue` return
+MissingNullability: androidx.room.ColumnInfo#name():
+    Missing nullability on method `name` return
+MissingNullability: androidx.room.Database#entities():
+    Missing nullability on method `entities` return
+MissingNullability: androidx.room.Database#views():
+    Missing nullability on method `views` return
+MissingNullability: androidx.room.DatabaseView#value():
+    Missing nullability on method `value` return
+MissingNullability: androidx.room.DatabaseView#viewName():
+    Missing nullability on method `viewName` return
+MissingNullability: androidx.room.Delete#entity():
+    Missing nullability on method `entity` return
+MissingNullability: androidx.room.Embedded#prefix():
+    Missing nullability on method `prefix` return
+MissingNullability: androidx.room.Entity#foreignKeys():
+    Missing nullability on method `foreignKeys` return
+MissingNullability: androidx.room.Entity#ignoredColumns():
+    Missing nullability on method `ignoredColumns` return
+MissingNullability: androidx.room.Entity#indices():
+    Missing nullability on method `indices` return
+MissingNullability: androidx.room.Entity#primaryKeys():
+    Missing nullability on method `primaryKeys` return
+MissingNullability: androidx.room.Entity#tableName():
+    Missing nullability on method `tableName` return
+MissingNullability: androidx.room.ForeignKey#childColumns():
+    Missing nullability on method `childColumns` return
+MissingNullability: androidx.room.ForeignKey#entity():
+    Missing nullability on method `entity` return
+MissingNullability: androidx.room.ForeignKey#parentColumns():
+    Missing nullability on method `parentColumns` return
+MissingNullability: androidx.room.Fts3#tokenizer():
+    Missing nullability on method `tokenizer` return
+MissingNullability: androidx.room.Fts3#tokenizerArgs():
+    Missing nullability on method `tokenizerArgs` return
+MissingNullability: androidx.room.Fts4#contentEntity():
+    Missing nullability on method `contentEntity` return
+MissingNullability: androidx.room.Fts4#languageId():
+    Missing nullability on method `languageId` return
+MissingNullability: androidx.room.Fts4#matchInfo():
+    Missing nullability on method `matchInfo` return
+MissingNullability: androidx.room.Fts4#notIndexed():
+    Missing nullability on method `notIndexed` return
+MissingNullability: androidx.room.Fts4#order():
+    Missing nullability on method `order` return
+MissingNullability: androidx.room.Fts4#prefix():
+    Missing nullability on method `prefix` return
+MissingNullability: androidx.room.Fts4#tokenizer():
+    Missing nullability on method `tokenizer` return
+MissingNullability: androidx.room.Fts4#tokenizerArgs():
+    Missing nullability on method `tokenizerArgs` return
+MissingNullability: androidx.room.Index#name():
+    Missing nullability on method `name` return
+MissingNullability: androidx.room.Index#value():
+    Missing nullability on method `value` return
+MissingNullability: androidx.room.Insert#entity():
+    Missing nullability on method `entity` return
+MissingNullability: androidx.room.Junction#entityColumn():
+    Missing nullability on method `entityColumn` return
+MissingNullability: androidx.room.Junction#parentColumn():
+    Missing nullability on method `parentColumn` return
+MissingNullability: androidx.room.Junction#value():
+    Missing nullability on method `value` return
+MissingNullability: androidx.room.Query#value():
+    Missing nullability on method `value` return
+MissingNullability: androidx.room.RawQuery#observedEntities():
+    Missing nullability on method `observedEntities` return
+MissingNullability: androidx.room.Relation#associateBy():
+    Missing nullability on method `associateBy` return
+MissingNullability: androidx.room.Relation#entity():
+    Missing nullability on method `entity` return
+MissingNullability: androidx.room.Relation#entityColumn():
+    Missing nullability on method `entityColumn` return
+MissingNullability: androidx.room.Relation#parentColumn():
+    Missing nullability on method `parentColumn` return
+MissingNullability: androidx.room.Relation#projection():
+    Missing nullability on method `projection` return
+MissingNullability: androidx.room.TypeConverters#value():
+    Missing nullability on method `value` return
+MissingNullability: androidx.room.Update#entity():
+    Missing nullability on method `entity` return
diff --git a/room/common/api/restricted_2.2.0-alpha03.txt b/room/common/api/restricted_2.2.0-alpha03.txt
new file mode 100644
index 0000000..ed6c4ee
--- /dev/null
+++ b/room/common/api/restricted_2.2.0-alpha03.txt
@@ -0,0 +1,206 @@
+// Signature format: 3.0
+package androidx.room {
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ColumnInfo {
+    method @androidx.room.ColumnInfo.Collate public abstract int collate() default androidx.room.ColumnInfo.UNSPECIFIED;
+    method public abstract String defaultValue() default androidx.room.ColumnInfo.VALUE_UNSPECIFIED;
+    method public abstract boolean index() default false;
+    method public abstract String name() default androidx.room.ColumnInfo.INHERIT_FIELD_NAME;
+    method @androidx.room.ColumnInfo.SQLiteTypeAffinity public abstract int typeAffinity() default androidx.room.ColumnInfo.UNDEFINED;
+    field public static final int BINARY = 2; // 0x2
+    field public static final int BLOB = 5; // 0x5
+    field public static final String INHERIT_FIELD_NAME = "[field-name]";
+    field public static final int INTEGER = 3; // 0x3
+    field @RequiresApi(21) public static final int LOCALIZED = 5; // 0x5
+    field public static final int NOCASE = 3; // 0x3
+    field public static final int REAL = 4; // 0x4
+    field public static final int RTRIM = 4; // 0x4
+    field public static final int TEXT = 2; // 0x2
+    field public static final int UNDEFINED = 1; // 0x1
+    field @RequiresApi(21) public static final int UNICODE = 6; // 0x6
+    field public static final int UNSPECIFIED = 1; // 0x1
+    field public static final String VALUE_UNSPECIFIED = "[value-unspecified]";
+  }
+
+  @IntDef({androidx.room.ColumnInfo.UNSPECIFIED, androidx.room.ColumnInfo.BINARY, androidx.room.ColumnInfo.NOCASE, androidx.room.ColumnInfo.RTRIM, androidx.room.ColumnInfo.LOCALIZED, androidx.room.ColumnInfo.UNICODE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface ColumnInfo.Collate {
+  }
+
+  @IntDef({androidx.room.ColumnInfo.UNDEFINED, androidx.room.ColumnInfo.TEXT, androidx.room.ColumnInfo.INTEGER, androidx.room.ColumnInfo.REAL, androidx.room.ColumnInfo.BLOB}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface ColumnInfo.SQLiteTypeAffinity {
+  }
+
+  @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Dao {
+  }
+
+  @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Database {
+    method public abstract Class<?>[] entities();
+    method public abstract boolean exportSchema() default true;
+    method public abstract int version();
+    method public abstract Class<?>[] views() default {};
+  }
+
+  @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface DatabaseView {
+    method public abstract String value() default "";
+    method public abstract String viewName() default "";
+  }
+
+  @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Delete {
+    method public abstract Class<?> entity() default java.lang.Object.class;
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Embedded {
+    method public abstract String prefix() default "";
+  }
+
+  @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Entity {
+    method public abstract androidx.room.ForeignKey[] foreignKeys() default {};
+    method public abstract String[] ignoredColumns() default {};
+    method public abstract androidx.room.Index[] indices() default {};
+    method public abstract boolean inheritSuperIndices() default false;
+    method public abstract String[] primaryKeys() default {};
+    method public abstract String tableName() default "";
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ForeignKey {
+    method public abstract String[] childColumns();
+    method public abstract boolean deferred() default false;
+    method public abstract Class<?> entity();
+    method @androidx.room.ForeignKey.Action public abstract int onDelete() default androidx.room.ForeignKey.NO_ACTION;
+    method @androidx.room.ForeignKey.Action public abstract int onUpdate() default androidx.room.ForeignKey.NO_ACTION;
+    method public abstract String[] parentColumns();
+    field public static final int CASCADE = 5; // 0x5
+    field public static final int NO_ACTION = 1; // 0x1
+    field public static final int RESTRICT = 2; // 0x2
+    field public static final int SET_DEFAULT = 4; // 0x4
+    field public static final int SET_NULL = 3; // 0x3
+  }
+
+  @IntDef({androidx.room.ForeignKey.NO_ACTION, androidx.room.ForeignKey.RESTRICT, androidx.room.ForeignKey.SET_NULL, androidx.room.ForeignKey.SET_DEFAULT, androidx.room.ForeignKey.CASCADE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface ForeignKey.Action {
+  }
+
+  @RequiresApi(16) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Fts3 {
+    method public abstract String tokenizer() default androidx.room.FtsOptions.TOKENIZER_SIMPLE;
+    method public abstract String[] tokenizerArgs() default {};
+  }
+
+  @RequiresApi(16) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Fts4 {
+    method public abstract Class<?> contentEntity() default java.lang.Object.class;
+    method public abstract String languageId() default "";
+    method public abstract androidx.room.FtsOptions.MatchInfo matchInfo() default androidx.room.FtsOptions.MatchInfo.FTS4;
+    method public abstract String[] notIndexed() default {};
+    method public abstract androidx.room.FtsOptions.Order order() default androidx.room.FtsOptions.Order.ASC;
+    method public abstract int[] prefix() default {};
+    method public abstract String tokenizer() default androidx.room.FtsOptions.TOKENIZER_SIMPLE;
+    method public abstract String[] tokenizerArgs() default {};
+  }
+
+  public class FtsOptions {
+    field public static final String TOKENIZER_ICU = "icu";
+    field public static final String TOKENIZER_PORTER = "porter";
+    field public static final String TOKENIZER_SIMPLE = "simple";
+    field @RequiresApi(21) public static final String TOKENIZER_UNICODE61 = "unicode61";
+  }
+
+  public enum FtsOptions.MatchInfo {
+    enum_constant public static final androidx.room.FtsOptions.MatchInfo FTS3;
+    enum_constant public static final androidx.room.FtsOptions.MatchInfo FTS4;
+  }
+
+  public enum FtsOptions.Order {
+    enum_constant public static final androidx.room.FtsOptions.Order ASC;
+    enum_constant public static final androidx.room.FtsOptions.Order DESC;
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.CONSTRUCTOR}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Ignore {
+  }
+
+  @java.lang.annotation.Target({}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Index {
+    method public abstract String name() default "";
+    method public abstract boolean unique() default false;
+    method public abstract String[] value();
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Insert {
+    method public abstract Class<?> entity() default java.lang.Object.class;
+    method @androidx.room.OnConflictStrategy public abstract int onConflict() default androidx.room.OnConflictStrategy.ABORT;
+  }
+
+  @java.lang.annotation.Target({}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Junction {
+    method public abstract String entityColumn() default "";
+    method public abstract String parentColumn() default "";
+    method public abstract Class<?> value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @IntDef({androidx.room.OnConflictStrategy.REPLACE, androidx.room.OnConflictStrategy.ROLLBACK, androidx.room.OnConflictStrategy.ABORT, androidx.room.OnConflictStrategy.FAIL, androidx.room.OnConflictStrategy.IGNORE}) public @interface OnConflictStrategy {
+    field public static final int ABORT = 3; // 0x3
+    field @Deprecated public static final int FAIL = 4; // 0x4
+    field public static final int IGNORE = 5; // 0x5
+    field public static final int REPLACE = 1; // 0x1
+    field @Deprecated public static final int ROLLBACK = 2; // 0x2
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface PrimaryKey {
+    method public abstract boolean autoGenerate() default false;
+  }
+
+  @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Query {
+    method public abstract String value();
+  }
+
+  @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface RawQuery {
+    method public abstract Class<?>[] observedEntities() default {};
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Relation {
+    method public abstract androidx.room.Junction associateBy() default @androidx.room.Junction;
+    method public abstract Class<?> entity() default java.lang.Object.class;
+    method public abstract String entityColumn();
+    method public abstract String parentColumn();
+    method public abstract String[] projection() default {};
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class RoomMasterTable {
+    method public static String! createInsertQuery(String!);
+    field public static final String CREATE_QUERY = "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)";
+    field public static final String DEFAULT_ID = "42";
+    field public static final String NAME = "room_master_table";
+    field public static final String READ_QUERY = "SELECT identity_hash FROM room_master_table WHERE id = 42 LIMIT 1";
+    field public static final String TABLE_NAME = "room_master_table";
+  }
+
+  public class RoomWarnings {
+    ctor @Deprecated public RoomWarnings();
+    field public static final String CANNOT_CREATE_VERIFICATION_DATABASE = "ROOM_CANNOT_CREATE_VERIFICATION_DATABASE";
+    field public static final String CURSOR_MISMATCH = "ROOM_CURSOR_MISMATCH";
+    field public static final String DEFAULT_CONSTRUCTOR = "ROOM_DEFAULT_CONSTRUCTOR";
+    field public static final String INDEX_FROM_EMBEDDED_ENTITY_IS_DROPPED = "ROOM_EMBEDDED_ENTITY_INDEX_IS_DROPPED";
+    field public static final String INDEX_FROM_EMBEDDED_FIELD_IS_DROPPED = "ROOM_EMBEDDED_INDEX_IS_DROPPED";
+    field public static final String INDEX_FROM_PARENT_FIELD_IS_DROPPED = "ROOM_PARENT_FIELD_INDEX_IS_DROPPED";
+    field public static final String INDEX_FROM_PARENT_IS_DROPPED = "ROOM_PARENT_INDEX_IS_DROPPED";
+    field public static final String MISSING_INDEX_ON_FOREIGN_KEY_CHILD = "ROOM_MISSING_FOREIGN_KEY_CHILD_INDEX";
+    field public static final String MISSING_JAVA_TMP_DIR = "ROOM_MISSING_JAVA_TMP_DIR";
+    field public static final String MISSING_SCHEMA_LOCATION = "ROOM_MISSING_SCHEMA_LOCATION";
+    field public static final String PRIMARY_KEY_FROM_EMBEDDED_IS_DROPPED = "ROOM_EMBEDDED_PRIMARY_KEY_IS_DROPPED";
+    field public static final String RELATION_QUERY_WITHOUT_TRANSACTION = "ROOM_RELATION_QUERY_WITHOUT_TRANSACTION";
+    field public static final String RELATION_TYPE_MISMATCH = "ROOM_RELATION_TYPE_MISMATCH";
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface SkipQueryVerification {
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Transaction {
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface TypeConverter {
+  }
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface TypeConverters {
+    method public abstract Class<?>[] value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Update {
+    method public abstract Class<?> entity() default java.lang.Object.class;
+    method @androidx.room.OnConflictStrategy public abstract int onConflict() default androidx.room.OnConflictStrategy.ABORT;
+  }
+
+}
+
diff --git a/room/compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt b/room/compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt
index 6e7a114..0267637 100644
--- a/room/compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt
@@ -111,6 +111,7 @@
 object AndroidTypeNames {
     val CURSOR: ClassName = ClassName.get("android.database", "Cursor")
     val BUILD: ClassName = ClassName.get("android.os", "Build")
+    val CANCELLATION_SIGNAL: ClassName = ClassName.get("android.os", "CancellationSignal")
 }
 
 object CollectionTypeNames {
diff --git a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/CoroutineFlowResultBinder.kt b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/CoroutineFlowResultBinder.kt
index 127d925..3feb379 100644
--- a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/CoroutineFlowResultBinder.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/CoroutineFlowResultBinder.kt
@@ -16,18 +16,15 @@
 
 package androidx.room.solver.query.result
 
-import androidx.room.ext.AndroidTypeNames
 import androidx.room.ext.CallableTypeSpecBuilder
 import androidx.room.ext.L
 import androidx.room.ext.N
 import androidx.room.ext.RoomCoroutinesTypeNames
-import androidx.room.ext.RoomTypeNames
 import androidx.room.ext.T
 import androidx.room.ext.arrayTypeName
 import androidx.room.ext.typeName
 import androidx.room.solver.CodeGenScope
 import com.squareup.javapoet.FieldSpec
-import com.squareup.javapoet.MethodSpec
 import javax.lang.model.type.TypeMirror
 
 /**
@@ -37,25 +34,27 @@
     val typeArg: TypeMirror,
     val tableNames: Set<String>,
     adapter: QueryResultAdapter?
-) : QueryResultBinder(adapter) {
+) : BaseObservableQueryResultBinder(adapter) {
 
     override fun convertAndReturn(
         roomSQLiteQueryVar: String,
         canReleaseQuery: Boolean,
         dbField: FieldSpec,
         inTransaction: Boolean,
-        scope: CodeGenScope,
-        cancellationSignalVar: String
+        scope: CodeGenScope
     ) {
         val callableImpl = CallableTypeSpecBuilder(typeArg.typeName()) {
             createRunQueryAndReturnStatements(
                 builder = this,
                 roomSQLiteQueryVar = roomSQLiteQueryVar,
-                canReleaseQuery = canReleaseQuery,
                 dbField = dbField,
                 inTransaction = inTransaction,
                 scope = scope,
-                cancellationSignalVar = cancellationSignalVar)
+                cancellationSignalVar = "null")
+        }.apply {
+            if (canReleaseQuery) {
+                addMethod(createFinalizeMethod(roomSQLiteQueryVar))
+            }
         }.build()
 
         scope.builder().apply {
@@ -70,49 +69,4 @@
                 callableImpl)
         }
     }
-
-    private fun createRunQueryAndReturnStatements(
-        builder: MethodSpec.Builder,
-        roomSQLiteQueryVar: String,
-        canReleaseQuery: Boolean,
-        dbField: FieldSpec,
-        inTransaction: Boolean,
-        scope: CodeGenScope,
-        cancellationSignalVar: String
-    ) {
-        val transactionWrapper = if (inTransaction) {
-            builder.transactionWrapper(dbField)
-        } else {
-            null
-        }
-        val shouldCopyCursor = adapter?.shouldCopyCursor() == true
-        val outVar = scope.getTmpVar("_result")
-        val cursorVar = scope.getTmpVar("_cursor")
-        transactionWrapper?.beginTransactionWithControlFlow()
-        builder.apply {
-            addStatement("final $T $L = $T.query($N, $L, $L, $L)",
-                AndroidTypeNames.CURSOR,
-                cursorVar,
-                RoomTypeNames.DB_UTIL,
-                dbField,
-                roomSQLiteQueryVar,
-                if (shouldCopyCursor) "true" else "false",
-                cancellationSignalVar)
-            beginControlFlow("try").apply {
-                val adapterScope = scope.fork()
-                adapter?.convert(outVar, cursorVar, adapterScope)
-                addCode(adapterScope.builder().build())
-                transactionWrapper?.commitTransaction()
-                addStatement("return $L", outVar)
-            }
-            nextControlFlow("finally").apply {
-                addStatement("$L.close()", cursorVar)
-                if (canReleaseQuery) {
-                    addStatement("$L.release()", roomSQLiteQueryVar)
-                }
-            }
-            endControlFlow()
-        }
-        transactionWrapper?.endTransactionWithControlFlow()
-    }
 }
\ No newline at end of file
diff --git a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/CoroutineResultBinder.kt b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/CoroutineResultBinder.kt
index 906db3b..f9a5eaa 100644
--- a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/CoroutineResultBinder.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/CoroutineResultBinder.kt
@@ -43,8 +43,7 @@
         canReleaseQuery: Boolean,
         dbField: FieldSpec,
         inTransaction: Boolean,
-        scope: CodeGenScope,
-        cancellationSignalVar: String
+        scope: CodeGenScope
     ) {
         val callableImpl = CallableTypeSpecBuilder(typeArg.typeName()) {
             createRunQueryAndReturnStatements(
@@ -54,7 +53,7 @@
                 dbField = dbField,
                 inTransaction = inTransaction,
                 scope = scope,
-                cancellationSignalVar = cancellationSignalVar)
+                cancellationSignalVar = "null")
         }.build()
 
         scope.builder().apply {
diff --git a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/CursorQueryResultBinder.kt b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/CursorQueryResultBinder.kt
index 9e9eb9c..9f8c9e7 100644
--- a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/CursorQueryResultBinder.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/CursorQueryResultBinder.kt
@@ -29,8 +29,7 @@
         canReleaseQuery: Boolean,
         dbField: FieldSpec,
         inTransaction: Boolean,
-        scope: CodeGenScope,
-        cancellationSignalVar: String
+        scope: CodeGenScope
     ) {
         val builder = scope.builder()
         val transactionWrapper = if (inTransaction) {
diff --git a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/DataSourceFactoryQueryResultBinder.kt b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/DataSourceFactoryQueryResultBinder.kt
index 2609a29..9bf9860 100644
--- a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/DataSourceFactoryQueryResultBinder.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/DataSourceFactoryQueryResultBinder.kt
@@ -37,8 +37,7 @@
         canReleaseQuery: Boolean,
         dbField: FieldSpec,
         inTransaction: Boolean,
-        scope: CodeGenScope,
-        cancellationSignalVar: String
+        scope: CodeGenScope
     ) {
         scope.builder().apply {
             val pagedListProvider = TypeSpec
@@ -49,8 +48,7 @@
                         roomSQLiteQueryVar = roomSQLiteQueryVar,
                         dbField = dbField,
                         inTransaction = inTransaction,
-                        scope = scope,
-                        cancellationSignalVar = cancellationSignalVar))
+                        scope = scope))
             }.build()
             addStatement("return $L", pagedListProvider)
         }
@@ -60,8 +58,7 @@
         roomSQLiteQueryVar: String,
         dbField: FieldSpec,
         inTransaction: Boolean,
-        scope: CodeGenScope,
-        cancellationSignalVar: String
+        scope: CodeGenScope
     ): MethodSpec = MethodSpec.methodBuilder("create").apply {
         addAnnotation(Override::class.java)
         addModifiers(Modifier.PUBLIC)
@@ -72,8 +69,7 @@
                 canReleaseQuery = true,
                 dbField = dbField,
                 inTransaction = inTransaction,
-                scope = countedBinderScope,
-                cancellationSignalVar = cancellationSignalVar)
+                scope = countedBinderScope)
         addCode(countedBinderScope.builder().build())
     }.build()
 }
diff --git a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/GuavaListenableFutureQueryResultBinder.kt b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/GuavaListenableFutureQueryResultBinder.kt
index b3d8c2c..5a6536f 100644
--- a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/GuavaListenableFutureQueryResultBinder.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/GuavaListenableFutureQueryResultBinder.kt
@@ -16,11 +16,13 @@
 
 package androidx.room.solver.query.result
 
+import androidx.room.ext.AndroidTypeNames
 import androidx.room.ext.L
 import androidx.room.ext.N
 import androidx.room.ext.RoomGuavaTypeNames
 import androidx.room.ext.T
 import androidx.room.ext.CallableTypeSpecBuilder
+import androidx.room.ext.RoomTypeNames
 import androidx.room.ext.typeName
 import androidx.room.solver.CodeGenScope
 import com.squareup.javapoet.FieldSpec
@@ -41,9 +43,16 @@
         canReleaseQuery: Boolean,
         dbField: FieldSpec,
         inTransaction: Boolean,
-        scope: CodeGenScope,
-        cancellationSignalVar: String
+        scope: CodeGenScope
     ) {
+        val cancellationSignalVar = scope.getTmpVar("_cancellationSignal")
+        scope.builder().addStatement(
+            "final $T $L = $T.createCancellationSignal()",
+            AndroidTypeNames.CANCELLATION_SIGNAL,
+            cancellationSignalVar,
+            RoomTypeNames.DB_UTIL
+        )
+
         // Callable<T> // Note that this callable does not release the query object.
         val callableImpl = CallableTypeSpecBuilder(typeArg.typeName()) {
             createRunQueryAndReturnStatements(
@@ -58,13 +67,14 @@
 
         scope.builder().apply {
             addStatement(
-                "return $T.createListenableFuture($N, $L, $L, $L, $L)",
+                "return $T.createListenableFuture($N, $L, $L, $L, $L, $L)",
                 RoomGuavaTypeNames.GUAVA_ROOM,
                 dbField,
                 if (inTransaction) "true" else "false",
                 callableImpl,
                 roomSQLiteQueryVar,
-                canReleaseQuery
+                canReleaseQuery,
+                cancellationSignalVar
             )
         }
     }
diff --git a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/InstantQueryResultBinder.kt b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/InstantQueryResultBinder.kt
index 48e322c..89e143e 100644
--- a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/InstantQueryResultBinder.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/InstantQueryResultBinder.kt
@@ -33,8 +33,7 @@
         canReleaseQuery: Boolean,
         dbField: FieldSpec,
         inTransaction: Boolean,
-        scope: CodeGenScope,
-        cancellationSignalVar: String
+        scope: CodeGenScope
     ) {
         scope.builder().apply {
             addStatement("$N.assertNotSuspendingTransaction()", DaoWriter.dbField)
@@ -57,7 +56,7 @@
                 dbField,
                 roomSQLiteQueryVar,
                 if (shouldCopyCursor) "true" else "false",
-                cancellationSignalVar
+                "null"
             )
             beginControlFlow("try").apply {
                 adapter?.convert(outVar, cursorVar, scope)
diff --git a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/LiveDataQueryResultBinder.kt b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/LiveDataQueryResultBinder.kt
index e4e77d2..81371af 100644
--- a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/LiveDataQueryResultBinder.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/LiveDataQueryResultBinder.kt
@@ -48,8 +48,7 @@
         canReleaseQuery: Boolean,
         dbField: FieldSpec,
         inTransaction: Boolean,
-        scope: CodeGenScope,
-        cancellationSignalVar: String
+        scope: CodeGenScope
     ) {
         val callableImpl = CallableTypeSpecBuilder(typeArg.typeName()) {
             createRunQueryAndReturnStatements(
diff --git a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/PositionalDataSourceQueryResultBinder.kt b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/PositionalDataSourceQueryResultBinder.kt
index 1efee13..8ddf99f 100644
--- a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/PositionalDataSourceQueryResultBinder.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/PositionalDataSourceQueryResultBinder.kt
@@ -43,8 +43,7 @@
         canReleaseQuery: Boolean,
         dbField: FieldSpec,
         inTransaction: Boolean,
-        scope: CodeGenScope,
-        cancellationSignalVar: String
+        scope: CodeGenScope
     ) {
         // first comma for table names comes from the string since it might be empty in which case
         // we don't need a comma. If list is empty, this prevents generating bad code (it is still
diff --git a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/QueryResultBinder.kt b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/QueryResultBinder.kt
index faa3854..d3d6d8c 100644
--- a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/QueryResultBinder.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/QueryResultBinder.kt
@@ -36,7 +36,6 @@
         canReleaseQuery: Boolean, // false if query is provided by the user
         dbField: FieldSpec,
         inTransaction: Boolean,
-        scope: CodeGenScope,
-        cancellationSignalVar: String // "null" if cancellation isn't supported
+        scope: CodeGenScope
     )
 }
diff --git a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/RxCallableQueryResultBinder.kt b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/RxCallableQueryResultBinder.kt
index fc454fe..d42748a 100644
--- a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/RxCallableQueryResultBinder.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/RxCallableQueryResultBinder.kt
@@ -46,16 +46,14 @@
         canReleaseQuery: Boolean,
         dbField: FieldSpec,
         inTransaction: Boolean,
-        scope: CodeGenScope,
-        cancellationSignalVar: String
+        scope: CodeGenScope
     ) {
         val callable = CallableTypeSpecBuilder(typeArg.typeName()) {
             fillInCallMethod(
                 roomSQLiteQueryVar = roomSQLiteQueryVar,
                 dbField = dbField,
                 inTransaction = inTransaction,
-                scope = scope,
-                cancellationSignalVar = cancellationSignalVar)
+                scope = scope)
         }.apply {
             if (canReleaseQuery) {
                 addMethod(createFinalizeMethod(roomSQLiteQueryVar))
@@ -74,8 +72,7 @@
         roomSQLiteQueryVar: String,
         dbField: FieldSpec,
         inTransaction: Boolean,
-        scope: CodeGenScope,
-        cancellationSignalVar: String
+        scope: CodeGenScope
     ) {
         val adapterScope = scope.fork()
         val transactionWrapper = if (inTransaction) {
@@ -94,7 +91,7 @@
                 dbField,
                 roomSQLiteQueryVar,
                 if (shouldCopyCursor) "true" else "false",
-                cancellationSignalVar)
+                "null")
         beginControlFlow("try").apply {
             adapter?.convert(outVar, cursorVar, adapterScope)
             addCode(adapterScope.generate())
diff --git a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/RxQueryResultBinder.kt b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/RxQueryResultBinder.kt
index f042089..4bdc734 100644
--- a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/RxQueryResultBinder.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/RxQueryResultBinder.kt
@@ -43,8 +43,7 @@
         canReleaseQuery: Boolean,
         dbField: FieldSpec,
         inTransaction: Boolean,
-        scope: CodeGenScope,
-        cancellationSignalVar: String
+        scope: CodeGenScope
     ) {
         val callableImpl = CallableTypeSpecBuilder(typeArg.typeName()) {
             createRunQueryAndReturnStatements(builder = this,
@@ -52,7 +51,7 @@
                 inTransaction = inTransaction,
                 dbField = dbField,
                 scope = scope,
-                cancellationSignalVar = cancellationSignalVar)
+                cancellationSignalVar = "null")
         }.apply {
             if (canReleaseQuery) {
                 addMethod(createFinalizeMethod(roomSQLiteQueryVar))
diff --git a/room/compiler/src/main/kotlin/androidx/room/vo/Database.kt b/room/compiler/src/main/kotlin/androidx/room/vo/Database.kt
index e37ec0b..5479bff 100644
--- a/room/compiler/src/main/kotlin/androidx/room/vo/Database.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/vo/Database.kt
@@ -73,7 +73,10 @@
         val indexDescriptions = entities
                 .flatMap { entity ->
                     entity.indices.map { index ->
-                        index.createQuery(entity.tableName)
+                        // For legacy purposes we need to remove the later added 'IF NOT EXISTS'
+                        // part of the create statement, otherwise old valid legacy hashes stop
+                        // being accepted even though the schema has not changed.
+                        index.createQuery(entity.tableName).replaceFirst("IF NOT EXISTS ", "")
                     }
                 }
         val viewDescriptions = views
diff --git a/room/compiler/src/main/kotlin/androidx/room/writer/DaoWriter.kt b/room/compiler/src/main/kotlin/androidx/room/writer/DaoWriter.kt
index d3a2106..5d9dc90 100644
--- a/room/compiler/src/main/kotlin/androidx/room/writer/DaoWriter.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/writer/DaoWriter.kt
@@ -273,8 +273,7 @@
                         canReleaseQuery = shouldReleaseQuery,
                         dbField = dbField,
                         inTransaction = method.inTransaction,
-                        scope = scope,
-                        cancellationSignalVar = "null")
+                        scope = scope)
             }
             addCode(scope.builder().build())
         }.build()
@@ -425,8 +424,7 @@
                 canReleaseQuery = true,
                 dbField = dbField,
                 inTransaction = method.inTransaction,
-                scope = scope,
-                cancellationSignalVar = "null")
+                scope = scope)
         return scope.builder().build()
     }
 
diff --git a/room/compiler/src/test/data/common/input/GuavaRoom.java b/room/compiler/src/test/data/common/input/GuavaRoom.java
index 0cf7c71..2e28770 100644
--- a/room/compiler/src/test/data/common/input/GuavaRoom.java
+++ b/room/compiler/src/test/data/common/input/GuavaRoom.java
@@ -1,6 +1,24 @@
 package androidx.room.guava;
 
+import android.os.CancellationSignal;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.room.RoomDatabase;
+import androidx.room.RoomSQLiteQuery;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.Callable;
+
 // fake GuavaRoom class for tests
 public class GuavaRoom {
 
+    @NonNull
+    public static <T> ListenableFuture<T> createListenableFuture(
+            final @NonNull RoomDatabase roomDatabase,
+            final boolean inTransaction,
+            final @NonNull Callable<T> callable,
+            final @NonNull RoomSQLiteQuery query,
+            final boolean releaseQuery,
+            final @Nullable CancellationSignal cancellationSignal) {
+        return null;
+    }
 }
\ No newline at end of file
diff --git a/room/compiler/src/test/data/daoWriter/input/ComplexDao.java b/room/compiler/src/test/data/daoWriter/input/ComplexDao.java
index cdf2155..c3a4f55 100644
--- a/room/compiler/src/test/data/daoWriter/input/ComplexDao.java
+++ b/room/compiler/src/test/data/daoWriter/input/ComplexDao.java
@@ -18,6 +18,8 @@
 import androidx.room.*;
 import java.util.List;
 import androidx.lifecycle.LiveData;
+import com.google.common.util.concurrent.ListenableFuture;
+
 @Dao
 abstract class ComplexDao {
     static class FullName {
@@ -72,4 +74,7 @@
 
     @Query("SELECT * FROM Child2")
     abstract public List<Child2> getChild2List();
+
+    @Query("SELECT * FROM Child1")
+    abstract public ListenableFuture<List<Child1>> getChild1ListListenableFuture();
 }
diff --git a/room/compiler/src/test/data/daoWriter/output/ComplexDao.java b/room/compiler/src/test/data/daoWriter/output/ComplexDao.java
index 72e3734..ba5d420 100644
--- a/room/compiler/src/test/data/daoWriter/output/ComplexDao.java
+++ b/room/compiler/src/test/data/daoWriter/output/ComplexDao.java
@@ -1,12 +1,15 @@
 package foo.bar;
 
 import android.database.Cursor;
+import android.os.CancellationSignal;
 import androidx.lifecycle.LiveData;
 import androidx.room.RoomDatabase;
 import androidx.room.RoomSQLiteQuery;
+import androidx.room.guava.GuavaRoom;
 import androidx.room.util.CursorUtil;
 import androidx.room.util.DBUtil;
 import androidx.room.util.StringUtil;
+import com.google.common.util.concurrent.ListenableFuture;
 import java.lang.Exception;
 import java.lang.Integer;
 import java.lang.Override;
@@ -495,4 +498,44 @@
             _statement.release();
         }
     }
+
+    @Override
+    public ListenableFuture<List<Child1>> getChild1ListListenableFuture() {
+        final String _sql = "SELECT * FROM Child1";
+        final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
+        final CancellationSignal _cancellationSignal = DBUtil.createCancellationSignal();
+        return GuavaRoom.createListenableFuture(__db, false, new Callable<List<Child1>>() {
+            @Override
+            public List<Child1> call() throws Exception {
+                final Cursor _cursor = DBUtil.query(__db, _statement, false, _cancellationSignal);
+                try {
+                    final int _cursorIndexOfId = CursorUtil.getColumnIndexOrThrow(_cursor, "id");
+                    final int _cursorIndexOfName = CursorUtil.getColumnIndexOrThrow(_cursor, "name");
+                    final int _cursorIndexOfSerial = CursorUtil.getColumnIndexOrThrow(_cursor, "serial");
+                    final int _cursorIndexOfCode = CursorUtil.getColumnIndexOrThrow(_cursor, "code");
+                    final List<Child1> _result = new ArrayList<Child1>(_cursor.getCount());
+                    while(_cursor.moveToNext()) {
+                        final Child1 _item;
+                        final int _tmpId;
+                        _tmpId = _cursor.getInt(_cursorIndexOfId);
+                        final String _tmpName;
+                        _tmpName = _cursor.getString(_cursorIndexOfName);
+                        final Info _tmpInfo;
+                        if (! (_cursor.isNull(_cursorIndexOfSerial) && _cursor.isNull(_cursorIndexOfCode))) {
+                            _tmpInfo = new Info();
+                            _tmpInfo.serial = _cursor.getInt(_cursorIndexOfSerial);
+                            _tmpInfo.code = _cursor.getString(_cursorIndexOfCode);
+                        }  else  {
+                            _tmpInfo = null;
+                        }
+                        _item = new Child1(_tmpId,_tmpName,_tmpInfo);
+                        _result.add(_item);
+                    }
+                    return _result;
+                } finally {
+                    _cursor.close();
+                }
+            }
+        }, _statement, true, _cancellationSignal);
+    }
 }
\ No newline at end of file
diff --git a/room/compiler/src/test/kotlin/androidx/room/vo/DatabaseTest.kt b/room/compiler/src/test/kotlin/androidx/room/vo/DatabaseTest.kt
new file mode 100644
index 0000000..5d2e945
--- /dev/null
+++ b/room/compiler/src/test/kotlin/androidx/room/vo/DatabaseTest.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2019 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.room.vo
+
+import org.apache.commons.codec.digest.DigestUtils
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.Mockito.mock
+import javax.lang.model.element.Element
+import javax.lang.model.element.ExecutableElement
+import javax.lang.model.element.TypeElement
+import javax.lang.model.type.DeclaredType
+import javax.lang.model.type.TypeMirror
+
+@RunWith(JUnit4::class)
+class DatabaseTest {
+
+    @Test
+    fun indexLegacyHash() {
+        val database = Database(
+            element = mock(TypeElement::class.java),
+            type = mock(TypeMirror::class.java),
+            entities = listOf(
+                Entity(
+                    mock(TypeElement::class.java),
+                    tableName = "TheTable",
+                    type = mock(DeclaredType::class.java),
+                    fields = emptyList(),
+                    embeddedFields = emptyList(),
+                    primaryKey = PrimaryKey(mock(Element::class.java), Fields(), false),
+                    indices = listOf(
+                        Index(
+                            name = "leIndex",
+                            unique = false,
+                            fields = Fields())
+                    ),
+                    foreignKeys = emptyList(),
+                    constructor = Constructor(mock(ExecutableElement::class.java), emptyList()),
+                    shadowTableName = null
+                )
+            ),
+            views = emptyList(),
+            daoMethods = emptyList(),
+            version = 1,
+            exportSchema = false,
+            enableForeignKeys = false
+        )
+
+        val expectedLegacyHash = DigestUtils.md5Hex(
+            "CREATE TABLE IF NOT EXISTS `TheTable` ()¯\\_(ツ)_/¯" +
+                    "CREATE INDEX `leIndex` ON `TheTable` ()")
+        assertEquals(expectedLegacyHash, database.legacyIdentityHash)
+    }
+}
\ No newline at end of file
diff --git a/room/compiler/src/test/kotlin/androidx/room/writer/DaoWriterTest.kt b/room/compiler/src/test/kotlin/androidx/room/writer/DaoWriterTest.kt
index ec24403..307fe39 100644
--- a/room/compiler/src/test/kotlin/androidx/room/writer/DaoWriterTest.kt
+++ b/room/compiler/src/test/kotlin/androidx/room/writer/DaoWriterTest.kt
@@ -78,7 +78,8 @@
                 .that(jfo.toList() + COMMON.USER + COMMON.MULTI_PKEY_ENTITY + COMMON.BOOK +
                         COMMON.LIVE_DATA + COMMON.COMPUTABLE_LIVE_DATA + COMMON.SINGLE +
                         COMMON.MAYBE + COMMON.COMPLETABLE + COMMON.USER_SUMMARY + COMMON.RX2_ROOM +
-                        COMMON.PARENT + COMMON.CHILD1 + COMMON.CHILD2 + COMMON.INFO)
+                        COMMON.PARENT + COMMON.CHILD1 + COMMON.CHILD2 + COMMON.INFO +
+                        COMMON.LISTENABLE_FUTURE + COMMON.GUAVA_ROOM)
                 .processedWith(TestProcessor.builder()
                         .forAnnotations(androidx.room.Dao::class)
                         .nextRunHandler { invocation ->
diff --git a/room/compiler/src/test/kotlin/androidx/room/writer/DatabaseWriterTest.kt b/room/compiler/src/test/kotlin/androidx/room/writer/DatabaseWriterTest.kt
index fc9f6b2..45f646c 100644
--- a/room/compiler/src/test/kotlin/androidx/room/writer/DatabaseWriterTest.kt
+++ b/room/compiler/src/test/kotlin/androidx/room/writer/DatabaseWriterTest.kt
@@ -124,6 +124,6 @@
     return Truth.assertAbout(JavaSourcesSubjectFactory.javaSources())
             .that(jfo.toList() + COMMON.USER + COMMON.USER_SUMMARY + COMMON.LIVE_DATA +
                     COMMON.COMPUTABLE_LIVE_DATA + COMMON.PARENT + COMMON.CHILD1 + COMMON.CHILD2 +
-                    COMMON.INFO)
+                    COMMON.INFO + COMMON.GUAVA_ROOM + COMMON.LISTENABLE_FUTURE)
             .processedWith(RoomProcessor())
 }
diff --git a/preference/ktx/api/restricted_1.1.0-alpha06.txt b/room/guava/api/2.2.0-alpha03.txt
similarity index 100%
copy from preference/ktx/api/restricted_1.1.0-alpha06.txt
copy to room/guava/api/2.2.0-alpha03.txt
diff --git a/preference/ktx/api/res-1.1.0-alpha03.txt b/room/guava/api/res-2.2.0-alpha03.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha03.txt
copy to room/guava/api/res-2.2.0-alpha03.txt
diff --git a/room/guava/api/restricted_2.2.0-alpha02.txt b/room/guava/api/restricted_2.2.0-alpha02.txt
index 0dd91d1..b39d410 100644
--- a/room/guava/api/restricted_2.2.0-alpha02.txt
+++ b/room/guava/api/restricted_2.2.0-alpha02.txt
@@ -5,8 +5,9 @@
     method @Deprecated public static <T> com.google.common.util.concurrent.ListenableFuture<T!>! createListenableFuture(java.util.concurrent.Callable<T!>!, androidx.room.RoomSQLiteQuery!, boolean);
     method @Deprecated public static <T> com.google.common.util.concurrent.ListenableFuture<T!>! createListenableFuture(androidx.room.RoomDatabase!, java.util.concurrent.Callable<T!>!, androidx.room.RoomSQLiteQuery!, boolean);
     method public static <T> com.google.common.util.concurrent.ListenableFuture<T!>! createListenableFuture(androidx.room.RoomDatabase!, boolean, java.util.concurrent.Callable<T!>!, androidx.room.RoomSQLiteQuery!, boolean);
-    method @Deprecated public static <T> com.google.common.util.concurrent.ListenableFuture<T!>! createListenableFuture(androidx.room.RoomDatabase!, java.util.concurrent.Callable<T!>!);
-    method public static <T> com.google.common.util.concurrent.ListenableFuture<T!>! createListenableFuture(androidx.room.RoomDatabase!, boolean, java.util.concurrent.Callable<T!>!);
+    method public static <T> com.google.common.util.concurrent.ListenableFuture<T!> createListenableFuture(androidx.room.RoomDatabase, boolean, java.util.concurrent.Callable<T!>, androidx.room.RoomSQLiteQuery, boolean, android.os.CancellationSignal?);
+    method @Deprecated public static <T> com.google.common.util.concurrent.ListenableFuture<T!> createListenableFuture(androidx.room.RoomDatabase, java.util.concurrent.Callable<T!>);
+    method public static <T> com.google.common.util.concurrent.ListenableFuture<T!> createListenableFuture(androidx.room.RoomDatabase, boolean, java.util.concurrent.Callable<T!>);
   }
 
 }
diff --git a/room/guava/api/restricted_2.2.0-alpha03.txt b/room/guava/api/restricted_2.2.0-alpha03.txt
new file mode 100644
index 0000000..b39d410
--- /dev/null
+++ b/room/guava/api/restricted_2.2.0-alpha03.txt
@@ -0,0 +1,14 @@
+// Signature format: 3.0
+package androidx.room.guava {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class GuavaRoom {
+    method @Deprecated public static <T> com.google.common.util.concurrent.ListenableFuture<T!>! createListenableFuture(java.util.concurrent.Callable<T!>!, androidx.room.RoomSQLiteQuery!, boolean);
+    method @Deprecated public static <T> com.google.common.util.concurrent.ListenableFuture<T!>! createListenableFuture(androidx.room.RoomDatabase!, java.util.concurrent.Callable<T!>!, androidx.room.RoomSQLiteQuery!, boolean);
+    method public static <T> com.google.common.util.concurrent.ListenableFuture<T!>! createListenableFuture(androidx.room.RoomDatabase!, boolean, java.util.concurrent.Callable<T!>!, androidx.room.RoomSQLiteQuery!, boolean);
+    method public static <T> com.google.common.util.concurrent.ListenableFuture<T!> createListenableFuture(androidx.room.RoomDatabase, boolean, java.util.concurrent.Callable<T!>, androidx.room.RoomSQLiteQuery, boolean, android.os.CancellationSignal?);
+    method @Deprecated public static <T> com.google.common.util.concurrent.ListenableFuture<T!> createListenableFuture(androidx.room.RoomDatabase, java.util.concurrent.Callable<T!>);
+    method public static <T> com.google.common.util.concurrent.ListenableFuture<T!> createListenableFuture(androidx.room.RoomDatabase, boolean, java.util.concurrent.Callable<T!>);
+  }
+
+}
+
diff --git a/room/guava/api/restricted_current.txt b/room/guava/api/restricted_current.txt
index 0dd91d1..b39d410 100644
--- a/room/guava/api/restricted_current.txt
+++ b/room/guava/api/restricted_current.txt
@@ -5,8 +5,9 @@
     method @Deprecated public static <T> com.google.common.util.concurrent.ListenableFuture<T!>! createListenableFuture(java.util.concurrent.Callable<T!>!, androidx.room.RoomSQLiteQuery!, boolean);
     method @Deprecated public static <T> com.google.common.util.concurrent.ListenableFuture<T!>! createListenableFuture(androidx.room.RoomDatabase!, java.util.concurrent.Callable<T!>!, androidx.room.RoomSQLiteQuery!, boolean);
     method public static <T> com.google.common.util.concurrent.ListenableFuture<T!>! createListenableFuture(androidx.room.RoomDatabase!, boolean, java.util.concurrent.Callable<T!>!, androidx.room.RoomSQLiteQuery!, boolean);
-    method @Deprecated public static <T> com.google.common.util.concurrent.ListenableFuture<T!>! createListenableFuture(androidx.room.RoomDatabase!, java.util.concurrent.Callable<T!>!);
-    method public static <T> com.google.common.util.concurrent.ListenableFuture<T!>! createListenableFuture(androidx.room.RoomDatabase!, boolean, java.util.concurrent.Callable<T!>!);
+    method public static <T> com.google.common.util.concurrent.ListenableFuture<T!> createListenableFuture(androidx.room.RoomDatabase, boolean, java.util.concurrent.Callable<T!>, androidx.room.RoomSQLiteQuery, boolean, android.os.CancellationSignal?);
+    method @Deprecated public static <T> com.google.common.util.concurrent.ListenableFuture<T!> createListenableFuture(androidx.room.RoomDatabase, java.util.concurrent.Callable<T!>);
+    method public static <T> com.google.common.util.concurrent.ListenableFuture<T!> createListenableFuture(androidx.room.RoomDatabase, boolean, java.util.concurrent.Callable<T!>);
   }
 
 }
diff --git a/room/guava/build.gradle b/room/guava/build.gradle
index 3cbd76e..4de80a2 100644
--- a/room/guava/build.gradle
+++ b/room/guava/build.gradle
@@ -34,6 +34,8 @@
 
     api(SUPPORT_ANNOTATIONS)
     api(GUAVA_ANDROID)
+    androidTestImplementation(ANDROIDX_TEST_RUNNER)
+    androidTestImplementation(TRUTH)
 }
 
 androidx {
diff --git a/room/guava/src/androidTest/java/androidx/room/guava/GuavaRoomTest.java b/room/guava/src/androidTest/java/androidx/room/guava/GuavaRoomTest.java
new file mode 100644
index 0000000..653a6b9
--- /dev/null
+++ b/room/guava/src/androidTest/java/androidx/room/guava/GuavaRoomTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2019 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.room.guava;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.CancellationSignal;
+
+import androidx.annotation.NonNull;
+import androidx.room.DatabaseConfiguration;
+import androidx.room.InvalidationTracker;
+import androidx.room.RoomDatabase;
+import androidx.sqlite.db.SupportSQLiteOpenHelper;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.junit.Test;
+
+import java.util.concurrent.Executor;
+
+@SmallTest
+public class GuavaRoomTest {
+
+    @Test
+    @SdkSuppress(minSdkVersion = 16)
+    public void queryIsCancelled() {
+        Executor executor = runnable -> { /* nothing to do */ };
+
+        CancellationSignal signal = new CancellationSignal();
+        ListenableFuture<Integer> future = GuavaRoom.createListenableFuture(
+                new TestDatabase(executor), false, () -> 1, null, false, signal);
+
+        future.cancel(true);
+
+        assertThat(signal.isCanceled()).isTrue();
+    }
+
+    private static class TestDatabase extends RoomDatabase {
+
+        private final Executor mTestExecutor;
+
+        private TestDatabase(Executor testExecutor) {
+            mTestExecutor = testExecutor;
+        }
+
+        @NonNull
+        @Override
+        public Executor getQueryExecutor() {
+            return mTestExecutor;
+        }
+
+        @NonNull
+        @Override
+        protected SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration config) {
+            throw new UnsupportedOperationException("Shouldn't be called!");
+        }
+
+        @NonNull
+        @Override
+        protected InvalidationTracker createInvalidationTracker() {
+            return null;
+        }
+
+        @Override
+        public void clearAllTables() {
+            throw new UnsupportedOperationException("Shouldn't be called!");
+        }
+    }
+
+}
diff --git a/room/guava/src/main/java/androidx/room/guava/GuavaRoom.java b/room/guava/src/main/java/androidx/room/guava/GuavaRoom.java
index 4e2f500..4665165 100644
--- a/room/guava/src/main/java/androidx/room/guava/GuavaRoom.java
+++ b/room/guava/src/main/java/androidx/room/guava/GuavaRoom.java
@@ -18,7 +18,11 @@
 import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
 
 import android.annotation.SuppressLint;
+import android.os.Build;
+import android.os.CancellationSignal;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.arch.core.executor.ArchTaskExecutor;
 import androidx.room.RoomDatabase;
@@ -49,7 +53,7 @@
      * {@link ArchTaskExecutor}'s background-threaded Executor.
      *
      * @deprecated Use {@link #createListenableFuture(RoomDatabase, boolean, Callable,
-     *             RoomSQLiteQuery, boolean)}
+     *             RoomSQLiteQuery, boolean, CancellationSignal)}
      */
     @Deprecated
     public static <T> ListenableFuture<T> createListenableFuture(
@@ -57,7 +61,7 @@
             final RoomSQLiteQuery query,
             final boolean releaseQuery) {
         return createListenableFuture(
-                ArchTaskExecutor.getIOThreadExecutor(), callable, query, releaseQuery);
+                ArchTaskExecutor.getIOThreadExecutor(), callable, query, releaseQuery, null);
     }
 
     /**
@@ -65,7 +69,7 @@
      * {@link RoomDatabase}'s {@link java.util.concurrent.Executor}.
      *
      * @deprecated Use {@link #createListenableFuture(RoomDatabase, boolean, Callable,
-     *             RoomSQLiteQuery, boolean)}
+     *             RoomSQLiteQuery, boolean, CancellationSignal)}
      */
     @Deprecated
     public static <T> ListenableFuture<T> createListenableFuture(
@@ -74,13 +78,14 @@
             final RoomSQLiteQuery query,
             final boolean releaseQuery) {
         return createListenableFuture(
-                roomDatabase.getQueryExecutor(), callable, query, releaseQuery);
+                roomDatabase.getQueryExecutor(), callable, query, releaseQuery, null);
     }
 
     /**
      * Returns a {@link ListenableFuture<T>} created by submitting the input {@code callable} to
      * {@link RoomDatabase}'s {@link java.util.concurrent.Executor}.
      */
+    @SuppressLint("LambdaLast")
     public static <T> ListenableFuture<T> createListenableFuture(
             final RoomDatabase roomDatabase,
             final boolean inTransaction,
@@ -88,15 +93,43 @@
             final RoomSQLiteQuery query,
             final boolean releaseQuery) {
         return createListenableFuture(
-                getExecutor(roomDatabase, inTransaction), callable, query, releaseQuery);
+                getExecutor(roomDatabase, inTransaction), callable, query, releaseQuery, null);
+    }
+
+    /**
+     * Returns a {@link ListenableFuture<T>} created by submitting the input {@code callable} to
+     * {@link RoomDatabase}'s {@link java.util.concurrent.Executor}.
+     */
+    @NonNull
+    public static <T> ListenableFuture<T> createListenableFuture(
+            final @NonNull RoomDatabase roomDatabase,
+            final boolean inTransaction,
+            final @NonNull Callable<T> callable,
+            final @NonNull RoomSQLiteQuery query,
+            final boolean releaseQuery,
+            final @Nullable CancellationSignal cancellationSignal) {
+        return createListenableFuture(
+                getExecutor(roomDatabase, inTransaction), callable, query, releaseQuery,
+                cancellationSignal);
     }
 
     private static <T> ListenableFuture<T> createListenableFuture(
             final Executor executor,
             final Callable<T> callable,
             final RoomSQLiteQuery query,
-            final boolean releaseQuery) {
+            final boolean releaseQuery,
+            final @Nullable CancellationSignal cancellationSignal) {
         ListenableFutureTask<T> listenableFutureTask = ListenableFutureTask.create(callable);
+        if (cancellationSignal != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+            listenableFutureTask.addListener(new Runnable() {
+                @Override
+                public void run() {
+                    if (listenableFutureTask.isCancelled()) {
+                        cancellationSignal.cancel();
+                    }
+                }
+            }, directExecutor());
+        }
         executor.execute(listenableFutureTask);
 
         if (releaseQuery) {
@@ -126,9 +159,10 @@
      * @deprecated Use {@link #createListenableFuture(RoomDatabase, boolean, Callable)}
      */
     @Deprecated
+    @NonNull
     public static <T> ListenableFuture<T> createListenableFuture(
-            final RoomDatabase roomDatabase,
-            final Callable<T> callable) {
+            final @NonNull RoomDatabase roomDatabase,
+            final @NonNull Callable<T> callable) {
         return createListenableFuture(roomDatabase, false, callable);
     }
 
@@ -136,10 +170,11 @@
      * Returns a {@link ListenableFuture<T>} created by submitting the input {@code callable} to
      * {@link RoomDatabase}'s {@link java.util.concurrent.Executor}.
      */
+    @NonNull
     public static <T> ListenableFuture<T> createListenableFuture(
-            final RoomDatabase roomDatabase,
+            final @NonNull RoomDatabase roomDatabase,
             final boolean inTransaction,
-            final Callable<T> callable) {
+            final @NonNull Callable<T> callable) {
         ListenableFutureTask<T> listenableFutureTask = ListenableFutureTask.create(callable);
         getExecutor(roomDatabase, inTransaction).execute(listenableFutureTask);
         return listenableFutureTask;
diff --git a/room/integration-tests/kotlintestapp/schemas/androidx.room.integration.kotlintestapp.migration.MigrationDbKotlin/7.json b/room/integration-tests/kotlintestapp/schemas/androidx.room.integration.kotlintestapp.migration.MigrationDbKotlin/7.json
index 110d60d..78ce189 100644
--- a/room/integration-tests/kotlintestapp/schemas/androidx.room.integration.kotlintestapp.migration.MigrationDbKotlin/7.json
+++ b/room/integration-tests/kotlintestapp/schemas/androidx.room.integration.kotlintestapp.migration.MigrationDbKotlin/7.json
@@ -2,7 +2,7 @@
   "formatVersion": 1,
   "database": {
     "version": 7,
-    "identityHash": "7c65736dc87e4f5bf7bf54e1ef798ec2",
+    "identityHash": "5653c29453937d8e34dc031af1ab4c7d",
     "entities": [
       {
         "tableName": "Entity1",
@@ -110,10 +110,9 @@
         ]
       }
     ],
-    "views": [],
     "setupQueries": [
       "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
-      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7c65736dc87e4f5bf7bf54e1ef798ec2')"
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"5653c29453937d8e34dc031af1ab4c7d\")"
     ]
   }
 }
\ No newline at end of file
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/FlowQueryTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/FlowQueryTest.kt
index 0abc393..fb56ad1 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/FlowQueryTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/FlowQueryTest.kt
@@ -37,7 +37,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import java.util.concurrent.CountDownLatch
-import java.util.concurrent.Phaser
 import java.util.concurrent.TimeUnit
 
 @MediumTest
@@ -90,28 +89,29 @@
         booksDao.addPublishers(TestUtil.PUBLISHER)
         booksDao.addBooks(TestUtil.BOOK_1, TestUtil.BOOK_2)
 
-        val barrier = Phaser(2)
+        val firstResultLatch = CountDownLatch(1)
+        val secondResultLatch = CountDownLatch(1)
         val results = mutableListOf<List<Book>>()
         val job = async(Dispatchers.IO) {
             booksDao.getBooksFlow().collect {
                 when (results.size) {
                     0 -> {
                         results.add(it)
-                        barrier.arrive()
+                        firstResultLatch.countDown()
                     }
                     1 -> {
                         results.add(it)
-                        barrier.arrive()
+                        secondResultLatch.countDown()
                     }
                     else -> fail("Should have only collected 2 results.")
                 }
             }
         }
 
-        barrier.arriveAndAwaitAdvance()
+        firstResultLatch.await()
         booksDao.insertBookSuspend(TestUtil.BOOK_3)
 
-        barrier.arriveAndAwaitAdvance()
+        secondResultLatch.await()
         assertThat(results.size).isEqualTo(2)
         assertThat(results[0])
             .isEqualTo(listOf(TestUtil.BOOK_1, TestUtil.BOOK_2))
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingQueryTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingQueryTest.kt
index 6c1b231..9d2ce74 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingQueryTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingQueryTest.kt
@@ -786,7 +786,7 @@
                     object : SupportSQLiteOpenHelper.Factory {
                         val factoryDelegate = FrameworkSQLiteOpenHelperFactory()
                         override fun create(
-                            configuration: SupportSQLiteOpenHelper.Configuration?
+                            configuration: SupportSQLiteOpenHelper.Configuration
                         ): SupportSQLiteOpenHelper {
                             val helperDelegate = factoryDelegate.create(configuration)
                             return object : SupportSQLiteOpenHelper by helperDelegate {
diff --git a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/CustomDatabaseTest.java b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/CustomDatabaseTest.java
index 31d078d..77e9a7e 100644
--- a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/CustomDatabaseTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/CustomDatabaseTest.java
@@ -26,6 +26,7 @@
 import android.database.sqlite.SQLiteException;
 import android.os.SystemClock;
 
+import androidx.annotation.NonNull;
 import androidx.room.Room;
 import androidx.room.RoomDatabase;
 import androidx.room.integration.testapp.database.Customer;
@@ -76,8 +77,10 @@
      */
     private static class RethrowExceptionFactory implements SupportSQLiteOpenHelper.Factory {
 
+        @NonNull
         @Override
-        public SupportSQLiteOpenHelper create(SupportSQLiteOpenHelper.Configuration configuration) {
+        public SupportSQLiteOpenHelper create(
+                @NonNull SupportSQLiteOpenHelper.Configuration configuration) {
             final FrameworkSQLiteOpenHelperFactory factory = new FrameworkSQLiteOpenHelperFactory();
             final SupportSQLiteOpenHelper helper = factory.create(configuration);
             SupportSQLiteOpenHelper helperMock = mock(SupportSQLiteOpenHelper.class,
diff --git a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/DatabaseCallbackTest.java b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/DatabaseCallbackTest.java
index 8a56860..1e9c3df 100644
--- a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/DatabaseCallbackTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/DatabaseCallbackTest.java
@@ -41,7 +41,6 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
-import androidx.test.filters.SmallTest;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -52,11 +51,11 @@
 import java.util.ArrayList;
 import java.util.List;
 
+@MediumTest
 @RunWith(AndroidJUnit4.class)
 public class DatabaseCallbackTest {
 
     @Test
-    @MediumTest
     public void createAndOpen() {
         Context context = ApplicationProvider.getApplicationContext();
         TestDatabaseCallback callback1 = new TestDatabaseCallback();
@@ -95,7 +94,6 @@
     }
 
     @Test
-    @SmallTest
     public void writeOnCreate() {
         Context context = ApplicationProvider.getApplicationContext();
         TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class)
@@ -124,7 +122,6 @@
     }
 
     @Test
-    @SmallTest
     public void exceptionOnCreate() {
         Context context = ApplicationProvider.getApplicationContext();
         TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class)
@@ -155,7 +152,6 @@
     }
 
     @Test
-    @MediumTest
     public void corruptExceptionOnCreate() throws IOException {
         Context context = ApplicationProvider.getApplicationContext();
 
@@ -188,7 +184,6 @@
     }
 
     @Test
-    @SmallTest
     public void onDestructiveMigration_calledOnUpgrade() {
         Context context = ApplicationProvider.getApplicationContext();
         context.deleteDatabase("products.db");
diff --git a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/MultiInstanceInvalidationTest.java b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/MultiInstanceInvalidationTest.java
index 7b6dad7..0126834 100644
--- a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/MultiInstanceInvalidationTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/MultiInstanceInvalidationTest.java
@@ -190,7 +190,7 @@
 
         assertTrue(changed1.second.await(3, TimeUnit.SECONDS));
         assertTrue(changed2.second.await(3, TimeUnit.SECONDS));
-        assertFalse(changed3.second.await(300, TimeUnit.MILLISECONDS));
+        assertFalse(changed3.second.await(3, TimeUnit.SECONDS));
     }
 
     @Test
diff --git a/room/ktx/api/2.2.0-alpha03.txt b/room/ktx/api/2.2.0-alpha03.txt
new file mode 100644
index 0000000..cee69e3
--- /dev/null
+++ b/room/ktx/api/2.2.0-alpha03.txt
@@ -0,0 +1,14 @@
+// Signature format: 3.0
+package androidx.room {
+
+  public final class CoroutinesRoomKt {
+    ctor public CoroutinesRoomKt();
+  }
+
+  public final class RoomDatabaseKt {
+    ctor public RoomDatabaseKt();
+    method public static suspend <R> Object! withTransaction(androidx.room.RoomDatabase, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R> p);
+  }
+
+}
+
diff --git a/room/ktx/api/api_lint.ignore b/room/ktx/api/api_lint.ignore
new file mode 100644
index 0000000..3cbc9d4
--- /dev/null
+++ b/room/ktx/api/api_lint.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+MissingNullability: androidx.room.RoomDatabaseKt#withTransaction(androidx.room.RoomDatabase, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super R>,?>, kotlin.coroutines.Continuation<? super R>):
+    Missing nullability on method `withTransaction` return
diff --git a/preference/ktx/api/res-1.1.0-alpha03.txt b/room/ktx/api/res-2.2.0-alpha03.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha03.txt
copy to room/ktx/api/res-2.2.0-alpha03.txt
diff --git a/room/ktx/api/restricted_2.2.0-alpha03.txt b/room/ktx/api/restricted_2.2.0-alpha03.txt
new file mode 100644
index 0000000..20837edc
--- /dev/null
+++ b/room/ktx/api/restricted_2.2.0-alpha03.txt
@@ -0,0 +1,25 @@
+// Signature format: 3.0
+package androidx.room {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class CoroutinesRoom {
+    method public static <R> kotlinx.coroutines.flow.Flow<R> createFlow(androidx.room.RoomDatabase db, boolean inTransaction, String![] tableNames, java.util.concurrent.Callable<R> callable);
+    method public static suspend <R> Object! execute(androidx.room.RoomDatabase p, boolean db, java.util.concurrent.Callable<R> inTransaction, kotlin.coroutines.Continuation<? super R> callable);
+    field public static final androidx.room.CoroutinesRoom.Companion! Companion;
+  }
+
+  public static final class CoroutinesRoom.Companion {
+    method public <R> kotlinx.coroutines.flow.Flow<R> createFlow(androidx.room.RoomDatabase db, boolean inTransaction, String![] tableNames, java.util.concurrent.Callable<R> callable);
+    method public suspend <R> Object! execute(androidx.room.RoomDatabase db, boolean inTransaction, java.util.concurrent.Callable<R> callable, kotlin.coroutines.Continuation<? super R> p);
+  }
+
+  public final class CoroutinesRoomKt {
+    ctor public CoroutinesRoomKt();
+  }
+
+  public final class RoomDatabaseKt {
+    ctor public RoomDatabaseKt();
+    method public static suspend <R> Object! withTransaction(androidx.room.RoomDatabase, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R> p);
+  }
+
+}
+
diff --git a/preference/ktx/api/restricted_1.1.0-alpha06.txt b/room/migration/api/2.2.0-alpha03.txt
similarity index 100%
copy from preference/ktx/api/restricted_1.1.0-alpha06.txt
copy to room/migration/api/2.2.0-alpha03.txt
diff --git a/room/migration/api/restricted_2.2.0-alpha03.txt b/room/migration/api/restricted_2.2.0-alpha03.txt
new file mode 100644
index 0000000..ae8f58d
--- /dev/null
+++ b/room/migration/api/restricted_2.2.0-alpha03.txt
@@ -0,0 +1,107 @@
+// Signature format: 3.0
+package androidx.room.migration.bundle {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class BundleUtil {
+    field public static final String TABLE_NAME_PLACEHOLDER = "${TABLE_NAME}";
+    field public static final String VIEW_NAME_PLACEHOLDER = "${VIEW_NAME}";
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class DatabaseBundle {
+    ctor public DatabaseBundle(int, String!, java.util.List<androidx.room.migration.bundle.EntityBundle!>!, java.util.List<androidx.room.migration.bundle.DatabaseViewBundle!>!, java.util.List<java.lang.String!>!);
+    ctor public DatabaseBundle();
+    method public java.util.List<java.lang.String!>! buildCreateQueries();
+    method public java.util.List<androidx.room.migration.bundle.EntityBundle!>! getEntities();
+    method public java.util.Map<java.lang.String!,androidx.room.migration.bundle.EntityBundle!>! getEntitiesByTableName();
+    method public String! getIdentityHash();
+    method public int getVersion();
+    method public java.util.List<androidx.room.migration.bundle.DatabaseViewBundle!>! getViews();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.DatabaseBundle!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class DatabaseViewBundle {
+    ctor public DatabaseViewBundle(String!, String!);
+    method public String! createView();
+    method public String! getCreateSql();
+    method public String! getViewName();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.DatabaseViewBundle!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class EntityBundle {
+    ctor public EntityBundle(String!, String!, java.util.List<androidx.room.migration.bundle.FieldBundle!>!, androidx.room.migration.bundle.PrimaryKeyBundle!, java.util.List<androidx.room.migration.bundle.IndexBundle!>!, java.util.List<androidx.room.migration.bundle.ForeignKeyBundle!>!);
+    method public java.util.Collection<java.lang.String!>! buildCreateQueries();
+    method public String! createNewTable();
+    method public String! createTable();
+    method public String! getCreateSql();
+    method public java.util.List<androidx.room.migration.bundle.FieldBundle!>! getFields();
+    method public java.util.Map<java.lang.String!,androidx.room.migration.bundle.FieldBundle!>! getFieldsByColumnName();
+    method public java.util.List<androidx.room.migration.bundle.ForeignKeyBundle!>! getForeignKeys();
+    method public java.util.List<androidx.room.migration.bundle.IndexBundle!>! getIndices();
+    method public String! getNewTableName();
+    method public androidx.room.migration.bundle.PrimaryKeyBundle! getPrimaryKey();
+    method public String! getTableName();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.EntityBundle!);
+    method public String renameToOriginal();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class FieldBundle {
+    ctor @Deprecated public FieldBundle(String!, String!, String!, boolean);
+    ctor public FieldBundle(String!, String!, String!, boolean, String!);
+    method public String! getAffinity();
+    method public String! getColumnName();
+    method public String! getDefaultValue();
+    method public String! getFieldPath();
+    method public boolean isNonNull();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.FieldBundle!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ForeignKeyBundle {
+    ctor public ForeignKeyBundle(String!, String!, String!, java.util.List<java.lang.String!>!, java.util.List<java.lang.String!>!);
+    method public java.util.List<java.lang.String!>! getColumns();
+    method public String! getOnDelete();
+    method public String! getOnUpdate();
+    method public java.util.List<java.lang.String!>! getReferencedColumns();
+    method public String! getTable();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.ForeignKeyBundle!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class FtsEntityBundle extends androidx.room.migration.bundle.EntityBundle {
+    ctor public FtsEntityBundle(String!, String!, java.util.List<androidx.room.migration.bundle.FieldBundle!>!, androidx.room.migration.bundle.PrimaryKeyBundle!, String!, androidx.room.migration.bundle.FtsOptionsBundle!, java.util.List<java.lang.String!>!);
+    method public androidx.room.migration.bundle.FtsOptionsBundle! getFtsOptions();
+    method public java.util.List<java.lang.String!>! getShadowTableNames();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class FtsOptionsBundle {
+    ctor public FtsOptionsBundle(String!, java.util.List<java.lang.String!>!, String!, String!, String!, java.util.List<java.lang.String!>!, java.util.List<java.lang.Integer!>!, String!);
+    method public String! getContentTable();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.FtsOptionsBundle!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class IndexBundle {
+    ctor public IndexBundle(String!, boolean, java.util.List<java.lang.String!>!, String!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public String! create(String!);
+    method public java.util.List<java.lang.String!>! getColumnNames();
+    method public String! getName();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.IndexBundle!);
+    method public boolean isUnique();
+    field public static final String DEFAULT_PREFIX = "index_";
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class PrimaryKeyBundle {
+    ctor public PrimaryKeyBundle(boolean, java.util.List<java.lang.String!>!);
+    method public java.util.List<java.lang.String!>! getColumnNames();
+    method public boolean isAutoGenerate();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.PrimaryKeyBundle!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class SchemaBundle {
+    ctor public SchemaBundle(int, androidx.room.migration.bundle.DatabaseBundle!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.room.migration.bundle.SchemaBundle! deserialize(java.io.InputStream!) throws java.io.UnsupportedEncodingException;
+    method public androidx.room.migration.bundle.DatabaseBundle! getDatabase();
+    method public int getFormatVersion();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.SchemaBundle!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void serialize(androidx.room.migration.bundle.SchemaBundle!, java.io.File!) throws java.io.IOException;
+    field public static final int LATEST_FORMAT = 1; // 0x1
+  }
+
+}
+
diff --git a/room/runtime/api/2.2.0-alpha03.txt b/room/runtime/api/2.2.0-alpha03.txt
new file mode 100644
index 0000000..1d210e5
--- /dev/null
+++ b/room/runtime/api/2.2.0-alpha03.txt
@@ -0,0 +1,117 @@
+// Signature format: 3.0
+package androidx.room {
+
+  public class DatabaseConfiguration {
+    method public boolean isMigrationRequired(int, int);
+    method @Deprecated public boolean isMigrationRequiredFrom(int);
+    field public final boolean allowDestructiveMigrationOnDowngrade;
+    field public final boolean allowMainThreadQueries;
+    field public final java.util.List<androidx.room.RoomDatabase.Callback!>? callbacks;
+    field public final android.content.Context context;
+    field public final String? copyFromAssetPath;
+    field public final java.io.File? copyFromFile;
+    field public final androidx.room.RoomDatabase.JournalMode! journalMode;
+    field public final androidx.room.RoomDatabase.MigrationContainer migrationContainer;
+    field public final boolean multiInstanceInvalidation;
+    field public final String? name;
+    field public final java.util.concurrent.Executor queryExecutor;
+    field public final boolean requireMigration;
+    field public final androidx.sqlite.db.SupportSQLiteOpenHelper.Factory sqliteOpenHelperFactory;
+    field public final java.util.concurrent.Executor transactionExecutor;
+  }
+
+  public class InvalidationTracker {
+    method @WorkerThread public void addObserver(androidx.room.InvalidationTracker.Observer);
+    method public void refreshVersionsAsync();
+    method @WorkerThread public void removeObserver(androidx.room.InvalidationTracker.Observer);
+  }
+
+  public abstract static class InvalidationTracker.Observer {
+    ctor protected InvalidationTracker.Observer(String, java.lang.String!...);
+    ctor public InvalidationTracker.Observer(String![]);
+    method public abstract void onInvalidated(java.util.Set<java.lang.String!>);
+  }
+
+  public class Room {
+    ctor @Deprecated public Room();
+    method public static <T extends androidx.room.RoomDatabase> androidx.room.RoomDatabase.Builder<T!> databaseBuilder(android.content.Context, Class<T!>, String);
+    method public static <T extends androidx.room.RoomDatabase> androidx.room.RoomDatabase.Builder<T!> inMemoryDatabaseBuilder(android.content.Context, Class<T!>);
+    field public static final String MASTER_TABLE_NAME = "room_master_table";
+  }
+
+  public abstract class RoomDatabase {
+    ctor public RoomDatabase();
+    method @Deprecated public void beginTransaction();
+    method @WorkerThread public abstract void clearAllTables();
+    method public void close();
+    method public androidx.sqlite.db.SupportSQLiteStatement! compileStatement(String);
+    method protected abstract androidx.room.InvalidationTracker createInvalidationTracker();
+    method protected abstract androidx.sqlite.db.SupportSQLiteOpenHelper createOpenHelper(androidx.room.DatabaseConfiguration!);
+    method @Deprecated public void endTransaction();
+    method public androidx.room.InvalidationTracker getInvalidationTracker();
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper getOpenHelper();
+    method public java.util.concurrent.Executor getQueryExecutor();
+    method public java.util.concurrent.Executor getTransactionExecutor();
+    method public boolean inTransaction();
+    method @CallSuper public void init(androidx.room.DatabaseConfiguration);
+    method protected void internalInitInvalidationTracker(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public boolean isOpen();
+    method public android.database.Cursor query(String, Object![]?);
+    method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery);
+    method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery, android.os.CancellationSignal?);
+    method public void runInTransaction(Runnable);
+    method public <V> V! runInTransaction(java.util.concurrent.Callable<V!>);
+    method @Deprecated public void setTransactionSuccessful();
+    field @Deprecated protected java.util.List<androidx.room.RoomDatabase.Callback!>? mCallbacks;
+    field @Deprecated protected volatile androidx.sqlite.db.SupportSQLiteDatabase! mDatabase;
+  }
+
+  public static class RoomDatabase.Builder<T extends androidx.room.RoomDatabase> {
+    method public androidx.room.RoomDatabase.Builder<T!> addCallback(androidx.room.RoomDatabase.Callback);
+    method public androidx.room.RoomDatabase.Builder<T!> addMigrations(androidx.room.migration.Migration!...);
+    method public androidx.room.RoomDatabase.Builder<T!> allowMainThreadQueries();
+    method public T build();
+    method public androidx.room.RoomDatabase.Builder<T!> createFromAsset(String);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromFile(java.io.File);
+    method public androidx.room.RoomDatabase.Builder<T!> enableMultiInstanceInvalidation();
+    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigration();
+    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationFrom(int...);
+    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationOnDowngrade();
+    method public androidx.room.RoomDatabase.Builder<T!> openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory?);
+    method public androidx.room.RoomDatabase.Builder<T!> setJournalMode(androidx.room.RoomDatabase.JournalMode);
+    method public androidx.room.RoomDatabase.Builder<T!> setQueryExecutor(java.util.concurrent.Executor);
+    method public androidx.room.RoomDatabase.Builder<T!> setTransactionExecutor(java.util.concurrent.Executor);
+  }
+
+  public abstract static class RoomDatabase.Callback {
+    ctor public RoomDatabase.Callback();
+    method public void onCreate(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onDestructiveMigration(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase);
+  }
+
+  public enum RoomDatabase.JournalMode {
+    enum_constant public static final androidx.room.RoomDatabase.JournalMode AUTOMATIC;
+    enum_constant public static final androidx.room.RoomDatabase.JournalMode TRUNCATE;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.JELLY_BEAN) public static final androidx.room.RoomDatabase.JournalMode WRITE_AHEAD_LOGGING;
+  }
+
+  public static class RoomDatabase.MigrationContainer {
+    ctor public RoomDatabase.MigrationContainer();
+    method public void addMigrations(androidx.room.migration.Migration!...);
+    method public java.util.List<androidx.room.migration.Migration!>? findMigrationPath(int, int);
+  }
+
+}
+
+package androidx.room.migration {
+
+  public abstract class Migration {
+    ctor public Migration(int, int);
+    method public abstract void migrate(androidx.sqlite.db.SupportSQLiteDatabase);
+    field public final int endVersion;
+    field public final int startVersion;
+  }
+
+}
+
diff --git a/room/runtime/api/api_lint.ignore b/room/runtime/api/api_lint.ignore
index d491809..cfb48c3 100644
--- a/room/runtime/api/api_lint.ignore
+++ b/room/runtime/api/api_lint.ignore
@@ -3,5 +3,17 @@
     Class should be named Callback
 
 
+MissingNullability: androidx.room.DatabaseConfiguration#journalMode:
+    Missing nullability on field `journalMode` in class `class androidx.room.DatabaseConfiguration`
+MissingNullability: androidx.room.InvalidationTracker.Observer#Observer(String, java.lang.String...) parameter #1:
+    Missing nullability on parameter `rest` in method `Observer`
+MissingNullability: androidx.room.RoomDatabase#compileStatement(String):
+    Missing nullability on method `compileStatement` return
+MissingNullability: androidx.room.RoomDatabase#createOpenHelper(androidx.room.DatabaseConfiguration) parameter #0:
+    Missing nullability on parameter `config` in method `createOpenHelper`
+MissingNullability: androidx.room.RoomDatabase.Builder#fallbackToDestructiveMigrationFrom(int...) parameter #0:
+    Missing nullability on parameter `startVersions` in method `fallbackToDestructiveMigrationFrom`
+
+
 RegistrationName: androidx.room.RoomDatabase.Builder#addCallback(androidx.room.RoomDatabase.Callback):
     Callback methods should be named register/unregister; was addCallback
diff --git a/preference/ktx/api/res-1.1.0-alpha03.txt b/room/runtime/api/res-2.2.0-alpha03.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha03.txt
copy to room/runtime/api/res-2.2.0-alpha03.txt
diff --git a/room/runtime/api/restricted_2.2.0-alpha02.txt b/room/runtime/api/restricted_2.2.0-alpha02.txt
index 8e744d7..6bc1371 100644
--- a/room/runtime/api/restricted_2.2.0-alpha02.txt
+++ b/room/runtime/api/restricted_2.2.0-alpha02.txt
@@ -233,6 +233,7 @@
   }
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class DBUtil {
+    method public static android.os.CancellationSignal? createCancellationSignal();
     method public static void dropFtsSyncTriggers(androidx.sqlite.db.SupportSQLiteDatabase!);
     method @Deprecated public static android.database.Cursor query(androidx.room.RoomDatabase!, androidx.sqlite.db.SupportSQLiteQuery!, boolean);
     method public static android.database.Cursor query(androidx.room.RoomDatabase, androidx.sqlite.db.SupportSQLiteQuery, boolean, android.os.CancellationSignal?);
diff --git a/room/runtime/api/restricted_2.2.0-alpha03.ignore b/room/runtime/api/restricted_2.2.0-alpha03.ignore
new file mode 100644
index 0000000..6984c60
--- /dev/null
+++ b/room/runtime/api/restricted_2.2.0-alpha03.ignore
@@ -0,0 +1,19 @@
+// Baseline format: 1.0
+ChangedType: androidx.room.InvalidationTracker#createLiveData(String[], boolean, java.util.concurrent.Callable<T>):
+    Method androidx.room.InvalidationTracker.createLiveData has changed return type from LiveData<T> to androidx.lifecycle.LiveData<T>
+ChangedType: androidx.room.InvalidationTracker#createLiveData(String[], java.util.concurrent.Callable<T>):
+    Method androidx.room.InvalidationTracker.createLiveData has changed return type from LiveData<T> to androidx.lifecycle.LiveData<T>
+
+
+InvalidNullConversion: androidx.room.InvalidationTracker#createLiveData(String[], boolean, java.util.concurrent.Callable<T>):
+    Attempted to remove @NonNull annotation from method androidx.room.InvalidationTracker.createLiveData(String[],boolean,java.util.concurrent.Callable<T>)
+InvalidNullConversion: androidx.room.InvalidationTracker#createLiveData(String[], java.util.concurrent.Callable<T>):
+    Attempted to remove @NonNull annotation from method androidx.room.InvalidationTracker.createLiveData(String[],java.util.concurrent.Callable<T>)
+
+
+RemovedMethod: androidx.room.paging.LimitOffsetDataSource#isInvalid():
+    Removed method androidx.room.paging.LimitOffsetDataSource.isInvalid()
+RemovedMethod: androidx.room.paging.LimitOffsetDataSource#loadInitial(LoadInitialParams, LoadInitialCallback<T>):
+    Removed method androidx.room.paging.LimitOffsetDataSource.loadInitial(LoadInitialParams,LoadInitialCallback<T>)
+RemovedMethod: androidx.room.paging.LimitOffsetDataSource#loadRange(LoadRangeParams, LoadRangeCallback<T>):
+    Removed method androidx.room.paging.LimitOffsetDataSource.loadRange(LoadRangeParams,LoadRangeCallback<T>)
diff --git a/room/runtime/api/restricted_2.2.0-alpha03.txt b/room/runtime/api/restricted_2.2.0-alpha03.txt
new file mode 100644
index 0000000..6bc1371
--- /dev/null
+++ b/room/runtime/api/restricted_2.2.0-alpha03.txt
@@ -0,0 +1,318 @@
+// Signature format: 3.0
+package androidx.room {
+
+  public class DatabaseConfiguration {
+    ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode!, java.util.concurrent.Executor, boolean, java.util.Set<java.lang.Integer!>?);
+    ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode!, java.util.concurrent.Executor, java.util.concurrent.Executor, boolean, boolean, boolean, java.util.Set<java.lang.Integer!>?);
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode!, java.util.concurrent.Executor, java.util.concurrent.Executor, boolean, boolean, boolean, java.util.Set<java.lang.Integer!>?, String?, java.io.File?);
+    method public boolean isMigrationRequired(int, int);
+    method @Deprecated public boolean isMigrationRequiredFrom(int);
+    field public final boolean allowDestructiveMigrationOnDowngrade;
+    field public final boolean allowMainThreadQueries;
+    field public final java.util.List<androidx.room.RoomDatabase.Callback!>? callbacks;
+    field public final android.content.Context context;
+    field public final String? copyFromAssetPath;
+    field public final java.io.File? copyFromFile;
+    field public final androidx.room.RoomDatabase.JournalMode! journalMode;
+    field public final androidx.room.RoomDatabase.MigrationContainer migrationContainer;
+    field public final boolean multiInstanceInvalidation;
+    field public final String? name;
+    field public final java.util.concurrent.Executor queryExecutor;
+    field public final boolean requireMigration;
+    field public final androidx.sqlite.db.SupportSQLiteOpenHelper.Factory sqliteOpenHelperFactory;
+    field public final java.util.concurrent.Executor transactionExecutor;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class EntityDeletionOrUpdateAdapter<T> extends androidx.room.SharedSQLiteStatement {
+    ctor public EntityDeletionOrUpdateAdapter(androidx.room.RoomDatabase!);
+    method protected abstract void bind(androidx.sqlite.db.SupportSQLiteStatement!, T!);
+    method public final int handle(T!);
+    method public final int handleMultiple(Iterable<? extends T>!);
+    method public final int handleMultiple(T![]!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class EntityInsertionAdapter<T> extends androidx.room.SharedSQLiteStatement {
+    ctor public EntityInsertionAdapter(androidx.room.RoomDatabase!);
+    method protected abstract void bind(androidx.sqlite.db.SupportSQLiteStatement!, T!);
+    method public final void insert(T!);
+    method public final void insert(T![]!);
+    method public final void insert(Iterable<? extends T>!);
+    method public final long insertAndReturnId(T!);
+    method public final long[]! insertAndReturnIdsArray(java.util.Collection<? extends T>!);
+    method public final long[]! insertAndReturnIdsArray(T![]!);
+    method public final Long![]! insertAndReturnIdsArrayBox(java.util.Collection<? extends T>!);
+    method public final Long![]! insertAndReturnIdsArrayBox(T![]!);
+    method public final java.util.List<java.lang.Long!>! insertAndReturnIdsList(T![]!);
+    method public final java.util.List<java.lang.Long!>! insertAndReturnIdsList(java.util.Collection<? extends T>!);
+  }
+
+  public class InvalidationTracker {
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public InvalidationTracker(androidx.room.RoomDatabase!, java.lang.String!...);
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public InvalidationTracker(androidx.room.RoomDatabase!, java.util.Map<java.lang.String!,java.lang.String!>!, java.util.Map<java.lang.String!,java.util.Set<java.lang.String!>!>!, java.lang.String!...);
+    method @WorkerThread public void addObserver(androidx.room.InvalidationTracker.Observer);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void addWeakObserver(androidx.room.InvalidationTracker.Observer!);
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public <T> androidx.lifecycle.LiveData<T!>! createLiveData(String![]!, java.util.concurrent.Callable<T!>!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public <T> androidx.lifecycle.LiveData<T!>! createLiveData(String![]!, boolean, java.util.concurrent.Callable<T!>!);
+    method public void refreshVersionsAsync();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @WorkerThread public void refreshVersionsSync();
+    method @WorkerThread public void removeObserver(androidx.room.InvalidationTracker.Observer);
+  }
+
+  public abstract static class InvalidationTracker.Observer {
+    ctor protected InvalidationTracker.Observer(String, java.lang.String!...);
+    ctor public InvalidationTracker.Observer(String![]);
+    method public abstract void onInvalidated(java.util.Set<java.lang.String!>);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class MultiInstanceInvalidationService extends android.app.Service {
+    ctor public MultiInstanceInvalidationService();
+    method public android.os.IBinder? onBind(android.content.Intent!);
+  }
+
+  public class Room {
+    ctor @Deprecated public Room();
+    method public static <T extends androidx.room.RoomDatabase> androidx.room.RoomDatabase.Builder<T!> databaseBuilder(android.content.Context, Class<T!>, String);
+    method public static <T extends androidx.room.RoomDatabase> androidx.room.RoomDatabase.Builder<T!> inMemoryDatabaseBuilder(android.content.Context, Class<T!>);
+    field public static final String MASTER_TABLE_NAME = "room_master_table";
+  }
+
+  public abstract class RoomDatabase {
+    ctor public RoomDatabase();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void assertNotMainThread();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public void assertNotSuspendingTransaction();
+    method @Deprecated public void beginTransaction();
+    method @WorkerThread public abstract void clearAllTables();
+    method public void close();
+    method public androidx.sqlite.db.SupportSQLiteStatement! compileStatement(String);
+    method protected abstract androidx.room.InvalidationTracker createInvalidationTracker();
+    method protected abstract androidx.sqlite.db.SupportSQLiteOpenHelper createOpenHelper(androidx.room.DatabaseConfiguration!);
+    method @Deprecated public void endTransaction();
+    method public androidx.room.InvalidationTracker getInvalidationTracker();
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper getOpenHelper();
+    method public java.util.concurrent.Executor getQueryExecutor();
+    method public java.util.concurrent.Executor getTransactionExecutor();
+    method public boolean inTransaction();
+    method @CallSuper public void init(androidx.room.DatabaseConfiguration);
+    method protected void internalInitInvalidationTracker(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public boolean isOpen();
+    method public android.database.Cursor query(String, Object![]?);
+    method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery);
+    method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery, android.os.CancellationSignal?);
+    method public void runInTransaction(Runnable);
+    method public <V> V! runInTransaction(java.util.concurrent.Callable<V!>);
+    method @Deprecated public void setTransactionSuccessful();
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final int MAX_BIND_PARAMETER_CNT = 999; // 0x3e7
+    field @Deprecated protected java.util.List<androidx.room.RoomDatabase.Callback!>? mCallbacks;
+    field @Deprecated protected volatile androidx.sqlite.db.SupportSQLiteDatabase! mDatabase;
+  }
+
+  public static class RoomDatabase.Builder<T extends androidx.room.RoomDatabase> {
+    method public androidx.room.RoomDatabase.Builder<T!> addCallback(androidx.room.RoomDatabase.Callback);
+    method public androidx.room.RoomDatabase.Builder<T!> addMigrations(androidx.room.migration.Migration!...);
+    method public androidx.room.RoomDatabase.Builder<T!> allowMainThreadQueries();
+    method public T build();
+    method public androidx.room.RoomDatabase.Builder<T!> createFromAsset(String);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromFile(java.io.File);
+    method public androidx.room.RoomDatabase.Builder<T!> enableMultiInstanceInvalidation();
+    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigration();
+    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationFrom(int...);
+    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationOnDowngrade();
+    method public androidx.room.RoomDatabase.Builder<T!> openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory?);
+    method public androidx.room.RoomDatabase.Builder<T!> setJournalMode(androidx.room.RoomDatabase.JournalMode);
+    method public androidx.room.RoomDatabase.Builder<T!> setQueryExecutor(java.util.concurrent.Executor);
+    method public androidx.room.RoomDatabase.Builder<T!> setTransactionExecutor(java.util.concurrent.Executor);
+  }
+
+  public abstract static class RoomDatabase.Callback {
+    ctor public RoomDatabase.Callback();
+    method public void onCreate(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onDestructiveMigration(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase);
+  }
+
+  public enum RoomDatabase.JournalMode {
+    enum_constant public static final androidx.room.RoomDatabase.JournalMode AUTOMATIC;
+    enum_constant public static final androidx.room.RoomDatabase.JournalMode TRUNCATE;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.JELLY_BEAN) public static final androidx.room.RoomDatabase.JournalMode WRITE_AHEAD_LOGGING;
+  }
+
+  public static class RoomDatabase.MigrationContainer {
+    ctor public RoomDatabase.MigrationContainer();
+    method public void addMigrations(androidx.room.migration.Migration!...);
+    method public java.util.List<androidx.room.migration.Migration!>? findMigrationPath(int, int);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class RoomOpenHelper extends androidx.sqlite.db.SupportSQLiteOpenHelper.Callback {
+    ctor public RoomOpenHelper(androidx.room.DatabaseConfiguration, androidx.room.RoomOpenHelper.Delegate, String, String);
+    ctor public RoomOpenHelper(androidx.room.DatabaseConfiguration, androidx.room.RoomOpenHelper.Delegate, String);
+    method public void onCreate(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method public void onUpgrade(androidx.sqlite.db.SupportSQLiteDatabase!, int, int);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract static class RoomOpenHelper.Delegate {
+    ctor public RoomOpenHelper.Delegate(int);
+    method protected abstract void createAllTables(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method protected abstract void dropAllTables(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method protected abstract void onCreate(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method protected abstract void onOpen(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method protected void onPostMigrate(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method protected void onPreMigrate(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method protected androidx.room.RoomOpenHelper.ValidationResult onValidateSchema(androidx.sqlite.db.SupportSQLiteDatabase);
+    method @Deprecated protected void validateMigration(androidx.sqlite.db.SupportSQLiteDatabase!);
+    field public final int version;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static class RoomOpenHelper.ValidationResult {
+    ctor public RoomOpenHelper.ValidationResult(boolean, String?);
+    field public final String? expectedFoundMsg;
+    field public final boolean isValid;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class RoomSQLiteQuery implements androidx.sqlite.db.SupportSQLiteProgram androidx.sqlite.db.SupportSQLiteQuery {
+    method public static androidx.room.RoomSQLiteQuery! acquire(String!, int);
+    method public void bindBlob(int, byte[]!);
+    method public void bindDouble(int, double);
+    method public void bindLong(int, long);
+    method public void bindNull(int);
+    method public void bindString(int, String!);
+    method public void bindTo(androidx.sqlite.db.SupportSQLiteProgram!);
+    method public void clearBindings();
+    method public void close();
+    method public void copyArgumentsFrom(androidx.room.RoomSQLiteQuery!);
+    method public static androidx.room.RoomSQLiteQuery! copyFrom(androidx.sqlite.db.SupportSQLiteQuery!);
+    method public int getArgCount();
+    method public String! getSql();
+    method public void release();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class SharedSQLiteStatement {
+    ctor public SharedSQLiteStatement(androidx.room.RoomDatabase!);
+    method public androidx.sqlite.db.SupportSQLiteStatement! acquire();
+    method protected void assertNotMainThread();
+    method protected abstract String! createQuery();
+    method public void release(androidx.sqlite.db.SupportSQLiteStatement!);
+  }
+
+}
+
+package androidx.room.migration {
+
+  public abstract class Migration {
+    ctor public Migration(int, int);
+    method public abstract void migrate(androidx.sqlite.db.SupportSQLiteDatabase);
+    field public final int endVersion;
+    field public final int startVersion;
+  }
+
+}
+
+package androidx.room.paging {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class LimitOffsetDataSource<T> extends androidx.paging.PositionalDataSource<T> {
+    ctor protected LimitOffsetDataSource(androidx.room.RoomDatabase!, androidx.sqlite.db.SupportSQLiteQuery!, boolean, java.lang.String!...);
+    ctor protected LimitOffsetDataSource(androidx.room.RoomDatabase!, androidx.room.RoomSQLiteQuery!, boolean, java.lang.String!...);
+    method protected abstract java.util.List<T!>! convertRows(android.database.Cursor!);
+    method public void loadInitial(androidx.paging.PositionalDataSource.LoadInitialParams, androidx.paging.PositionalDataSource.LoadInitialCallback<T!>);
+    method public void loadRange(androidx.paging.PositionalDataSource.LoadRangeParams, androidx.paging.PositionalDataSource.LoadRangeCallback<T!>);
+  }
+
+}
+
+package androidx.room.util {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class CopyLock {
+    ctor public CopyLock(String, java.io.File, boolean);
+    method public void lock();
+    method public void unlock();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class CursorUtil {
+    method public static android.database.Cursor copyAndClose(android.database.Cursor);
+    method public static int getColumnIndex(android.database.Cursor, String);
+    method public static int getColumnIndexOrThrow(android.database.Cursor, String);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class DBUtil {
+    method public static android.os.CancellationSignal? createCancellationSignal();
+    method public static void dropFtsSyncTriggers(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method @Deprecated public static android.database.Cursor query(androidx.room.RoomDatabase!, androidx.sqlite.db.SupportSQLiteQuery!, boolean);
+    method public static android.database.Cursor query(androidx.room.RoomDatabase, androidx.sqlite.db.SupportSQLiteQuery, boolean, android.os.CancellationSignal?);
+    method public static int readVersion(java.io.File) throws java.io.IOException;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class FileUtil {
+    method public static void copy(java.nio.channels.ReadableByteChannel, java.nio.channels.FileChannel) throws java.io.IOException;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class FtsTableInfo {
+    ctor public FtsTableInfo(String!, java.util.Set<java.lang.String!>!, java.util.Set<java.lang.String!>!);
+    ctor public FtsTableInfo(String!, java.util.Set<java.lang.String!>!, String!);
+    method public static androidx.room.util.FtsTableInfo! read(androidx.sqlite.db.SupportSQLiteDatabase!, String!);
+    field public final java.util.Set<java.lang.String!>! columns;
+    field public final String! name;
+    field public final java.util.Set<java.lang.String!>! options;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public class SneakyThrow {
+    method public static void reThrow(Exception);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class StringUtil {
+    method public static void appendPlaceholders(StringBuilder!, int);
+    method public static String? joinIntoString(java.util.List<java.lang.Integer!>?);
+    method public static StringBuilder! newStringBuilder();
+    method public static java.util.List<java.lang.Integer!>? splitToIntList(String?);
+    field public static final String![]! EMPTY_STRING_ARRAY;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class TableInfo {
+    ctor public TableInfo(String!, java.util.Map<java.lang.String!,androidx.room.util.TableInfo.Column!>!, java.util.Set<androidx.room.util.TableInfo.ForeignKey!>!, java.util.Set<androidx.room.util.TableInfo.Index!>!);
+    ctor public TableInfo(String!, java.util.Map<java.lang.String!,androidx.room.util.TableInfo.Column!>!, java.util.Set<androidx.room.util.TableInfo.ForeignKey!>!);
+    method public static androidx.room.util.TableInfo! read(androidx.sqlite.db.SupportSQLiteDatabase!, String!);
+    field public static final int CREATED_FROM_DATABASE = 2; // 0x2
+    field public static final int CREATED_FROM_ENTITY = 1; // 0x1
+    field public static final int CREATED_FROM_UNKNOWN = 0; // 0x0
+    field public final java.util.Map<java.lang.String!,androidx.room.util.TableInfo.Column!>! columns;
+    field public final java.util.Set<androidx.room.util.TableInfo.ForeignKey!>! foreignKeys;
+    field public final java.util.Set<androidx.room.util.TableInfo.Index!>? indices;
+    field public final String! name;
+  }
+
+  public static class TableInfo.Column {
+    ctor @Deprecated public TableInfo.Column(String!, String!, boolean, int);
+    ctor public TableInfo.Column(String!, String!, boolean, int, String!, int);
+    method public boolean isPrimaryKey();
+    field public final int affinity;
+    field public final String! defaultValue;
+    field public final String! name;
+    field public final boolean notNull;
+    field public final int primaryKeyPosition;
+    field public final String! type;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static class TableInfo.ForeignKey {
+    ctor public TableInfo.ForeignKey(String, String, String, java.util.List<java.lang.String!>, java.util.List<java.lang.String!>);
+    field public final java.util.List<java.lang.String!> columnNames;
+    field public final String onDelete;
+    field public final String onUpdate;
+    field public final java.util.List<java.lang.String!> referenceColumnNames;
+    field public final String referenceTable;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static class TableInfo.Index {
+    ctor public TableInfo.Index(String!, boolean, java.util.List<java.lang.String!>!);
+    field public static final String DEFAULT_PREFIX = "index_";
+    field public final java.util.List<java.lang.String!>! columns;
+    field public final String! name;
+    field public final boolean unique;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ViewInfo {
+    ctor public ViewInfo(String!, String!);
+    method public static androidx.room.util.ViewInfo! read(androidx.sqlite.db.SupportSQLiteDatabase!, String!);
+    field public final String! name;
+    field public final String! sql;
+  }
+
+}
+
diff --git a/room/runtime/api/restricted_current.txt b/room/runtime/api/restricted_current.txt
index 8e744d7..6bc1371 100644
--- a/room/runtime/api/restricted_current.txt
+++ b/room/runtime/api/restricted_current.txt
@@ -233,6 +233,7 @@
   }
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class DBUtil {
+    method public static android.os.CancellationSignal? createCancellationSignal();
     method public static void dropFtsSyncTriggers(androidx.sqlite.db.SupportSQLiteDatabase!);
     method @Deprecated public static android.database.Cursor query(androidx.room.RoomDatabase!, androidx.sqlite.db.SupportSQLiteQuery!, boolean);
     method public static android.database.Cursor query(androidx.room.RoomDatabase, androidx.sqlite.db.SupportSQLiteQuery, boolean, android.os.CancellationSignal?);
diff --git a/room/runtime/src/androidTest/java/androidx/room/util/DBUtilTest.java b/room/runtime/src/androidTest/java/androidx/room/util/DBUtilTest.java
index 015b4d0..77437f1 100644
--- a/room/runtime/src/androidTest/java/androidx/room/util/DBUtilTest.java
+++ b/room/runtime/src/androidTest/java/androidx/room/util/DBUtilTest.java
@@ -16,16 +16,20 @@
 
 package androidx.room.util;
 
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
 import android.database.AbstractWindowedCursor;
 import android.database.Cursor;
+import android.os.CancellationSignal;
 
 import androidx.sqlite.db.SupportSQLiteDatabase;
 import androidx.sqlite.db.SupportSQLiteOpenHelper;
 import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Test;
@@ -72,4 +76,11 @@
                         }).build()
         ).getWritableDatabase();
     }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 16)
+    public void createCancellationSignal() {
+        CancellationSignal signal = DBUtil.createCancellationSignal();
+        assertThat(signal, notNullValue());
+    }
 }
diff --git a/room/runtime/src/main/java/androidx/room/util/DBUtil.java b/room/runtime/src/main/java/androidx/room/util/DBUtil.java
index f802e6d..1b9b866 100644
--- a/room/runtime/src/main/java/androidx/room/util/DBUtil.java
+++ b/room/runtime/src/main/java/androidx/room/util/DBUtil.java
@@ -156,6 +156,20 @@
         }
     }
 
+    /**
+     * CancellationSignal is only available from API 16 on. This function will create a new
+     * instance of the Cancellation signal only if the current API > 16.
+     *
+     * @return A new instance of CancellationSignal or null.
+     */
+    @Nullable
+    public static CancellationSignal createCancellationSignal() {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+            return new CancellationSignal();
+        }
+        return null;
+    }
+
     private DBUtil() {
     }
 }
diff --git a/room/rxjava2/api/2.2.0-alpha03.txt b/room/rxjava2/api/2.2.0-alpha03.txt
new file mode 100644
index 0000000..07ab5f2
--- /dev/null
+++ b/room/rxjava2/api/2.2.0-alpha03.txt
@@ -0,0 +1,16 @@
+// Signature format: 3.0
+package androidx.room {
+
+  public class EmptyResultSetException extends java.lang.RuntimeException {
+    ctor public EmptyResultSetException(String!);
+  }
+
+  public class RxRoom {
+    ctor @Deprecated public RxRoom();
+    method public static io.reactivex.Flowable<java.lang.Object!>! createFlowable(androidx.room.RoomDatabase!, java.lang.String!...);
+    method public static io.reactivex.Observable<java.lang.Object!>! createObservable(androidx.room.RoomDatabase!, java.lang.String!...);
+    field public static final Object! NOTHING;
+  }
+
+}
+
diff --git a/room/rxjava2/api/api_lint.ignore b/room/rxjava2/api/api_lint.ignore
new file mode 100644
index 0000000..f5b27266
--- /dev/null
+++ b/room/rxjava2/api/api_lint.ignore
@@ -0,0 +1,17 @@
+// Baseline format: 1.0
+MissingNullability: androidx.room.EmptyResultSetException#EmptyResultSetException(String) parameter #0:
+    Missing nullability on parameter `message` in method `EmptyResultSetException`
+MissingNullability: androidx.room.RxRoom#NOTHING:
+    Missing nullability on field `NOTHING` in class `class androidx.room.RxRoom`
+MissingNullability: androidx.room.RxRoom#createFlowable(androidx.room.RoomDatabase, java.lang.String...):
+    Missing nullability on method `createFlowable` return
+MissingNullability: androidx.room.RxRoom#createFlowable(androidx.room.RoomDatabase, java.lang.String...) parameter #0:
+    Missing nullability on parameter `database` in method `createFlowable`
+MissingNullability: androidx.room.RxRoom#createFlowable(androidx.room.RoomDatabase, java.lang.String...) parameter #1:
+    Missing nullability on parameter `tableNames` in method `createFlowable`
+MissingNullability: androidx.room.RxRoom#createObservable(androidx.room.RoomDatabase, java.lang.String...):
+    Missing nullability on method `createObservable` return
+MissingNullability: androidx.room.RxRoom#createObservable(androidx.room.RoomDatabase, java.lang.String...) parameter #0:
+    Missing nullability on parameter `database` in method `createObservable`
+MissingNullability: androidx.room.RxRoom#createObservable(androidx.room.RoomDatabase, java.lang.String...) parameter #1:
+    Missing nullability on parameter `tableNames` in method `createObservable`
diff --git a/preference/ktx/api/res-1.1.0-alpha03.txt b/room/rxjava2/api/res-2.2.0-alpha03.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha03.txt
copy to room/rxjava2/api/res-2.2.0-alpha03.txt
diff --git a/room/rxjava2/api/restricted_2.2.0-alpha03.txt b/room/rxjava2/api/restricted_2.2.0-alpha03.txt
new file mode 100644
index 0000000..869770f
--- /dev/null
+++ b/room/rxjava2/api/restricted_2.2.0-alpha03.txt
@@ -0,0 +1,21 @@
+// Signature format: 3.0
+package androidx.room {
+
+  public class EmptyResultSetException extends java.lang.RuntimeException {
+    ctor public EmptyResultSetException(String!);
+  }
+
+  public class RxRoom {
+    ctor @Deprecated public RxRoom();
+    method public static io.reactivex.Flowable<java.lang.Object!>! createFlowable(androidx.room.RoomDatabase!, java.lang.String!...);
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static <T> io.reactivex.Flowable<T!>! createFlowable(androidx.room.RoomDatabase!, String![]!, java.util.concurrent.Callable<T!>!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static <T> io.reactivex.Flowable<T!>! createFlowable(androidx.room.RoomDatabase!, boolean, String![]!, java.util.concurrent.Callable<T!>!);
+    method public static io.reactivex.Observable<java.lang.Object!>! createObservable(androidx.room.RoomDatabase!, java.lang.String!...);
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static <T> io.reactivex.Observable<T!>! createObservable(androidx.room.RoomDatabase!, String![]!, java.util.concurrent.Callable<T!>!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static <T> io.reactivex.Observable<T!>! createObservable(androidx.room.RoomDatabase!, boolean, String![]!, java.util.concurrent.Callable<T!>!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static <T> io.reactivex.Single<T!>! createSingle(java.util.concurrent.Callable<T!>!);
+    field public static final Object! NOTHING;
+  }
+
+}
+
diff --git a/room/testing/api/2.2.0-alpha03.txt b/room/testing/api/2.2.0-alpha03.txt
new file mode 100644
index 0000000..86e22e8
--- /dev/null
+++ b/room/testing/api/2.2.0-alpha03.txt
@@ -0,0 +1,14 @@
+// Signature format: 3.0
+package androidx.room.testing {
+
+  public class MigrationTestHelper extends org.junit.rules.TestWatcher {
+    ctor public MigrationTestHelper(android.app.Instrumentation!, String!);
+    ctor public MigrationTestHelper(android.app.Instrumentation!, String!, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory!);
+    method public void closeWhenFinished(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method public void closeWhenFinished(androidx.room.RoomDatabase!);
+    method public androidx.sqlite.db.SupportSQLiteDatabase! createDatabase(String!, int) throws java.io.IOException;
+    method public androidx.sqlite.db.SupportSQLiteDatabase! runMigrationsAndValidate(String!, int, boolean, androidx.room.migration.Migration!...) throws java.io.IOException;
+  }
+
+}
+
diff --git a/room/testing/api/api_lint.ignore b/room/testing/api/api_lint.ignore
new file mode 100644
index 0000000..6b8b6f7
--- /dev/null
+++ b/room/testing/api/api_lint.ignore
@@ -0,0 +1,29 @@
+// Baseline format: 1.0
+MissingNullability: androidx.room.testing.MigrationTestHelper#MigrationTestHelper(android.app.Instrumentation, String) parameter #0:
+    Missing nullability on parameter `instrumentation` in method `MigrationTestHelper`
+MissingNullability: androidx.room.testing.MigrationTestHelper#MigrationTestHelper(android.app.Instrumentation, String) parameter #1:
+    Missing nullability on parameter `assetsFolder` in method `MigrationTestHelper`
+MissingNullability: androidx.room.testing.MigrationTestHelper#MigrationTestHelper(android.app.Instrumentation, String, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory) parameter #0:
+    Missing nullability on parameter `instrumentation` in method `MigrationTestHelper`
+MissingNullability: androidx.room.testing.MigrationTestHelper#MigrationTestHelper(android.app.Instrumentation, String, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory) parameter #1:
+    Missing nullability on parameter `assetsFolder` in method `MigrationTestHelper`
+MissingNullability: androidx.room.testing.MigrationTestHelper#MigrationTestHelper(android.app.Instrumentation, String, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory) parameter #2:
+    Missing nullability on parameter `openFactory` in method `MigrationTestHelper`
+MissingNullability: androidx.room.testing.MigrationTestHelper#closeWhenFinished(androidx.room.RoomDatabase) parameter #0:
+    Missing nullability on parameter `db` in method `closeWhenFinished`
+MissingNullability: androidx.room.testing.MigrationTestHelper#closeWhenFinished(androidx.sqlite.db.SupportSQLiteDatabase) parameter #0:
+    Missing nullability on parameter `db` in method `closeWhenFinished`
+MissingNullability: androidx.room.testing.MigrationTestHelper#createDatabase(String, int):
+    Missing nullability on method `createDatabase` return
+MissingNullability: androidx.room.testing.MigrationTestHelper#createDatabase(String, int) parameter #0:
+    Missing nullability on parameter `name` in method `createDatabase`
+MissingNullability: androidx.room.testing.MigrationTestHelper#finished(org.junit.runner.Description) parameter #0:
+    Missing nullability on parameter `description` in method `finished`
+MissingNullability: androidx.room.testing.MigrationTestHelper#runMigrationsAndValidate(String, int, boolean, androidx.room.migration.Migration...):
+    Missing nullability on method `runMigrationsAndValidate` return
+MissingNullability: androidx.room.testing.MigrationTestHelper#runMigrationsAndValidate(String, int, boolean, androidx.room.migration.Migration...) parameter #0:
+    Missing nullability on parameter `name` in method `runMigrationsAndValidate`
+MissingNullability: androidx.room.testing.MigrationTestHelper#runMigrationsAndValidate(String, int, boolean, androidx.room.migration.Migration...) parameter #3:
+    Missing nullability on parameter `migrations` in method `runMigrationsAndValidate`
+MissingNullability: androidx.room.testing.MigrationTestHelper#starting(org.junit.runner.Description) parameter #0:
+    Missing nullability on parameter `description` in method `starting`
diff --git a/preference/ktx/api/res-1.1.0-alpha03.txt b/room/testing/api/res-2.2.0-alpha03.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha03.txt
copy to room/testing/api/res-2.2.0-alpha03.txt
diff --git a/room/testing/api/restricted_2.2.0-alpha03.txt b/room/testing/api/restricted_2.2.0-alpha03.txt
new file mode 100644
index 0000000..86e22e8
--- /dev/null
+++ b/room/testing/api/restricted_2.2.0-alpha03.txt
@@ -0,0 +1,14 @@
+// Signature format: 3.0
+package androidx.room.testing {
+
+  public class MigrationTestHelper extends org.junit.rules.TestWatcher {
+    ctor public MigrationTestHelper(android.app.Instrumentation!, String!);
+    ctor public MigrationTestHelper(android.app.Instrumentation!, String!, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory!);
+    method public void closeWhenFinished(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method public void closeWhenFinished(androidx.room.RoomDatabase!);
+    method public androidx.sqlite.db.SupportSQLiteDatabase! createDatabase(String!, int) throws java.io.IOException;
+    method public androidx.sqlite.db.SupportSQLiteDatabase! runMigrationsAndValidate(String!, int, boolean, androidx.room.migration.Migration!...) throws java.io.IOException;
+  }
+
+}
+
diff --git a/samples/BiometricDemos/src/main/AndroidManifest.xml b/samples/BiometricDemos/src/main/AndroidManifest.xml
index 6b87961..7459a17 100644
--- a/samples/BiometricDemos/src/main/AndroidManifest.xml
+++ b/samples/BiometricDemos/src/main/AndroidManifest.xml
@@ -56,6 +56,11 @@
         <activity android:name=".BiometricPromptDemoFragmentHostActivity"
             android:theme="@style/AppTheme" />
 
+        <activity android:name=".BiometricPromptDemoBiometricBoundKeyActivity"
+            android:theme="@style/AppTheme"/>
+
+        <activity android:name=".BiometricPromptDemoCredentialBoundKeyActivity"
+            android:theme="@style/AppTheme"/>
     </application>
 
 </manifest>
diff --git a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemo.java b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemo.java
index 905aad7..dbddf77 100644
--- a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemo.java
+++ b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemo.java
@@ -17,7 +17,9 @@
 package com.example.android.biometric;
 
 import android.content.Intent;
+import android.os.Build;
 import android.os.Bundle;
+import android.view.View;
 import android.widget.Button;
 
 import androidx.annotation.Nullable;
@@ -37,8 +39,22 @@
         setContentView(R.layout.biometric_prompt_demo);
         final Button hostInActivityButton = findViewById(R.id.host_in_activity_button);
         final Button hostInFragmentButton = findViewById(R.id.host_in_fragment_button);
+        final Button biometricBoundKeyDemoButton =
+                findViewById(R.id.button_biometric_bound_key_demo);
+        final Button credentialBoundKeyDemoButton =
+                findViewById(R.id.button_credential_bound_key_demo);
         hostInActivityButton.setOnClickListener(view -> launchActivityHost());
         hostInFragmentButton.setOnClickListener(view -> launchFragmentHost());
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            biometricBoundKeyDemoButton.setOnClickListener(view -> launchBiometricBoundKeyDemo());
+        } else {
+            biometricBoundKeyDemoButton.setVisibility(View.GONE);
+        }
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            credentialBoundKeyDemoButton.setOnClickListener(view -> launchCredentialBoundKeyDemo());
+        } else {
+            credentialBoundKeyDemoButton.setVisibility(View.GONE);
+        }
     }
 
     private void launchActivityHost() {
@@ -50,4 +66,14 @@
         Intent intent = new Intent(this, BiometricPromptDemoFragmentHostActivity.class);
         startActivity(intent);
     }
+
+    private void launchBiometricBoundKeyDemo() {
+        Intent intent = new Intent(this, BiometricPromptDemoBiometricBoundKeyActivity.class);
+        startActivity(intent);
+    }
+
+    private void launchCredentialBoundKeyDemo() {
+        Intent intent = new Intent(this, BiometricPromptDemoCredentialBoundKeyActivity.class);
+        startActivity(intent);
+    }
 }
diff --git a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoActivityController.java b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoActivityController.java
index 97033ec..07610e0 100644
--- a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoActivityController.java
+++ b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoActivityController.java
@@ -17,10 +17,7 @@
 package com.example.android.biometric;
 
 import android.content.Context;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.RadioGroup;
-import android.widget.TextView;
+import android.view.View;
 
 import androidx.annotation.NonNull;
 import androidx.biometric.BiometricPrompt;
@@ -36,18 +33,8 @@
 
     BiometricPromptDemoActivityController(
             @NonNull FragmentActivity activity,
-            @NonNull Button createKeysButton,
-            @NonNull Button authenticateButton,
-            @NonNull Button canAuthenticateButton,
-            @NonNull CheckBox useCryptoCheckbox,
-            @NonNull CheckBox confirmationRequiredCheckbox,
-            @NonNull CheckBox deviceCredentialAllowedCheckbox,
-            @NonNull RadioGroup radioGroup,
-            @NonNull Button clearLogButton,
-            @NonNull TextView logView) {
-        super(createKeysButton, authenticateButton, canAuthenticateButton, useCryptoCheckbox,
-                confirmationRequiredCheckbox, deviceCredentialAllowedCheckbox, radioGroup,
-                clearLogButton, logView);
+            @NonNull View inflatedRootView) {
+        super(inflatedRootView);
         mActivity = activity;
     }
 
diff --git a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoActivityHost.java b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoActivityHost.java
index d0f1d5b..b3b06f0 100644
--- a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoActivityHost.java
+++ b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoActivityHost.java
@@ -17,9 +17,6 @@
 package com.example.android.biometric;
 
 import android.os.Bundle;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.RadioGroup;
 import android.widget.TextView;
 
 import androidx.annotation.NonNull;
@@ -42,29 +39,8 @@
         final TextView hostTypeTextView = findViewById(R.id.host_type_text_view);
         hostTypeTextView.setText(R.string.label_host_type_activity);
 
-        final Button createKeysButton = findViewById(R.id.button_enable_biometric_with_crypto);
-        final Button authenticateButton = findViewById(R.id.button_authenticate);
-        final Button canAuthenticateButton = findViewById(R.id.can_authenticate);
-        final CheckBox useCryptoCheckbox = findViewById(R.id.checkbox_use_crypto);
-        final CheckBox confirmationRequiredCheckbox = findViewById(
-                R.id.checkbox_require_confirmation);
-        final CheckBox deviceCredentialAllowedCheckbox = findViewById(
-                R.id.checkbox_enable_fallback);
-        final RadioGroup radioGroup = findViewById(R.id.radio_group);
-        final Button clearLogButton = findViewById(R.id.log_clear);
-        final TextView logView = findViewById(R.id.log_text);
-
-        mController = new BiometricPromptDemoActivityController(
-                this,
-                createKeysButton,
-                authenticateButton,
-                canAuthenticateButton,
-                useCryptoCheckbox,
-                confirmationRequiredCheckbox,
-                deviceCredentialAllowedCheckbox,
-                radioGroup,
-                clearLogButton,
-                logView);
+        mController = new BiometricPromptDemoActivityController(this,
+                findViewById(android.R.id.content));
         mController.init(savedInstanceState);
         mController.reconnect();
     }
diff --git a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoBiometricBoundKeyActivity.java b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoBiometricBoundKeyActivity.java
new file mode 100644
index 0000000..495331c
--- /dev/null
+++ b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoBiometricBoundKeyActivity.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2019 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 com.example.android.biometric;
+
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.biometric.BiometricPrompt;
+import androidx.fragment.app.FragmentActivity;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.Arrays;
+import java.util.concurrent.Executor;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+
+/**
+ * Demo activity that shows how BiometricPrompt can be used with biometric bound secret keys.
+ */
+@RequiresApi(api = Build.VERSION_CODES.M)
+public class BiometricPromptDemoBiometricBoundKeyActivity extends FragmentActivity {
+
+    private static final String TAG = "bio_prompt_demo_control";
+    private static final String LOG_BUNDLE = "log";
+    private static final String KEY_NAME = "demo_key";
+    private static final String PAYLOAD = "hello";
+
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
+    private final Executor mExecutor = mHandler::post;
+    private BiometricPrompt mBiometricPrompt;
+    private TextView mLogTextView;
+
+    private void log(String s) {
+        Log.d(TAG, s);
+        mLogTextView.append(s + '\n');
+    }
+
+    private void log(String s, Throwable tr) {
+        Log.e(TAG, "", tr);
+        mLogTextView.append(s + '\n' + tr.toString() + '\n');
+    }
+
+    private final BiometricPrompt.PromptInfo mPromptInfo = new BiometricPrompt.PromptInfo.Builder()
+            .setTitle("Title")
+            .setSubtitle("Subtitle")
+            .setDescription("Description")
+            .setNegativeButtonText("Negative Button")
+            .build();
+
+    private final BiometricPrompt.AuthenticationCallback mAuthenticationCallback =
+            new BiometricPrompt.AuthenticationCallback() {
+
+                @Override
+                public void onAuthenticationError(int err, @NonNull CharSequence message) {
+                    log("onAuthenticationError " + err + ": " + message);
+                }
+
+                @Override
+                public void onAuthenticationSucceeded(
+                        @NonNull BiometricPrompt.AuthenticationResult result) {
+                    final BiometricPrompt.CryptoObject cryptoObject = result.getCryptoObject();
+                    log("onAuthenticationSucceeded, cryptoObject: " + cryptoObject);
+                    if (cryptoObject != null) {
+                        try {
+                            byte[] encrypted =
+                                    cryptoObject.getCipher().doFinal(
+                                            PAYLOAD.getBytes(Charset.defaultCharset()));
+                            log("Test payload: " + PAYLOAD);
+                            log("Encrypted payload: " + Arrays.toString(encrypted));
+                        } catch (BadPaddingException | IllegalBlockSizeException e) {
+                            log("Failed to encrypt", e);
+                        }
+                    }
+                }
+
+                @Override
+                public void onAuthenticationFailed() {
+                    log("onAuthenticationFailed");
+                    mBiometricPrompt.cancelAuthentication();
+                }
+            };
+
+    private View.OnClickListener mGenerateKeyListener = view -> {
+        try {
+            BiometricPromptDemoSecretKeyHelper.generateBiometricBoundKey(KEY_NAME,
+                    true /* invalidatedByBiometricEnrollment */);
+            log("Generated a key");
+        } catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException
+                | NoSuchProviderException e) {
+            log("Failed to generate key", e);
+        }
+    };
+
+    private View.OnClickListener mUnlockAndUseKeyListener = view -> {
+        Cipher cipher = null;
+        try {
+            cipher = BiometricPromptDemoSecretKeyHelper.getCipher();
+        } catch (NoSuchPaddingException | NoSuchAlgorithmException e) {
+            log("Failed to get cipher", e);
+        }
+
+        SecretKey secretKey = null;
+        try {
+            secretKey = BiometricPromptDemoSecretKeyHelper.getSecretKey(KEY_NAME);
+        } catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException
+                | UnrecoverableKeyException e) {
+            log("Failed to get secret key", e);
+        }
+
+        if (cipher != null && secretKey != null) {
+            try {
+                cipher.init(Cipher.ENCRYPT_MODE, secretKey);
+                mBiometricPrompt.authenticate(mPromptInfo,
+                        new BiometricPrompt.CryptoObject(cipher));
+                log("Started authentication with a crypto object");
+            } catch (InvalidKeyException e) {
+                log("Failed to init cipher", e);
+            }
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.biometric_prompt_demo_biometric_bound_key);
+
+        mLogTextView = findViewById(R.id.text_view_log);
+        mBiometricPrompt = new BiometricPrompt(this, mExecutor, mAuthenticationCallback);
+
+        ((TextView) findViewById(R.id.text_view_activity_description)).setText(
+                R.string.label_biometric_bound_key_activity_description);
+
+        if (savedInstanceState != null) {
+            mLogTextView.setText(savedInstanceState.getCharSequence(LOG_BUNDLE));
+        }
+
+        findViewById(R.id.button_generate_key).setOnClickListener(mGenerateKeyListener);
+        findViewById(R.id.button_unlock_and_use_key).setOnClickListener(mUnlockAndUseKeyListener);
+        findViewById(R.id.button_clear_log).setOnClickListener(v -> mLogTextView.setText(""));
+    }
+
+    @Override
+    protected void onPause() {
+        mBiometricPrompt.cancelAuthentication();
+        super.onPause();
+    }
+
+    @Override
+    protected void onSaveInstanceState(@NonNull Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putCharSequence(LOG_BUNDLE, mLogTextView.getText());
+    }
+}
diff --git a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoController.java b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoController.java
index 438e4eb..f14163a 100644
--- a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoController.java
+++ b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoController.java
@@ -21,9 +21,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
-import android.security.keystore.KeyGenParameterSpec;
-import android.security.keystore.KeyProperties;
-import android.util.Base64;
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
@@ -33,33 +30,14 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.biometric.BiometricManager;
 import androidx.biometric.BiometricPrompt;
 
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import java.util.Arrays;
 import java.util.concurrent.Executor;
 
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.KeyGenerator;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-
 /**
  * Controller for the biometric prompt demo app. Coordinates the logic of initializing buttons,
- * generating the info and crypto objects for the biometric prompt, and launching the prompt itself.
+ * generating the info, and launching the prompt itself.
  */
 abstract class BiometricPromptDemoController {
 
@@ -68,8 +46,6 @@
     private static final String KEY_COUNTER = "saved_counter";
     private static final String KEY_LOG = "saved_log";
 
-    private static final String DEFAULT_KEY_NAME = "default_key";
-
     private static final String BIOMETRIC_SUCCESS_MESSAGE = "BIOMETRIC_SUCCESS_MESSAGE";
     private static final String BIOMETRIC_ERROR_HW_UNAVAILABLE_MESSAGE =
             "BIOMETRIC_ERROR_HW_UNAVAILABLE";
@@ -84,25 +60,23 @@
     private static final int MODE_CANCEL_ON_CONFIGURATION_CHANGE = 2;
     private static final int MODE_CANCEL_AFTER_THREE_FAILURES = 3;
 
-    private Handler mHandler = new Handler(Looper.getMainLooper());
-    private KeyStore mKeyStore;
-    private int mCounter;
-    private int mNumberFailedAttempts;
-
-    private Button mCreateKeysButton;
-    private Button mAuthenticateButton;
-    private Button mCanAuthenticateButton;
-    private CheckBox mUseCryptoCheckbox;
-    private CheckBox mConfirmationRequiredCheckbox;
-    private CheckBox mDeviceCredentialAllowedCheckbox;
-    private RadioGroup mRadioGroup;
-    private TextView mLogView;
-
     BiometricPrompt mBiometricPrompt;
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
+    final Executor mExecutor = mHandler::post;
+    private int mCounter;
 
-    final Executor mExecutor = runnable -> mHandler.post(runnable);
+    private final Button mCanAuthenticateButton;
+    private final Button mAuthenticateButton;
+    private final CheckBox mRequireConfirmationCheckbox;
+    private final CheckBox mAllowDeviceCredentialCheckbox;
+    private final RadioGroup mBiometricPromptConfigurationRadioGroup;
+
+    private final TextView mLogView;
+
     final BiometricPrompt.AuthenticationCallback mAuthenticationCallback =
             new BiometricPrompt.AuthenticationCallback() {
+                private int mNumberFailedAttempts = 0;
+
                 @Override
                 public void onAuthenticationError(int err, @NonNull CharSequence message) {
                     log("onAuthenticationError " + err + ": " + message);
@@ -110,22 +84,10 @@
                 }
 
                 @Override
-                public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
-                    log("onAuthenticationSucceeded, crypto: " + result.getCryptoObject());
+                public void onAuthenticationSucceeded(
+                        @NonNull BiometricPrompt.AuthenticationResult result) {
+                    log("onAuthenticationSucceeded");
                     mNumberFailedAttempts = 0;
-
-                    if (result.getCryptoObject() != null) {
-                        Cipher cipher = result.getCryptoObject().getCipher();
-                        try {
-                            byte[] encrypted = cipher.doFinal(
-                                    "hello".getBytes(Charset.defaultCharset()));
-                            String message = Arrays.toString(
-                                    Base64.encode(encrypted, 0 /* flags */));
-                            log("Message: " + message);
-                        } catch (BadPaddingException | IllegalBlockSizeException e) {
-                            log("Error encrypting");
-                        }
-                    }
                 }
 
                 @Override
@@ -155,25 +117,20 @@
      */
     abstract void reconnect();
 
-    BiometricPromptDemoController(@NonNull Button createKeysButton,
-            @NonNull Button authenticateButton,
-            @NonNull Button canAuthenticateButton,
-            @NonNull CheckBox useCryptoCheckbox,
-            @NonNull CheckBox confirmationRequiredCheckbox,
-            @NonNull CheckBox deviceCredentialAllowedCheckbox,
-            @NonNull RadioGroup radioGroup,
-            @NonNull Button clearLogButton,
-            @NonNull TextView logView) {
-        mCreateKeysButton = createKeysButton;
-        mAuthenticateButton = authenticateButton;
-        mCanAuthenticateButton = canAuthenticateButton;
-        mUseCryptoCheckbox = useCryptoCheckbox;
-        mConfirmationRequiredCheckbox = confirmationRequiredCheckbox;
-        mDeviceCredentialAllowedCheckbox = deviceCredentialAllowedCheckbox;
-        mRadioGroup = radioGroup;
-        mLogView = logView;
+    BiometricPromptDemoController(@NonNull View inflatedRootView) {
+        mCanAuthenticateButton = inflatedRootView.findViewById(R.id.can_authenticate);
+        mAuthenticateButton = inflatedRootView.findViewById(R.id.button_authenticate);
+        mRequireConfirmationCheckbox = inflatedRootView.findViewById(
+                R.id.checkbox_require_confirmation);
+        mAllowDeviceCredentialCheckbox = inflatedRootView.findViewById(
+                R.id.checkbox_allow_device_credential);
+        mBiometricPromptConfigurationRadioGroup = inflatedRootView.findViewById(
+                R.id.radio_group_biometric_prompt_configuration);
 
-        clearLogButton.setOnClickListener((view1) -> logView.setText(""));
+        mLogView = inflatedRootView.findViewById(R.id.log_text);
+
+        Button clearLogButton = inflatedRootView.findViewById(R.id.button_clear_log);
+        clearLogButton.setOnClickListener((view1) -> mLogView.setText(""));
     }
 
     /** Sets up button callbacks and other state for the biometric prompt demo controller. */
@@ -182,23 +139,6 @@
             mCounter = savedInstanceState.getInt(KEY_COUNTER);
             mLogView.setText(savedInstanceState.getCharSequence(KEY_LOG));
         }
-
-        try {
-            mKeyStore = KeyStore.getInstance("AndroidKeyStore");
-        } catch (java.security.KeyStoreException e) {
-            throw new RuntimeException("Failed to get an instance of KeyStore", e);
-        }
-
-        if (!useCrypto()) {
-            mCreateKeysButton.setVisibility(View.GONE);
-        } else {
-            mCreateKeysButton.setVisibility(View.VISIBLE);
-        }
-        mUseCryptoCheckbox.setOnClickListener(this::onCheckboxClicked);
-
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
-            mCreateKeysButton.setOnClickListener(v -> enableBiometricWithCrypto());
-        }
         mAuthenticateButton.setOnClickListener(v -> startAuthentication());
 
         mCanAuthenticateButton.setOnClickListener(v -> {
@@ -225,8 +165,8 @@
 
 
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
-            mDeviceCredentialAllowedCheckbox.setEnabled(false);
-            mDeviceCredentialAllowedCheckbox.setChecked(false);
+            mAllowDeviceCredentialCheckbox.setEnabled(false);
+            mAllowDeviceCredentialCheckbox.setChecked(false);
         }
     }
 
@@ -241,18 +181,6 @@
         outState.putCharSequence(KEY_LOG, mLogView.getText());
     }
 
-    @RequiresApi(Build.VERSION_CODES.M)
-    private void enableBiometricWithCrypto() {
-        // Create the key, this is usually done when the user allows Biometric
-        // authentication in the app. This key is invalidated by new biometric enrollment
-        // (done in createKey())
-        try {
-            createKey(DEFAULT_KEY_NAME, true);
-        } catch (RuntimeException e) {
-            log(e.getMessage());
-        }
-    }
-
     private void startAuthentication() {
         if (getMode() == MODE_NONE) {
             log("Select a test first");
@@ -266,128 +194,26 @@
                 .setDescription(
                         "Lorem ipsum dolor sit amet, consecte etur adipisicing elit. "
                                 + mCounter)
-                .setConfirmationRequired(mConfirmationRequiredCheckbox.isChecked());
+                .setConfirmationRequired(mRequireConfirmationCheckbox.isChecked());
 
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
-            if (mDeviceCredentialAllowedCheckbox.isChecked()) {
-                builder.setDeviceCredentialAllowed(true);
-            } else {
-                builder.setNegativeButtonText("Negative Button " + mCounter);
-            }
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
+                && mAllowDeviceCredentialCheckbox.isChecked()) {
+            builder.setDeviceCredentialAllowed(true);
         } else {
             builder.setNegativeButtonText("Negative Button " + mCounter);
         }
         BiometricPrompt.PromptInfo info = builder.build();
         mCounter++;
 
-        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M && useCrypto()) {
-            try {
-                // Initialize the cipher. The cipher will be unlocked by KeyStore after the user has
-                // authenticated via biometrics.
-                Cipher defaultCipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
-                        + KeyProperties.BLOCK_MODE_CBC + "/"
-                        + KeyProperties.ENCRYPTION_PADDING_PKCS7);
-
-                if (initCipher(defaultCipher, DEFAULT_KEY_NAME)) {
-                    BiometricPrompt.CryptoObject crypto =
-                            new BiometricPrompt.CryptoObject(
-                                    defaultCipher);
-
-                    // Show the biometric prompt.
-                    mBiometricPrompt.authenticate(info, crypto);
-                }
-            } catch (RuntimeException e) {
-                log(e.getMessage());
-                return;
-            } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
-                throw new RuntimeException("Failed to get an instance of Cipher", e);
-            }
-        } else {
-            // Show the biometric prompt.
-            mBiometricPrompt.authenticate(info);
-        }
-    }
-
-    @RequiresApi(Build.VERSION_CODES.M)
-    private boolean initCipher(Cipher cipher, String keyName) {
-        try {
-            mKeyStore.load(null);
-            SecretKey key = (SecretKey) mKeyStore.getKey(keyName, null);
-            cipher.init(Cipher.ENCRYPT_MODE, key);
-            return true;
-        } catch (KeyStoreException | CertificateException | UnrecoverableKeyException | IOException
-                | NoSuchAlgorithmException | InvalidKeyException e) {
-            throw new RuntimeException("Failed to init Cipher", e);
-        }
-    }
-
-    @RequiresApi(Build.VERSION_CODES.M)
-    private void createKey(String keyName, boolean invalidatedByBiometricEnrollment) {
-        KeyGenerator keyGenerator;
-
-        try {
-            keyGenerator = KeyGenerator
-                    .getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
-        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
-            throw new RuntimeException("Failed to get an instance of KeyGenerator", e);
-        }
-
-        // The enrolling flow for fingerprint. This is where you ask the user to set up fingerprint
-        // for your flow. Use of keys is necessary if you need to know if the set of
-        // enrolled fingerprints has changed.
-        try {
-            mKeyStore.load(null);
-
-            // Set the alias of the entry in Android KeyStore where the key will appear
-            // and the constrains (purposes) in the constructor of the Builder
-            KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(
-                    keyName,
-                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
-                    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
-                    // Require the user to authenticate with a fingerprint to authorize every use
-                    // of the key
-                    .setUserAuthenticationRequired(true)
-                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);
-
-            // This is a workaround to avoid crashes on devices whose API level is < 24
-            // because KeyGenParameterSpec.Builder#setInvalidatedByBiometricEnrollment is only
-            // visible on API level 24+.
-            // Ideally there should be a compat library for KeyGenParameterSpec.Builder but
-            // which isn't available yet.
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-                // Invalidate the keys if a new biometric has been enrolled.
-                builder.setInvalidatedByBiometricEnrollment(invalidatedByBiometricEnrollment);
-            }
-            keyGenerator.init(builder.build());
-            keyGenerator.generateKey();
-        } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException
-                | CertificateException | IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private boolean useCrypto() {
-        return mUseCryptoCheckbox.isChecked();
-    }
-
-    /**
-     * Callback when the checkbox is clicked.
-     */
-    private void onCheckboxClicked(View view) {
-        final boolean checked = ((CheckBox) view).isChecked();
-
-        switch (view.getId()) {
-            case R.id.checkbox_use_crypto:
-                mCreateKeysButton.setVisibility(checked ? View.VISIBLE : View.GONE);
-                break;
-        }
+        // Show the biometric prompt.
+        mBiometricPrompt.authenticate(info);
     }
 
     /**
      * @return The currently selected configuration.
      */
     private int getMode() {
-        int id = mRadioGroup.getCheckedRadioButtonId();
+        int id = mBiometricPromptConfigurationRadioGroup.getCheckedRadioButtonId();
         switch (id) {
             case R.id.radio_persist_across_configuration_changes:
                 return MODE_PERSIST_ACROSS_CONFIGURATION_CHANGES;
diff --git a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoCredentialBoundKeyActivity.java b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoCredentialBoundKeyActivity.java
new file mode 100644
index 0000000..6e4dd92
--- /dev/null
+++ b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoCredentialBoundKeyActivity.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2019 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 com.example.android.biometric;
+
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.biometric.BiometricPrompt;
+import androidx.fragment.app.FragmentActivity;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.Arrays;
+import java.util.concurrent.Executor;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+
+/**
+ * Demo activity that shows how BiometricPrompt can be used with credential bound secret keys.
+ */
+@RequiresApi(api = Build.VERSION_CODES.Q)
+public class BiometricPromptDemoCredentialBoundKeyActivity extends FragmentActivity {
+
+    private static final String TAG = "bio_prompt_demo_control";
+    private static final String LOG_BUNDLE = "log";
+    private static final String KEY_NAME = "demo_key";
+    private static final String PAYLOAD = "hello";
+
+    // Specifies the duration for which the key can be used after the last user authentication.
+    // Only affects the keys generated with setUserAuthenticationValidityDurationSeconds(int).
+    private static final int VALIDITY_DURATION = 5;
+
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
+    private final Executor mExecutor = mHandler::post;
+    private BiometricPrompt mBiometricPrompt;
+    private TextView mLogTextView;
+
+    private void log(String s) {
+        Log.d(TAG, s);
+        mLogTextView.append(s + '\n');
+    }
+
+    private void log(String s, Throwable tr) {
+        Log.e(TAG, "", tr);
+        mLogTextView.append(s + '\n' + tr.toString() + '\n');
+    }
+
+    private final BiometricPrompt.PromptInfo mPromptInfo = new BiometricPrompt.PromptInfo.Builder()
+            .setTitle("Title")
+            .setSubtitle("Subtitle")
+            .setDescription("Description")
+            .setDeviceCredentialAllowed(true)
+            .build();
+
+    private final BiometricPrompt.AuthenticationCallback mAuthenticationCallback =
+            new BiometricPrompt.AuthenticationCallback() {
+
+                @Override
+                public void onAuthenticationError(int err, @NonNull CharSequence message) {
+                    log("onAuthenticationError " + err + ": " + message);
+                }
+
+                @Override
+                public void onAuthenticationSucceeded(
+                        @NonNull BiometricPrompt.AuthenticationResult result) {
+                    log("onAuthenticationSucceeded");
+                }
+
+                @Override
+                public void onAuthenticationFailed() {
+                    log("onAuthenticationFailed");
+                    mBiometricPrompt.cancelAuthentication();
+                }
+            };
+
+    private View.OnClickListener mGenerateKeyListener = view -> {
+        try {
+            BiometricPromptDemoSecretKeyHelper.generateCredentialBoundKey(KEY_NAME,
+                    VALIDITY_DURATION);
+            log("Generated a key with a " + VALIDITY_DURATION + " second authentication validity");
+        } catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException
+                | NoSuchProviderException e) {
+            log("Failed to generate key", e);
+        }
+    };
+
+    private View.OnClickListener mUnlockKeyListener = view -> {
+        mBiometricPrompt.authenticate(mPromptInfo);
+        log("Started authentication");
+    };
+
+    private View.OnClickListener mUseKeyListener = view -> {
+        Cipher cipher = null;
+        try {
+            cipher = BiometricPromptDemoSecretKeyHelper.getCipher();
+        } catch (NoSuchPaddingException | NoSuchAlgorithmException e) {
+            log("Failed to get cipher", e);
+        }
+
+        SecretKey secretKey = null;
+        try {
+            secretKey = BiometricPromptDemoSecretKeyHelper.getSecretKey(KEY_NAME);
+        } catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException
+                | UnrecoverableKeyException e) {
+            log("Failed to get secret key", e);
+        }
+
+        if (cipher != null && secretKey != null) {
+            try {
+                cipher.init(Cipher.ENCRYPT_MODE, secretKey);
+                byte[] encrypted = cipher.doFinal(PAYLOAD.getBytes(Charset.defaultCharset()));
+                log("Test payload: " + PAYLOAD);
+                log("Encrypted payload: " + Arrays.toString(encrypted));
+            } catch (InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
+                log("Failed to encrypt", e);
+            }
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.biometric_prompt_demo_credential_bound_key);
+
+        mLogTextView = findViewById(R.id.text_view_log);
+        mBiometricPrompt = new BiometricPrompt(this, mExecutor, mAuthenticationCallback);
+
+        ((TextView) findViewById(R.id.text_view_activity_description)).setText(
+                R.string.label_credential_bound_key_activity_description);
+
+        if (savedInstanceState != null) {
+            mLogTextView.setText(savedInstanceState.getCharSequence(LOG_BUNDLE));
+        }
+
+        findViewById(R.id.button_generate_key).setOnClickListener(mGenerateKeyListener);
+        findViewById(R.id.button_unlock_key).setOnClickListener(mUnlockKeyListener);
+        findViewById(R.id.button_use_key).setOnClickListener(mUseKeyListener);
+        findViewById(R.id.button_clear_log).setOnClickListener(v -> mLogTextView.setText(""));
+    }
+
+    @Override
+    protected void onPause() {
+        mBiometricPrompt.cancelAuthentication();
+        super.onPause();
+    }
+
+    @Override
+    protected void onSaveInstanceState(@NonNull Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putCharSequence(LOG_BUNDLE, mLogTextView.getText());
+    }
+}
diff --git a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoFragmentController.java b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoFragmentController.java
index fb520bd..f38a179 100644
--- a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoFragmentController.java
+++ b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoFragmentController.java
@@ -17,10 +17,7 @@
 package com.example.android.biometric;
 
 import android.content.Context;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.RadioGroup;
-import android.widget.TextView;
+import android.view.View;
 
 import androidx.annotation.NonNull;
 import androidx.biometric.BiometricPrompt;
@@ -38,18 +35,8 @@
     BiometricPromptDemoFragmentController(
             @NonNull Context context,
             @NonNull Fragment fragment,
-            @NonNull Button createKeysButton,
-            @NonNull Button authenticateButton,
-            @NonNull Button canAuthenticateButton,
-            @NonNull CheckBox useCryptoCheckbox,
-            @NonNull CheckBox confirmationRequiredCheckbox,
-            @NonNull CheckBox deviceCredentialAllowedCheckbox,
-            @NonNull RadioGroup radioGroup,
-            @NonNull Button clearLogButton,
-            @NonNull TextView logView) {
-        super(createKeysButton, authenticateButton, canAuthenticateButton, useCryptoCheckbox,
-                confirmationRequiredCheckbox, deviceCredentialAllowedCheckbox, radioGroup,
-                clearLogButton, logView);
+            @NonNull View inflatedRootView) {
+        super(inflatedRootView);
         mContext = context;
         mFragment = fragment;
     }
diff --git a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoFragmentHost.java b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoFragmentHost.java
index 939f73c..a764e98 100644
--- a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoFragmentHost.java
+++ b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoFragmentHost.java
@@ -21,9 +21,6 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.RadioGroup;
 import android.widget.TextView;
 
 import androidx.annotation.NonNull;
@@ -54,30 +51,7 @@
         final TextView hostTypeTextView = view.findViewById(R.id.host_type_text_view);
         hostTypeTextView.setText(R.string.label_host_type_fragment);
 
-        final Button createKeysButton = view.findViewById(R.id.button_enable_biometric_with_crypto);
-        final Button authenticateButton = view.findViewById(R.id.button_authenticate);
-        final Button canAuthenticateButton = view.findViewById(R.id.can_authenticate);
-        final CheckBox useCryptoCheckbox = view.findViewById(R.id.checkbox_use_crypto);
-        final CheckBox confirmationRequiredCheckbox = view.findViewById(
-                R.id.checkbox_require_confirmation);
-        final CheckBox deviceCredentialAllowedCheckbox = view.findViewById(
-                R.id.checkbox_enable_fallback);
-        final RadioGroup radioGroup = view.findViewById(R.id.radio_group);
-        final Button clearLogButton = view.findViewById(R.id.log_clear);
-        final TextView logView = view.findViewById(R.id.log_text);
-
-        mController = new BiometricPromptDemoFragmentController(
-                mContext,
-                this,
-                createKeysButton,
-                authenticateButton,
-                canAuthenticateButton,
-                useCryptoCheckbox,
-                confirmationRequiredCheckbox,
-                deviceCredentialAllowedCheckbox,
-                radioGroup,
-                clearLogButton,
-                logView);
+        mController = new BiometricPromptDemoFragmentController(mContext, this, view);
         mController.init(savedInstanceState);
         mController.reconnect();
         return view;
diff --git a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoSecretKeyHelper.java b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoSecretKeyHelper.java
new file mode 100644
index 0000000..0652611
--- /dev/null
+++ b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemoSecretKeyHelper.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2019 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 com.example.android.biometric;
+
+import android.os.Build;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
+
+import androidx.annotation.RequiresApi;
+
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+
+/**
+ * Helper class that provides methods for generating and accessing secret keys, and showcases
+ * the differences between the keys that require biometrics and the keys bound to user credentials.
+ */
+@RequiresApi(api = Build.VERSION_CODES.M)
+final class BiometricPromptDemoSecretKeyHelper {
+
+    /**
+     * Generates a key that requires the user to authenticate with a biometric before each use.
+     */
+    static void generateBiometricBoundKey(String keyName,
+            boolean invalidatedByBiometricEnrollment)
+            throws InvalidAlgorithmParameterException, NoSuchAlgorithmException,
+            NoSuchProviderException {
+        generateKey(keyName, true, invalidatedByBiometricEnrollment, -1);
+    }
+
+    /**
+     * Generates a key that can only be used if the user is authenticated via secure lock screen or
+     * {@link androidx.biometric.BiometricPrompt.PromptInfo.Builder#setDeviceCredentialAllowed(
+     *boolean)}
+     */
+    static void generateCredentialBoundKey(String keyName, int validityDuration)
+            throws InvalidAlgorithmParameterException, NoSuchAlgorithmException,
+            NoSuchProviderException {
+        generateKey(keyName, false, false, validityDuration);
+    }
+
+    private static void generateKey(String keyName, boolean biometricBound,
+            boolean invalidatedByBiometricEnrollment, int validityDuration)
+            throws NoSuchProviderException, NoSuchAlgorithmException,
+            InvalidAlgorithmParameterException {
+        KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(
+                keyName,
+                KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
+                .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
+                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
+                .setUserAuthenticationRequired(true);
+
+        if (biometricBound) {
+            // Require the user to authenticate for every use of the key. This is the default, i.e.
+            // userAuthenticationValidityDurationSeconds is -1 unless specified otherwise.
+            // Explicitly setting it to -1 here for the sake of example.
+            // For this to work, at least one biometric must be enrolled.
+            builder.setUserAuthenticationValidityDurationSeconds(-1);
+
+            // This is a workaround to avoid crashes on devices whose API level is < 24
+            // because KeyGenParameterSpec.Builder#setInvalidatedByBiometricEnrollment is only
+            // visible on API level 24+.
+            // Ideally there should be a compat library for KeyGenParameterSpec.Builder but
+            // it isn't available yet.
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+                // Invalidate the keys if a new biometric has been enrolled.
+                builder.setInvalidatedByBiometricEnrollment(invalidatedByBiometricEnrollment);
+            }
+        } else {
+            // Sets the duration for which the key can be used after the last user authentication.
+            // For this to work, authentication must happen either via secure lock screen or the
+            // ConfirmDeviceCredential flow, which can be done by creating BiometricPrompt with
+            // BiometricPrompt.PromptInfo.Builder#setDeviceCredentialAllowed(true)
+            builder.setUserAuthenticationValidityDurationSeconds(validityDuration);
+        }
+
+        KeyGenerator keyGenerator = KeyGenerator
+                .getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
+        keyGenerator.init(builder.build());
+
+        // Generates and stores the key in Android KeyStore under the keystoreAlias (keyName)
+        // specified in the builder.
+        keyGenerator.generateKey();
+    }
+
+    static SecretKey getSecretKey(String keyName)
+            throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException,
+            UnrecoverableKeyException {
+        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+
+        // Before the keystore can be accessed, it must be loaded.
+        keyStore.load(null);
+        return (SecretKey) keyStore.getKey(keyName, null);
+    }
+
+    static Cipher getCipher() throws NoSuchPaddingException, NoSuchAlgorithmException {
+        return Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+                + KeyProperties.BLOCK_MODE_CBC + "/"
+                + KeyProperties.ENCRYPTION_PADDING_PKCS7);
+    }
+}
diff --git a/samples/BiometricDemos/src/main/res/layout/biometric_prompt_demo.xml b/samples/BiometricDemos/src/main/res/layout/biometric_prompt_demo.xml
index 008413f..c69b2c7 100644
--- a/samples/BiometricDemos/src/main/res/layout/biometric_prompt_demo.xml
+++ b/samples/BiometricDemos/src/main/res/layout/biometric_prompt_demo.xml
@@ -23,18 +23,34 @@
     <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:text="@string/label_choose_host_type"/>
+        android:text="@string/label_choose_mode" />
 
     <Button
         android:id="@+id/host_in_activity_button"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:text="@string/button_host_in_activity"/>
+        android:text="@string/button_host_in_activity"
+        android:textSize="12sp" />
 
     <Button
         android:id="@+id/host_in_fragment_button"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:text="@string/button_host_in_fragment"/>
+        android:text="@string/button_host_in_fragment"
+        android:textSize="12sp" />
+
+    <Button
+        android:id="@+id/button_biometric_bound_key_demo"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/button_biometric_bound_demo"
+        android:textSize="12sp" />
+
+    <Button
+        android:id="@+id/button_credential_bound_key_demo"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/button_credential_bound_demo"
+        android:textSize="12sp" />
 
 </LinearLayout>
\ No newline at end of file
diff --git a/samples/BiometricDemos/src/main/res/layout/biometric_prompt_demo_biometric_bound_key.xml b/samples/BiometricDemos/src/main/res/layout/biometric_prompt_demo_biometric_bound_key.xml
new file mode 100644
index 0000000..f37ae40
--- /dev/null
+++ b/samples/BiometricDemos/src/main/res/layout/biometric_prompt_demo_biometric_bound_key.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2019 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_view_activity_description"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+
+    <Button
+        android:id="@+id/button_generate_key"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/button_generate_key" />
+
+    <Button
+        android:id="@+id/button_unlock_and_use_key"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/button_unlock_and_use_key" />
+
+    <Button
+        android:id="@+id/button_clear_log"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/button_clear_log" />
+
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <TextView
+            android:id="@+id/text_view_log"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+    </ScrollView>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/BiometricDemos/src/main/res/layout/biometric_prompt_demo_content.xml b/samples/BiometricDemos/src/main/res/layout/biometric_prompt_demo_content.xml
index a288a29..1b3138b 100644
--- a/samples/BiometricDemos/src/main/res/layout/biometric_prompt_demo_content.xml
+++ b/samples/BiometricDemos/src/main/res/layout/biometric_prompt_demo_content.xml
@@ -15,8 +15,7 @@
   ~ limitations under the License.
   -->
 
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical">
@@ -24,7 +23,7 @@
     <TextView
         android:id="@+id/host_type_text_view"
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
+        android:layout_height="wrap_content" />
 
     <ScrollView
         android:layout_width="match_parent"
@@ -36,49 +35,34 @@
             android:orientation="vertical">
 
             <Button
-                android:id="@+id/button_enable_biometric_with_crypto"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:text="@string/button_enable_biometric_with_crypto"/>
-
-            <Button
                 android:id="@+id/can_authenticate"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:text="@string/button_can_authenticate"/>
+                android:text="@string/button_can_authenticate" />
 
             <Button
                 android:id="@+id/button_authenticate"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:text="@string/button_authenticate"/>
+                android:text="@string/button_authenticate" />
 
-            <LinearLayout android:layout_width="match_parent"
+            <CheckBox
+                android:id="@+id/checkbox_require_confirmation"
+                android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:orientation="vertical">
-                <CheckBox
-                    android:id="@+id/checkbox_use_crypto"
-                    android:layout_weight="1"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="@string/checkbox_text_use_crypto"/>
-                <CheckBox
-                    android:id="@+id/checkbox_require_confirmation"
-                    android:layout_weight="1"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="@string/checkbox_text_require_confirmation"
-                    android:checked="true"/>
-                <CheckBox
-                    android:id="@+id/checkbox_enable_fallback"
-                    android:layout_weight="1"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="@string/checkbox_text_allow_device_credential"/>
-            </LinearLayout>
+                android:layout_weight="1"
+                android:checked="true"
+                android:text="@string/checkbox_text_require_confirmation" />
+
+            <CheckBox
+                android:id="@+id/checkbox_allow_device_credential"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/checkbox_text_allow_device_credential" />
 
             <RadioGroup
-                android:id="@+id/radio_group"
+                android:id="@+id/radio_group_biometric_prompt_configuration"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content">
 
@@ -86,34 +70,35 @@
                     android:id="@+id/radio_persist_across_configuration_changes"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:text="@string/radio_text_persist_across_configuration_changes"/>
+                    android:checked="true"
+                    android:text="@string/radio_text_persist_across_configuration_changes" />
 
                 <RadioButton
                     android:id="@+id/radio_cancel_on_configuration_change"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:text="@string/radio_text_cancel_on_configuration_change"/>
+                    android:text="@string/radio_text_cancel_on_configuration_change" />
 
                 <RadioButton
                     android:id="@+id/radio_cancel_after_three_failures"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:text="@string/radio_text_cancel_after_three_failures"/>
+                    android:text="@string/radio_text_cancel_after_three_failures" />
             </RadioGroup>
 
             <Button
-                android:id="@+id/log_clear"
+                android:id="@+id/button_clear_log"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:text="@string/button_clear_log"/>
+                android:text="@string/button_clear_log" />
 
             <TextView
                 android:id="@+id/log_text"
                 android:layout_width="match_parent"
-                android:layout_height="match_parent"/>
+                android:layout_height="match_parent" />
 
         </LinearLayout>
 
     </ScrollView>
 
-</LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/BiometricDemos/src/main/res/layout/biometric_prompt_demo_credential_bound_key.xml b/samples/BiometricDemos/src/main/res/layout/biometric_prompt_demo_credential_bound_key.xml
new file mode 100644
index 0000000..1e57933
--- /dev/null
+++ b/samples/BiometricDemos/src/main/res/layout/biometric_prompt_demo_credential_bound_key.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2019 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_view_activity_description"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"/>
+
+    <Button
+        android:id="@+id/button_generate_key"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/button_generate_key" />
+
+    <Button
+        android:id="@+id/button_unlock_key"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/button_unlock_key" />
+
+    <Button
+        android:id="@+id/button_use_key"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/button_use_key" />
+
+    <Button
+        android:id="@+id/button_clear_log"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/button_clear_log" />
+
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <TextView
+            android:id="@+id/text_view_log"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+    </ScrollView>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/BiometricDemos/src/main/res/values/strings.xml b/samples/BiometricDemos/src/main/res/values/strings.xml
index 7ef3964..4d048d8 100644
--- a/samples/BiometricDemos/src/main/res/values/strings.xml
+++ b/samples/BiometricDemos/src/main/res/values/strings.xml
@@ -16,24 +16,49 @@
   -->
 
 <resources>
+
+    <!-- BiometricPromptDemo -->
     <string name="activity_sample_code">Biometric Demo</string>
+    <string name="label_choose_mode">Choose a mode for the biometric prompt:</string>
+    <string name="button_host_in_activity">Biometric prompt in a FragmentActivity</string>
+    <string name="button_host_in_fragment">Biometric prompt in a Fragment</string>
+    <string name="button_biometric_bound_demo">Biometric prompt with biometric bound secret keys</string>
+    <string name="button_credential_bound_demo">Biometric prompt with credential bound secret
+        keys</string>
 
-    <string name="button_enable_biometric_with_crypto">Create keys (for crypto)</string>
-    <string name="button_authenticate">Authenticate</string>
-    <string name="button_can_authenticate">Can Authenticate</string>
-    <string name="button_host_in_activity">Host in a FragmentActivity</string>
-    <string name="button_host_in_fragment">Host in a Fragment</string>
-    <string name="button_clear_log">Clear logs</string>
-
-    <string name="checkbox_text_use_crypto">Use crypto</string>
-    <string name="checkbox_text_require_confirmation">Require confirmation</string>
-    <string name="checkbox_text_allow_device_credential">Allow Device Credential</string>
-
-    <string name="label_choose_host_type">Choose a host for the biometric prompt:</string>
+    <!-- BiometricPromptDemoActivityHost -->
     <string name="label_host_type_activity">Currently hosted in a FragmentActivity</string>
+
+    <!-- BiometricPromptDemoFragmentHost -->
     <string name="label_host_type_fragment">Currently hosted in a Fragment</string>
 
+    <!-- BiometricPromptDemoController -->
+    <string name="button_can_authenticate">Can authenticate</string>
+    <string name="button_authenticate">Authenticate</string>
+
+    <string name="checkbox_text_require_confirmation">Require confirmation</string>
+    <string name="checkbox_text_allow_device_credential">Allow device credential</string>
+
     <string name="radio_text_persist_across_configuration_changes">Persist across configuration changes</string>
     <string name="radio_text_cancel_on_configuration_change">Cancel when configuration changes</string>
     <string name="radio_text_cancel_after_three_failures">Cancel after three failures</string>
+
+    <!-- Shared between multiple activities -->
+    <string name="button_generate_key">Generate key</string>
+    <string name="button_clear_log">Clear logs</string>
+
+    <!-- BiometricPromptDemoBiometricBoundKeyActivity -->
+    <string name="label_biometric_bound_key_activity_description">This activity shows how to handle
+        secret keys that require biometric authentication before each use.</string>
+    <string name="button_unlock_and_use_key">Unlock and use the key to encrypt test payload</string>
+
+    <!-- BiometricPromptDemoCredentialBoundKeyActivity -->
+    <string name="label_credential_bound_key_activity_description">This activity shows how to handle
+        secret keys that can only be used if the user is authenticated via secure lock screen or
+        PromptInfo.Builder#setDeviceCredentialAllowed(true). These keys might also have a
+        custom authentication validity duration, allowing the key to be used for some period of
+        time after the last authentication.</string>
+    <string name="button_unlock_key">Authenticate to unlock the key</string>
+    <string name="button_use_key">Use the key to encrypt test payload</string>
+
 </resources>
diff --git a/samples/BiometricDemos/src/main/res/values/styles.xml b/samples/BiometricDemos/src/main/res/values/styles.xml
index a23369f..c9e62d214 100644
--- a/samples/BiometricDemos/src/main/res/values/styles.xml
+++ b/samples/BiometricDemos/src/main/res/values/styles.xml
@@ -16,5 +16,5 @@
   -->
 
 <resources>
-    <style name="AppTheme" parent="Theme.AppCompat.DayNight"></style>
+    <style name="AppTheme" parent="Theme.AppCompat.DayNight"/>
 </resources>
diff --git a/samples/SupportPreferenceDemos/build.gradle b/samples/SupportPreferenceDemos/build.gradle
index fbdb445..bebcee1 100644
--- a/samples/SupportPreferenceDemos/build.gradle
+++ b/samples/SupportPreferenceDemos/build.gradle
@@ -5,8 +5,8 @@
 
 dependencies {
     implementation(project(":appcompat"))
+    implementation(project(":preference:preference"))
     implementation(project(":recyclerview:recyclerview"))
-    implementation(project(":preference"))
     implementation(project(":leanback"))
     implementation(project(":leanback-preference"))
     implementation(project(":car"))
diff --git a/settings.gradle b/settings.gradle
index 8e9171e..ec48eef 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -63,6 +63,7 @@
 includeProject(":benchmark:benchmark-junit4", "benchmark/junit4")
 includeProject(":benchmark:benchmark-benchmark", "benchmark/benchmark")
 includeProject(":benchmark:benchmark-gradle-plugin", "benchmark/gradle-plugin")
+includeProject(":benchmark:integration-tests:dry-run-benchmark", "benchmark/integration-tests/dry-run-benchmark")
 includeProject(":benchmark:integration-tests:startup-benchmark", "benchmark/integration-tests/startup-benchmark")
 includeProject(":biometric", "biometric")
 includeProject(":browser", "browser")
@@ -109,7 +110,7 @@
 includeProject(":fakeannotations", "fakeannotations")
 includeProject(":gridlayout", "gridlayout")
 includeProject(":heifwriter", "heifwriter")
-includeProject(":inspection:inspection-agent", "inspection/inspection-agent")
+includeProject(":inspection:inspection", "inspection/inspection")
 includeProject(":interpolator", "interpolator")
 includeProject(":jetifier-core", "jetifier/jetifier/core")
 includeProject(":jetifier-processor", "jetifier/jetifier/processor")
@@ -172,8 +173,8 @@
 includeProject(":palette:palette", "palette/palette")
 includeProject(":palette:palette-ktx", "palette/palette-ktx")
 includeProject(":percentlayout:percentlayout", "percentlayout/percentlayout")
-includeProject(":preference", "preference")
-includeProject(":preference-ktx", "preference/ktx")
+includeProject(":preference:preference", "preference/preference")
+includeProject(":preference:preference-ktx", "preference/preference-ktx")
 includeProject(":print", "print")
 includeProject(":recommendation", "recommendation")
 includeProject(":recyclerview:recyclerview", "recyclerview/recyclerview")
@@ -233,6 +234,7 @@
 includeProject(":work:work-runtime-ktx", "work/workmanager-ktx")
 includeProject(":work:work-rxjava2", "work/workmanager-rxjava2")
 includeProject(":work:work-testing", "work/workmanager-testing")
+includeProject(":work:work-benchmark", "work/workmanager-benchmark")
 includeProject(":work:integration-tests:testapp", "work/integration-tests/testapp")
 
 /////////////////////////////
diff --git a/slices/builders/api/api_lint.ignore b/slices/builders/api/api_lint.ignore
new file mode 100644
index 0000000..4f32b59
--- /dev/null
+++ b/slices/builders/api/api_lint.ignore
@@ -0,0 +1,47 @@
+// Baseline format: 1.0
+MissingNullability: androidx.slice.builders.ListBuilder#setKeywords(java.util.Set<java.lang.String>) parameter #0:
+    Missing nullability on parameter `keywords` in method `setKeywords`
+MissingNullability: androidx.slice.builders.ListBuilder.RowBuilder#RowBuilder(android.net.Uri) parameter #0:
+    Missing nullability on parameter `uri` in method `RowBuilder`
+MissingNullability: androidx.slice.builders.ListBuilder.RowBuilder#setTitleItem(androidx.core.graphics.drawable.IconCompat, int):
+    Missing nullability on method `setTitleItem` return
+MissingNullability: androidx.slice.builders.SelectionBuilder#addOption(String, CharSequence):
+    Missing nullability on method `addOption` return
+MissingNullability: androidx.slice.builders.SelectionBuilder#addOption(String, CharSequence) parameter #0:
+    Missing nullability on parameter `optionKey` in method `addOption`
+MissingNullability: androidx.slice.builders.SelectionBuilder#addOption(String, CharSequence) parameter #1:
+    Missing nullability on parameter `optionText` in method `addOption`
+MissingNullability: androidx.slice.builders.SelectionBuilder#setContentDescription(CharSequence):
+    Missing nullability on method `setContentDescription` return
+MissingNullability: androidx.slice.builders.SelectionBuilder#setInputAction(android.app.PendingIntent):
+    Missing nullability on method `setInputAction` return
+MissingNullability: androidx.slice.builders.SelectionBuilder#setInputAction(androidx.remotecallback.RemoteCallback):
+    Missing nullability on method `setInputAction` return
+MissingNullability: androidx.slice.builders.SelectionBuilder#setLayoutDirection(int):
+    Missing nullability on method `setLayoutDirection` return
+MissingNullability: androidx.slice.builders.SelectionBuilder#setPrimaryAction(androidx.slice.builders.SliceAction):
+    Missing nullability on method `setPrimaryAction` return
+MissingNullability: androidx.slice.builders.SelectionBuilder#setSelectedOption(String):
+    Missing nullability on method `setSelectedOption` return
+MissingNullability: androidx.slice.builders.SelectionBuilder#setSelectedOption(String) parameter #0:
+    Missing nullability on parameter `selectedOption` in method `setSelectedOption`
+MissingNullability: androidx.slice.builders.SelectionBuilder#setSubtitle(CharSequence):
+    Missing nullability on method `setSubtitle` return
+MissingNullability: androidx.slice.builders.SelectionBuilder#setTitle(CharSequence):
+    Missing nullability on method `setTitle` return
+MissingNullability: androidx.slice.builders.SliceAction#create(android.app.PendingIntent, androidx.core.graphics.drawable.IconCompat, int, CharSequence):
+    Missing nullability on method `create` return
+MissingNullability: androidx.slice.builders.SliceAction#create(androidx.remotecallback.RemoteCallback, androidx.core.graphics.drawable.IconCompat, int, CharSequence):
+    Missing nullability on method `create` return
+MissingNullability: androidx.slice.builders.SliceAction#createDeeplink(android.app.PendingIntent, androidx.core.graphics.drawable.IconCompat, int, CharSequence):
+    Missing nullability on method `createDeeplink` return
+MissingNullability: androidx.slice.builders.SliceAction#createDeeplink(androidx.remotecallback.RemoteCallback, androidx.core.graphics.drawable.IconCompat, int, CharSequence):
+    Missing nullability on method `createDeeplink` return
+MissingNullability: androidx.slice.builders.SliceAction#createToggle(android.app.PendingIntent, CharSequence, boolean):
+    Missing nullability on method `createToggle` return
+MissingNullability: androidx.slice.builders.SliceAction#createToggle(android.app.PendingIntent, androidx.core.graphics.drawable.IconCompat, CharSequence, boolean):
+    Missing nullability on method `createToggle` return
+MissingNullability: androidx.slice.builders.SliceAction#createToggle(androidx.remotecallback.RemoteCallback, CharSequence, boolean):
+    Missing nullability on method `createToggle` return
+MissingNullability: androidx.slice.builders.SliceAction#createToggle(androidx.remotecallback.RemoteCallback, androidx.core.graphics.drawable.IconCompat, CharSequence, boolean):
+    Missing nullability on method `createToggle` return
diff --git a/slices/core/api/1.1.0-alpha02.txt b/slices/core/api/1.1.0-alpha02.txt
index d9e4591..bada082 100644
--- a/slices/core/api/1.1.0-alpha02.txt
+++ b/slices/core/api/1.1.0-alpha02.txt
@@ -44,17 +44,17 @@
     method @RequiresApi(19) public final android.net.Uri? canonicalize(android.net.Uri);
     method public final int delete(android.net.Uri, String?, String![]?);
     method @RequiresApi(19) public java.util.List<android.net.Uri!> getPinnedSlices();
-    method public final String! getType(android.net.Uri!);
-    method @RequiresApi(19) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY) public Object! getWrapper();
+    method public final String? getType(android.net.Uri);
+    method @RequiresApi(19) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY) public Object? getWrapper();
     method public final android.net.Uri? insert(android.net.Uri, android.content.ContentValues?);
-    method @RequiresApi(19) public abstract androidx.slice.Slice! onBindSlice(android.net.Uri!);
+    method @RequiresApi(19) public abstract androidx.slice.Slice? onBindSlice(android.net.Uri);
     method public final boolean onCreate();
     method public android.app.PendingIntent? onCreatePermissionRequest(android.net.Uri, String);
     method @RequiresApi(19) public abstract boolean onCreateSliceProvider();
-    method @RequiresApi(19) public java.util.Collection<android.net.Uri!>! onGetSliceDescendants(android.net.Uri!);
-    method @RequiresApi(19) public android.net.Uri onMapIntentToUri(android.content.Intent!);
-    method @RequiresApi(19) public void onSlicePinned(android.net.Uri!);
-    method @RequiresApi(19) public void onSliceUnpinned(android.net.Uri!);
+    method @RequiresApi(19) public java.util.Collection<android.net.Uri!> onGetSliceDescendants(android.net.Uri);
+    method @RequiresApi(19) public android.net.Uri onMapIntentToUri(android.content.Intent);
+    method @RequiresApi(19) public void onSlicePinned(android.net.Uri);
+    method @RequiresApi(19) public void onSliceUnpinned(android.net.Uri);
     method public final android.database.Cursor? query(android.net.Uri, String![]?, String?, String![]?, String?);
     method @RequiresApi(28) public final android.database.Cursor? query(android.net.Uri, String![]?, android.os.Bundle?, android.os.CancellationSignal?);
     method @RequiresApi(16) public final android.database.Cursor? query(android.net.Uri, String![]?, String?, String![]?, String?, android.os.CancellationSignal?);
@@ -63,8 +63,8 @@
 
   public abstract class SliceProviderWithCallbacks<T extends androidx.slice.SliceProviderWithCallbacks> extends androidx.slice.SliceProvider implements androidx.remotecallback.CallbackBase<T> androidx.remotecallback.CallbackReceiver<T> {
     ctor public SliceProviderWithCallbacks();
-    method public T! createRemoteCallback(android.content.Context!);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.remotecallback.RemoteCallback! toRemoteCallback(Class<T!>!, android.content.Context!, String!, android.os.Bundle!, String!);
+    method public T createRemoteCallback(android.content.Context);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.remotecallback.RemoteCallback toRemoteCallback(Class<T!>, android.content.Context, String?, android.os.Bundle, String?);
   }
 
 }
diff --git a/slices/core/api/api_lint.ignore b/slices/core/api/api_lint.ignore
index cfd172f..09f02da 100644
--- a/slices/core/api/api_lint.ignore
+++ b/slices/core/api/api_lint.ignore
@@ -11,5 +11,45 @@
     Inconsistent class name; should be `<Foo>Provider`, was `SliceProviderWithCallbacks`
 
 
+MissingNullability: androidx.slice.Slice#getHints():
+    Missing nullability on method `getHints` return
+MissingNullability: androidx.slice.Slice#getItems():
+    Missing nullability on method `getItems` return
+MissingNullability: androidx.slice.Slice#getUri():
+    Missing nullability on method `getUri` return
+MissingNullability: androidx.slice.Slice#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.slice.SliceConvert#unwrap(androidx.slice.Slice):
+    Missing nullability on method `unwrap` return
+MissingNullability: androidx.slice.SliceConvert#unwrap(androidx.slice.Slice) parameter #0:
+    Missing nullability on parameter `slice` in method `unwrap`
+MissingNullability: androidx.slice.SliceConvert#wrap(android.app.slice.Slice, android.content.Context):
+    Missing nullability on method `wrap` return
+MissingNullability: androidx.slice.SliceConvert#wrap(android.app.slice.Slice, android.content.Context) parameter #0:
+    Missing nullability on parameter `slice` in method `wrap`
+MissingNullability: androidx.slice.SliceConvert#wrap(android.app.slice.Slice, android.content.Context) parameter #1:
+    Missing nullability on parameter `context` in method `wrap`
+MissingNullability: androidx.slice.SliceItem#getAction():
+    Missing nullability on method `getAction` return
+MissingNullability: androidx.slice.SliceItem#getFormat():
+    Missing nullability on method `getFormat` return
+MissingNullability: androidx.slice.SliceItem#getIcon():
+    Missing nullability on method `getIcon` return
+MissingNullability: androidx.slice.SliceItem#getSlice():
+    Missing nullability on method `getSlice` return
+MissingNullability: androidx.slice.SliceItem#getSubType():
+    Missing nullability on method `getSubType` return
+MissingNullability: androidx.slice.SliceItem#getText():
+    Missing nullability on method `getText` return
+MissingNullability: androidx.slice.SliceItem#hasHint(String) parameter #0:
+    Missing nullability on parameter `hint` in method `hasHint`
+MissingNullability: androidx.slice.SliceItem#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.slice.core.SliceAction#setChecked(boolean):
+    Missing nullability on method `setChecked` return
+MissingNullability: androidx.slice.core.SliceAction#setPriority(int):
+    Missing nullability on method `setPriority` return
+
+
 SingularCallback: androidx.slice.SliceProviderWithCallbacks:
     Callback class names should be singular: SliceProviderWithCallbacks
diff --git a/slices/core/api/current.txt b/slices/core/api/current.txt
index d9e4591..bada082 100644
--- a/slices/core/api/current.txt
+++ b/slices/core/api/current.txt
@@ -44,17 +44,17 @@
     method @RequiresApi(19) public final android.net.Uri? canonicalize(android.net.Uri);
     method public final int delete(android.net.Uri, String?, String![]?);
     method @RequiresApi(19) public java.util.List<android.net.Uri!> getPinnedSlices();
-    method public final String! getType(android.net.Uri!);
-    method @RequiresApi(19) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY) public Object! getWrapper();
+    method public final String? getType(android.net.Uri);
+    method @RequiresApi(19) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY) public Object? getWrapper();
     method public final android.net.Uri? insert(android.net.Uri, android.content.ContentValues?);
-    method @RequiresApi(19) public abstract androidx.slice.Slice! onBindSlice(android.net.Uri!);
+    method @RequiresApi(19) public abstract androidx.slice.Slice? onBindSlice(android.net.Uri);
     method public final boolean onCreate();
     method public android.app.PendingIntent? onCreatePermissionRequest(android.net.Uri, String);
     method @RequiresApi(19) public abstract boolean onCreateSliceProvider();
-    method @RequiresApi(19) public java.util.Collection<android.net.Uri!>! onGetSliceDescendants(android.net.Uri!);
-    method @RequiresApi(19) public android.net.Uri onMapIntentToUri(android.content.Intent!);
-    method @RequiresApi(19) public void onSlicePinned(android.net.Uri!);
-    method @RequiresApi(19) public void onSliceUnpinned(android.net.Uri!);
+    method @RequiresApi(19) public java.util.Collection<android.net.Uri!> onGetSliceDescendants(android.net.Uri);
+    method @RequiresApi(19) public android.net.Uri onMapIntentToUri(android.content.Intent);
+    method @RequiresApi(19) public void onSlicePinned(android.net.Uri);
+    method @RequiresApi(19) public void onSliceUnpinned(android.net.Uri);
     method public final android.database.Cursor? query(android.net.Uri, String![]?, String?, String![]?, String?);
     method @RequiresApi(28) public final android.database.Cursor? query(android.net.Uri, String![]?, android.os.Bundle?, android.os.CancellationSignal?);
     method @RequiresApi(16) public final android.database.Cursor? query(android.net.Uri, String![]?, String?, String![]?, String?, android.os.CancellationSignal?);
@@ -63,8 +63,8 @@
 
   public abstract class SliceProviderWithCallbacks<T extends androidx.slice.SliceProviderWithCallbacks> extends androidx.slice.SliceProvider implements androidx.remotecallback.CallbackBase<T> androidx.remotecallback.CallbackReceiver<T> {
     ctor public SliceProviderWithCallbacks();
-    method public T! createRemoteCallback(android.content.Context!);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.remotecallback.RemoteCallback! toRemoteCallback(Class<T!>!, android.content.Context!, String!, android.os.Bundle!, String!);
+    method public T createRemoteCallback(android.content.Context);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.remotecallback.RemoteCallback toRemoteCallback(Class<T!>, android.content.Context, String?, android.os.Bundle, String?);
   }
 
 }
diff --git a/slices/core/api/restricted_1.1.0-alpha02.txt b/slices/core/api/restricted_1.1.0-alpha02.txt
index c9d8659..3cf1dca 100644
--- a/slices/core/api/restricted_1.1.0-alpha02.txt
+++ b/slices/core/api/restricted_1.1.0-alpha02.txt
@@ -104,19 +104,19 @@
     method public final int bulkInsert(android.net.Uri, android.content.ContentValues![]);
     method @RequiresApi(19) public final android.net.Uri? canonicalize(android.net.Uri);
     method public final int delete(android.net.Uri, String?, String![]?);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @RequiresApi(19) public static androidx.slice.Clock! getClock();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @RequiresApi(19) public static java.util.Set<androidx.slice.SliceSpec!>! getCurrentSpecs();
+    method @RequiresApi(19) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public static androidx.slice.Clock? getClock();
+    method @RequiresApi(19) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static java.util.Set<androidx.slice.SliceSpec!>? getCurrentSpecs();
     method @RequiresApi(19) public java.util.List<android.net.Uri!> getPinnedSlices();
-    method public final String! getType(android.net.Uri!);
+    method public final String? getType(android.net.Uri);
     method public final android.net.Uri? insert(android.net.Uri, android.content.ContentValues?);
-    method @RequiresApi(19) public abstract androidx.slice.Slice! onBindSlice(android.net.Uri!);
+    method @RequiresApi(19) public abstract androidx.slice.Slice? onBindSlice(android.net.Uri);
     method public final boolean onCreate();
     method public android.app.PendingIntent? onCreatePermissionRequest(android.net.Uri, String);
     method @RequiresApi(19) public abstract boolean onCreateSliceProvider();
-    method @RequiresApi(19) public java.util.Collection<android.net.Uri!>! onGetSliceDescendants(android.net.Uri!);
-    method @RequiresApi(19) public android.net.Uri onMapIntentToUri(android.content.Intent!);
-    method @RequiresApi(19) public void onSlicePinned(android.net.Uri!);
-    method @RequiresApi(19) public void onSliceUnpinned(android.net.Uri!);
+    method @RequiresApi(19) public java.util.Collection<android.net.Uri!> onGetSliceDescendants(android.net.Uri);
+    method @RequiresApi(19) public android.net.Uri onMapIntentToUri(android.content.Intent);
+    method @RequiresApi(19) public void onSlicePinned(android.net.Uri);
+    method @RequiresApi(19) public void onSliceUnpinned(android.net.Uri);
     method public final android.database.Cursor? query(android.net.Uri, String![]?, String?, String![]?, String?);
     method @RequiresApi(28) public final android.database.Cursor? query(android.net.Uri, String![]?, android.os.Bundle?, android.os.CancellationSignal?);
     method @RequiresApi(16) public final android.database.Cursor? query(android.net.Uri, String![]?, String?, String![]?, String?, android.os.CancellationSignal?);
@@ -125,8 +125,8 @@
 
   public abstract class SliceProviderWithCallbacks<T extends androidx.slice.SliceProviderWithCallbacks> extends androidx.slice.SliceProvider implements androidx.remotecallback.CallbackBase<T> androidx.remotecallback.CallbackReceiver<T> {
     ctor public SliceProviderWithCallbacks();
-    method public T! createRemoteCallback(android.content.Context!);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.remotecallback.RemoteCallback! toRemoteCallback(Class<T!>!, android.content.Context!, String!, android.os.Bundle!, String!);
+    method public T createRemoteCallback(android.content.Context);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.remotecallback.RemoteCallback toRemoteCallback(Class<T!>, android.content.Context, String?, android.os.Bundle, String?);
   }
 
   @RequiresApi(19) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class SliceSpec implements androidx.versionedparcelable.VersionedParcelable {
@@ -163,22 +163,22 @@
 
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @RequiresApi(19) public class SliceProviderCompat {
-    ctor public SliceProviderCompat(androidx.slice.SliceProvider!, androidx.slice.compat.CompatPermissionManager!, android.content.Context!);
-    method public static void addSpecs(android.os.Bundle!, java.util.Set<androidx.slice.SliceSpec!>!);
-    method public static androidx.slice.Slice! bindSlice(android.content.Context!, android.net.Uri!, java.util.Set<androidx.slice.SliceSpec!>!);
-    method public static androidx.slice.Slice! bindSlice(android.content.Context!, android.content.Intent!, java.util.Set<androidx.slice.SliceSpec!>!);
-    method public android.os.Bundle! call(String!, String!, android.os.Bundle!);
-    method public static int checkSlicePermission(android.content.Context!, String!, android.net.Uri!, int, int);
-    method public String! getCallingPackage();
-    method public static java.util.List<android.net.Uri!>! getPinnedSlices(android.content.Context!);
-    method public static java.util.Set<androidx.slice.SliceSpec!>! getPinnedSpecs(android.content.Context!, android.net.Uri!);
-    method public static java.util.Collection<android.net.Uri!> getSliceDescendants(android.content.Context!, android.net.Uri);
-    method public static java.util.Set<androidx.slice.SliceSpec!>! getSpecs(android.os.Bundle!);
-    method public static void grantSlicePermission(android.content.Context!, String!, String!, android.net.Uri!);
-    method public static android.net.Uri! mapIntentToUri(android.content.Context!, android.content.Intent!);
-    method public static void pinSlice(android.content.Context!, android.net.Uri!, java.util.Set<androidx.slice.SliceSpec!>!);
-    method public static void revokeSlicePermission(android.content.Context!, String!, String!, android.net.Uri!);
-    method public static void unpinSlice(android.content.Context!, android.net.Uri!, java.util.Set<androidx.slice.SliceSpec!>!);
+    ctor public SliceProviderCompat(androidx.slice.SliceProvider, androidx.slice.compat.CompatPermissionManager, android.content.Context);
+    method public static void addSpecs(android.os.Bundle, java.util.Set<androidx.slice.SliceSpec!>);
+    method public static androidx.slice.Slice? bindSlice(android.content.Context, android.net.Uri, java.util.Set<androidx.slice.SliceSpec!>);
+    method public static androidx.slice.Slice? bindSlice(android.content.Context, android.content.Intent, java.util.Set<androidx.slice.SliceSpec!>);
+    method public android.os.Bundle? call(String, String?, android.os.Bundle);
+    method public static int checkSlicePermission(android.content.Context, String?, android.net.Uri, int, int);
+    method public String? getCallingPackage();
+    method public static java.util.List<android.net.Uri!> getPinnedSlices(android.content.Context);
+    method public static java.util.Set<androidx.slice.SliceSpec!>? getPinnedSpecs(android.content.Context, android.net.Uri);
+    method public static java.util.Collection<android.net.Uri!> getSliceDescendants(android.content.Context, android.net.Uri);
+    method public static java.util.Set<androidx.slice.SliceSpec!> getSpecs(android.os.Bundle);
+    method public static void grantSlicePermission(android.content.Context, String?, String?, android.net.Uri);
+    method public static android.net.Uri? mapIntentToUri(android.content.Context, android.content.Intent);
+    method public static void pinSlice(android.content.Context, android.net.Uri, java.util.Set<androidx.slice.SliceSpec!>);
+    method public static void revokeSlicePermission(android.content.Context, String?, String?, android.net.Uri);
+    method public static void unpinSlice(android.content.Context, android.net.Uri, java.util.Set<androidx.slice.SliceSpec!>);
     field public static final String ARG_SUPPORTS_VERSIONED_PARCELABLE = "supports_versioned_parcelable";
     field public static final String EXTRA_BIND_URI = "slice_uri";
     field public static final String EXTRA_INTENT = "slice_intent";
diff --git a/slices/core/api/restricted_current.txt b/slices/core/api/restricted_current.txt
index c9d8659..3cf1dca 100644
--- a/slices/core/api/restricted_current.txt
+++ b/slices/core/api/restricted_current.txt
@@ -104,19 +104,19 @@
     method public final int bulkInsert(android.net.Uri, android.content.ContentValues![]);
     method @RequiresApi(19) public final android.net.Uri? canonicalize(android.net.Uri);
     method public final int delete(android.net.Uri, String?, String![]?);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @RequiresApi(19) public static androidx.slice.Clock! getClock();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @RequiresApi(19) public static java.util.Set<androidx.slice.SliceSpec!>! getCurrentSpecs();
+    method @RequiresApi(19) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public static androidx.slice.Clock? getClock();
+    method @RequiresApi(19) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static java.util.Set<androidx.slice.SliceSpec!>? getCurrentSpecs();
     method @RequiresApi(19) public java.util.List<android.net.Uri!> getPinnedSlices();
-    method public final String! getType(android.net.Uri!);
+    method public final String? getType(android.net.Uri);
     method public final android.net.Uri? insert(android.net.Uri, android.content.ContentValues?);
-    method @RequiresApi(19) public abstract androidx.slice.Slice! onBindSlice(android.net.Uri!);
+    method @RequiresApi(19) public abstract androidx.slice.Slice? onBindSlice(android.net.Uri);
     method public final boolean onCreate();
     method public android.app.PendingIntent? onCreatePermissionRequest(android.net.Uri, String);
     method @RequiresApi(19) public abstract boolean onCreateSliceProvider();
-    method @RequiresApi(19) public java.util.Collection<android.net.Uri!>! onGetSliceDescendants(android.net.Uri!);
-    method @RequiresApi(19) public android.net.Uri onMapIntentToUri(android.content.Intent!);
-    method @RequiresApi(19) public void onSlicePinned(android.net.Uri!);
-    method @RequiresApi(19) public void onSliceUnpinned(android.net.Uri!);
+    method @RequiresApi(19) public java.util.Collection<android.net.Uri!> onGetSliceDescendants(android.net.Uri);
+    method @RequiresApi(19) public android.net.Uri onMapIntentToUri(android.content.Intent);
+    method @RequiresApi(19) public void onSlicePinned(android.net.Uri);
+    method @RequiresApi(19) public void onSliceUnpinned(android.net.Uri);
     method public final android.database.Cursor? query(android.net.Uri, String![]?, String?, String![]?, String?);
     method @RequiresApi(28) public final android.database.Cursor? query(android.net.Uri, String![]?, android.os.Bundle?, android.os.CancellationSignal?);
     method @RequiresApi(16) public final android.database.Cursor? query(android.net.Uri, String![]?, String?, String![]?, String?, android.os.CancellationSignal?);
@@ -125,8 +125,8 @@
 
   public abstract class SliceProviderWithCallbacks<T extends androidx.slice.SliceProviderWithCallbacks> extends androidx.slice.SliceProvider implements androidx.remotecallback.CallbackBase<T> androidx.remotecallback.CallbackReceiver<T> {
     ctor public SliceProviderWithCallbacks();
-    method public T! createRemoteCallback(android.content.Context!);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.remotecallback.RemoteCallback! toRemoteCallback(Class<T!>!, android.content.Context!, String!, android.os.Bundle!, String!);
+    method public T createRemoteCallback(android.content.Context);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.remotecallback.RemoteCallback toRemoteCallback(Class<T!>, android.content.Context, String?, android.os.Bundle, String?);
   }
 
   @RequiresApi(19) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class SliceSpec implements androidx.versionedparcelable.VersionedParcelable {
@@ -163,22 +163,22 @@
 
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @RequiresApi(19) public class SliceProviderCompat {
-    ctor public SliceProviderCompat(androidx.slice.SliceProvider!, androidx.slice.compat.CompatPermissionManager!, android.content.Context!);
-    method public static void addSpecs(android.os.Bundle!, java.util.Set<androidx.slice.SliceSpec!>!);
-    method public static androidx.slice.Slice! bindSlice(android.content.Context!, android.net.Uri!, java.util.Set<androidx.slice.SliceSpec!>!);
-    method public static androidx.slice.Slice! bindSlice(android.content.Context!, android.content.Intent!, java.util.Set<androidx.slice.SliceSpec!>!);
-    method public android.os.Bundle! call(String!, String!, android.os.Bundle!);
-    method public static int checkSlicePermission(android.content.Context!, String!, android.net.Uri!, int, int);
-    method public String! getCallingPackage();
-    method public static java.util.List<android.net.Uri!>! getPinnedSlices(android.content.Context!);
-    method public static java.util.Set<androidx.slice.SliceSpec!>! getPinnedSpecs(android.content.Context!, android.net.Uri!);
-    method public static java.util.Collection<android.net.Uri!> getSliceDescendants(android.content.Context!, android.net.Uri);
-    method public static java.util.Set<androidx.slice.SliceSpec!>! getSpecs(android.os.Bundle!);
-    method public static void grantSlicePermission(android.content.Context!, String!, String!, android.net.Uri!);
-    method public static android.net.Uri! mapIntentToUri(android.content.Context!, android.content.Intent!);
-    method public static void pinSlice(android.content.Context!, android.net.Uri!, java.util.Set<androidx.slice.SliceSpec!>!);
-    method public static void revokeSlicePermission(android.content.Context!, String!, String!, android.net.Uri!);
-    method public static void unpinSlice(android.content.Context!, android.net.Uri!, java.util.Set<androidx.slice.SliceSpec!>!);
+    ctor public SliceProviderCompat(androidx.slice.SliceProvider, androidx.slice.compat.CompatPermissionManager, android.content.Context);
+    method public static void addSpecs(android.os.Bundle, java.util.Set<androidx.slice.SliceSpec!>);
+    method public static androidx.slice.Slice? bindSlice(android.content.Context, android.net.Uri, java.util.Set<androidx.slice.SliceSpec!>);
+    method public static androidx.slice.Slice? bindSlice(android.content.Context, android.content.Intent, java.util.Set<androidx.slice.SliceSpec!>);
+    method public android.os.Bundle? call(String, String?, android.os.Bundle);
+    method public static int checkSlicePermission(android.content.Context, String?, android.net.Uri, int, int);
+    method public String? getCallingPackage();
+    method public static java.util.List<android.net.Uri!> getPinnedSlices(android.content.Context);
+    method public static java.util.Set<androidx.slice.SliceSpec!>? getPinnedSpecs(android.content.Context, android.net.Uri);
+    method public static java.util.Collection<android.net.Uri!> getSliceDescendants(android.content.Context, android.net.Uri);
+    method public static java.util.Set<androidx.slice.SliceSpec!> getSpecs(android.os.Bundle);
+    method public static void grantSlicePermission(android.content.Context, String?, String?, android.net.Uri);
+    method public static android.net.Uri? mapIntentToUri(android.content.Context, android.content.Intent);
+    method public static void pinSlice(android.content.Context, android.net.Uri, java.util.Set<androidx.slice.SliceSpec!>);
+    method public static void revokeSlicePermission(android.content.Context, String?, String?, android.net.Uri);
+    method public static void unpinSlice(android.content.Context, android.net.Uri, java.util.Set<androidx.slice.SliceSpec!>);
     field public static final String ARG_SUPPORTS_VERSIONED_PARCELABLE = "supports_versioned_parcelable";
     field public static final String EXTRA_BIND_URI = "slice_uri";
     field public static final String EXTRA_INTENT = "slice_intent";
diff --git a/slices/core/src/androidTest/java/androidx/slice/SlicePermissionTest.java b/slices/core/src/androidTest/java/androidx/slice/SlicePermissionTest.java
index 6b97b64..b8b3ecf 100644
--- a/slices/core/src/androidTest/java/androidx/slice/SlicePermissionTest.java
+++ b/slices/core/src/androidTest/java/androidx/slice/SlicePermissionTest.java
@@ -27,6 +27,7 @@
 import android.net.Uri;
 import android.os.Process;
 
+import androidx.annotation.NonNull;
 import androidx.slice.compat.CompatPermissionManager;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -193,14 +194,15 @@
             return true;
         }
 
+        @NonNull
         protected CompatPermissionManager onCreatePermissionManager(
-                String[] autoGrantPermissions) {
+                @NonNull String[] autoGrantPermissions) {
             return new CompatPermissionManager(getContext(), PERMS_PREFIX + getClass().getName(),
                     -1 /* Different uid to run permissions */, autoGrantPermissions);
         }
 
         @Override
-        public Slice onBindSlice(Uri sliceUri) {
+        public Slice onBindSlice(@NonNull Uri sliceUri) {
             return null;
         }
     }
diff --git a/slices/core/src/androidTest/java/androidx/slice/SliceProviderCallbackTest.java b/slices/core/src/androidTest/java/androidx/slice/SliceProviderCallbackTest.java
index ce9fdad..b8a48e7 100644
--- a/slices/core/src/androidTest/java/androidx/slice/SliceProviderCallbackTest.java
+++ b/slices/core/src/androidTest/java/androidx/slice/SliceProviderCallbackTest.java
@@ -26,6 +26,7 @@
 import android.content.Intent;
 import android.net.Uri;
 
+import androidx.annotation.NonNull;
 import androidx.remotecallback.RemoteCallable;
 import androidx.remotecallback.RemoteCallback;
 import androidx.test.core.app.ApplicationProvider;
@@ -156,7 +157,7 @@
         }
 
         @Override
-        public Slice onBindSlice(Uri sliceUri) {
+        public Slice onBindSlice(@NonNull Uri sliceUri) {
             return null;
         }
     }
diff --git a/slices/core/src/androidTest/java/androidx/slice/SliceTestProvider.java b/slices/core/src/androidTest/java/androidx/slice/SliceTestProvider.java
index 53e2388..475ae31 100644
--- a/slices/core/src/androidTest/java/androidx/slice/SliceTestProvider.java
+++ b/slices/core/src/androidTest/java/androidx/slice/SliceTestProvider.java
@@ -46,7 +46,7 @@
     }
 
     @Override
-    public Slice onBindSlice(Uri sliceUri) {
+    public Slice onBindSlice(@NonNull Uri sliceUri) {
         switch (sliceUri.getPath()) {
             case "/set_flag":
                 SliceTest.sFlag = true;
diff --git a/slices/core/src/androidTest/java/androidx/slice/compat/SliceProviderCompatTest.java b/slices/core/src/androidTest/java/androidx/slice/compat/SliceProviderCompatTest.java
index d7384e7..5a21ab3f 100644
--- a/slices/core/src/androidTest/java/androidx/slice/compat/SliceProviderCompatTest.java
+++ b/slices/core/src/androidTest/java/androidx/slice/compat/SliceProviderCompatTest.java
@@ -35,6 +35,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 
+import androidx.annotation.NonNull;
 import androidx.slice.Slice;
 import androidx.slice.SliceProvider;
 import androidx.slice.SliceSpec;
@@ -131,7 +132,7 @@
         }
 
         @Override
-        public Slice onBindSlice(Uri sliceUri) {
+        public Slice onBindSlice(@NonNull Uri sliceUri) {
             return null;
         }
     }
diff --git a/slices/core/src/main/java/androidx/slice/SliceProvider.java b/slices/core/src/main/java/androidx/slice/SliceProvider.java
index 7c9bb73..a4b57aa 100644
--- a/slices/core/src/main/java/androidx/slice/SliceProvider.java
+++ b/slices/core/src/main/java/androidx/slice/SliceProvider.java
@@ -187,6 +187,7 @@
     /**
      * @hide
      */
+    @Nullable
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @Override
     @RequiresApi(19)
@@ -212,24 +213,27 @@
      * @hide
      * @param autoGrantPermissions
      */
+    @NonNull
     @VisibleForTesting
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @RequiresApi(19)
     protected CompatPermissionManager onCreatePermissionManager(
-            String[] autoGrantPermissions) {
+            @NonNull String[] autoGrantPermissions) {
         return new CompatPermissionManager(getContext(), PERMS_PREFIX + getClass().getName(),
                 Process.myUid(), autoGrantPermissions);
     }
 
+    @Nullable
     @Override
-    public final String getType(Uri uri) {
+    public final String getType(@NonNull Uri uri) {
         if (Build.VERSION.SDK_INT < 19) return null;
         if (DEBUG) Log.d(TAG, "getFormat " + uri);
         return SLICE_TYPE;
     }
 
+    @Nullable
     @Override
-    public Bundle call(String method, String arg, Bundle extras) {
+    public Bundle call(@NonNull String method, @Nullable String arg, @Nullable Bundle extras) {
         if (Build.VERSION.SDK_INT < 19) return null;
         return mCompat != null ? mCompat.call(method, arg, extras) : null;
     }
@@ -247,7 +251,8 @@
      * @param sliceUri the Uri of the slice attempting to be bound.
      * @param callingPackage the packageName of the app requesting the slice
      */
-    public @Nullable PendingIntent onCreatePermissionRequest(@NonNull Uri sliceUri,
+    @Nullable
+    public PendingIntent onCreatePermissionRequest(@NonNull Uri sliceUri,
             @NonNull String callingPackage) {
         return null;
     }
@@ -256,9 +261,11 @@
      * Generate a slice that contains a permission request.
      * @hide
      */
+    @NonNull
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @RequiresApi(19)
-    public Slice createPermissionSlice(Uri sliceUri, String callingPackage) {
+    public Slice createPermissionSlice(@NonNull Uri sliceUri,
+            @NonNull String callingPackage) {
         Context context = getContext();
         PendingIntent action = onCreatePermissionRequest(sliceUri, callingPackage);
         if (action == null) {
@@ -336,8 +343,9 @@
      * @see android.app.slice.Slice#HINT_PARTIAL
      */
     // TODO: Provide alternate notifyChange that takes in the slice (i.e. notifyChange(Uri, Slice)).
+    @Nullable
     @RequiresApi(19)
-    public abstract Slice onBindSlice(Uri sliceUri);
+    public abstract Slice onBindSlice(@NonNull Uri sliceUri);
 
     /**
      * Called to inform an app that a slice has been pinned.
@@ -358,7 +366,7 @@
      * @see #onSliceUnpinned(Uri)
      */
     @RequiresApi(19)
-    public void onSlicePinned(Uri sliceUri) {}
+    public void onSlicePinned(@NonNull Uri sliceUri) {}
 
     /**
      * Called to inform an app that a slices is no longer pinned.
@@ -369,14 +377,14 @@
      * @see #onSlicePinned(Uri)
      */
     @RequiresApi(19)
-    public void onSliceUnpinned(Uri sliceUri) {}
+    public void onSliceUnpinned(@NonNull Uri sliceUri) {}
 
     /**
      * @hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @RequiresApi(19)
-    public void handleSlicePinned(Uri sliceUri) {
+    public void handleSlicePinned(@NonNull Uri sliceUri) {
         List<Uri> pinnedSlices = getPinnedSlices();
         if (!pinnedSlices.contains(sliceUri)) {
             pinnedSlices.add(sliceUri);
@@ -388,7 +396,7 @@
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @RequiresApi(19)
-    public void handleSliceUnpinned(Uri sliceUri) {
+    public void handleSliceUnpinned(@NonNull Uri sliceUri) {
         List<Uri> pinnedSlices = getPinnedSlices();
         if (pinnedSlices.contains(sliceUri)) {
             pinnedSlices.remove(sliceUri);
@@ -403,8 +411,9 @@
      * @return Uri representing the slice associated with the provided intent.
      * @see android.app.slice.Slice
      */
+    @NonNull
     @RequiresApi(19)
-    public @NonNull Uri onMapIntentToUri(Intent intent) {
+    public Uri onMapIntentToUri(@NonNull Intent intent) {
         throw new UnsupportedOperationException(
                 "This provider has not implemented intent to uri mapping");
     }
@@ -419,8 +428,9 @@
      * @return All slices within the space.
      * @see androidx.slice.SliceViewManager#getSliceDescendants(Uri)
      */
+    @NonNull
     @RequiresApi(19)
-    public Collection<Uri> onGetSliceDescendants(Uri uri) {
+    public Collection<Uri> onGetSliceDescendants(@NonNull Uri uri) {
         return Collections.emptyList();
     }
 
@@ -429,8 +439,9 @@
      *
      * @return All pinned slices.
      */
+    @NonNull
     @RequiresApi(19)
-    @NonNull public List<Uri> getPinnedSlices() {
+    public List<Uri> getPinnedSlices() {
         synchronized (mPinnedSliceUrisLock) {
             if (mPinnedSliceUris == null) {
                 mPinnedSliceUris = new ArrayList<>(SliceManager.getInstance(getContext())
@@ -500,13 +511,14 @@
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @RequiresApi(19)
-    public static void setSpecs(Set<SliceSpec> specs) {
+    public static void setSpecs(@Nullable Set<SliceSpec> specs) {
         sSpecs = specs;
     }
 
     /**
      * @hide
      */
+    @Nullable
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
     @RequiresApi(19)
     public static Set<SliceSpec> getCurrentSpecs() {
@@ -518,13 +530,14 @@
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @RequiresApi(19)
-    public static void setClock(Clock clock) {
+    public static void setClock(@Nullable Clock clock) {
         sClock = clock;
     }
 
     /**
      * @hide
      */
+    @Nullable
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @RequiresApi(19)
     public static Clock getClock() {
diff --git a/slices/core/src/main/java/androidx/slice/SliceProviderWithCallbacks.java b/slices/core/src/main/java/androidx/slice/SliceProviderWithCallbacks.java
index c73a9ea..5404f79 100644
--- a/slices/core/src/main/java/androidx/slice/SliceProviderWithCallbacks.java
+++ b/slices/core/src/main/java/androidx/slice/SliceProviderWithCallbacks.java
@@ -27,6 +27,8 @@
 import android.content.pm.ProviderInfo;
 import android.os.Bundle;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.remotecallback.CallbackBase;
 import androidx.remotecallback.CallbackHandlerRegistry;
@@ -49,13 +51,14 @@
     String mAuthority;
 
     @Override
-    public void attachInfo(Context context, ProviderInfo info) {
+    public void attachInfo(@NonNull Context context, @NonNull ProviderInfo info) {
         super.attachInfo(context, info);
         mAuthority = info.authority;
     }
 
+    @Nullable
     @Override
-    public Bundle call(String method, String arg, Bundle extras) {
+    public Bundle call(@NonNull String method, @Nullable String arg, @Nullable Bundle extras) {
         if (ProviderRelayReceiver.METHOD_PROVIDER_CALLBACK.equals(method)) {
             CallbackHandlerRegistry.sInstance.invokeCallback(getContext(), this, extras);
             return null;
@@ -63,8 +66,9 @@
         return super.call(method, arg, extras);
     }
 
+    @NonNull
     @Override
-    public T createRemoteCallback(Context context) {
+    public T createRemoteCallback(@NonNull Context context) {
         return CallbackHandlerRegistry.sInstance.getAndResetStub(getClass(), context, mAuthority);
     }
 
@@ -73,10 +77,11 @@
      * disappear when we have support for androidx-level @RestrictTo.
      * @hide
      */
+    @NonNull
     @Override
     @RestrictTo(LIBRARY_GROUP_PREFIX)
-    public RemoteCallback toRemoteCallback(Class<T> cls, Context context, String authority,
-            Bundle args, String method) {
+    public RemoteCallback toRemoteCallback(@NonNull Class<T> cls, @NonNull Context context,
+            @Nullable String authority, @NonNull Bundle args, @Nullable String method) {
         if (authority == null) {
             throw new IllegalStateException(
                     "ContentProvider must be attached before creating callbacks");
diff --git a/slices/core/src/main/java/androidx/slice/compat/SliceProviderCompat.java b/slices/core/src/main/java/androidx/slice/compat/SliceProviderCompat.java
index 987b2ed..dde160c 100644
--- a/slices/core/src/main/java/androidx/slice/compat/SliceProviderCompat.java
+++ b/slices/core/src/main/java/androidx/slice/compat/SliceProviderCompat.java
@@ -43,6 +43,7 @@
 import android.util.Log;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
@@ -108,8 +109,8 @@
     private CompatPinnedList mPinnedList;
     private CompatPermissionManager mPermissionManager;
 
-    public SliceProviderCompat(SliceProvider provider, CompatPermissionManager permissionManager,
-            Context context) {
+    public SliceProviderCompat(@NonNull SliceProvider provider,
+            @NonNull CompatPermissionManager permissionManager, @NonNull Context context) {
         mProvider = provider;
         mContext = context;
         String prefsFile = DATA_PREFIX + getClass().getName();
@@ -131,6 +132,7 @@
         return mContext;
     }
 
+    @Nullable
     public String getCallingPackage() {
         return mProvider.getCallingPackage();
     }
@@ -138,7 +140,8 @@
     /**
      * Called by SliceProvider when compat is needed.
      */
-    public Bundle call(String method, String arg, Bundle extras) {
+    @Nullable
+    public Bundle call(@NonNull String method, @Nullable String arg, @NonNull Bundle extras) {
         if (method.equals(METHOD_SLICE)) {
             Uri uri = extras.getParcelable(EXTRA_BIND_URI);
             Set<SliceSpec> specs = getSpecs(extras);
@@ -309,8 +312,9 @@
     /**
      * Compat version of {@link Slice#bindSlice}.
      */
-    public static Slice bindSlice(Context context, Uri uri,
-            Set<SliceSpec> supportedSpecs) {
+    @Nullable
+    public static Slice bindSlice(@NonNull Context context, @NonNull Uri uri,
+            @NonNull Set<SliceSpec> supportedSpecs) {
         ProviderHolder holder = acquireClient(context.getContentResolver(), uri);
         if (holder.mProvider == null) {
             throw new IllegalArgumentException("Unknown URI " + uri);
@@ -333,7 +337,7 @@
     /**
      * Compat way to push specs through the call.
      */
-    public static void addSpecs(Bundle extras, Set<SliceSpec> supportedSpecs) {
+    public static void addSpecs(@NonNull Bundle extras, @NonNull Set<SliceSpec> supportedSpecs) {
         ArrayList<String> types = new ArrayList<>();
         ArrayList<Integer> revs = new ArrayList<>();
         for (SliceSpec spec : supportedSpecs) {
@@ -347,7 +351,8 @@
     /**
      * Compat way to push specs through the call.
      */
-    public static Set<SliceSpec> getSpecs(Bundle extras) {
+    @NonNull
+    public static Set<SliceSpec> getSpecs(@NonNull Bundle extras) {
         ArraySet<SliceSpec> specs = new ArraySet<>();
         ArrayList<String> types = extras.getStringArrayList(EXTRA_SUPPORTED_SPECS);
         ArrayList<Integer> revs = extras.getIntegerArrayList(EXTRA_SUPPORTED_SPECS_REVS);
@@ -362,8 +367,9 @@
     /**
      * Compat version of {@link Slice#bindSlice}.
      */
-    public static Slice bindSlice(Context context, Intent intent,
-            Set<SliceSpec> supportedSpecs) {
+    @Nullable
+    public static Slice bindSlice(@NonNull Context context, @NonNull Intent intent,
+            @NonNull Set<SliceSpec> supportedSpecs) {
         Preconditions.checkNotNull(intent, "intent");
         Preconditions.checkArgument(intent.getComponent() != null || intent.getPackage() != null
                         || intent.getData() != null,
@@ -453,8 +459,8 @@
     /**
      * Compat version of {@link android.app.slice.SliceManager#pinSlice}.
      */
-    public static void pinSlice(Context context, Uri uri,
-            Set<SliceSpec> supportedSpecs) {
+    public static void pinSlice(@NonNull Context context, @NonNull Uri uri,
+            @NonNull Set<SliceSpec> supportedSpecs) {
         ProviderHolder holder = acquireClient(context.getContentResolver(), uri);
         if (holder.mProvider == null) {
             throw new IllegalArgumentException("Unknown URI " + uri);
@@ -475,8 +481,8 @@
     /**
      * Compat version of {@link android.app.slice.SliceManager#unpinSlice}.
      */
-    public static void unpinSlice(Context context, Uri uri,
-            Set<SliceSpec> supportedSpecs) {
+    public static void unpinSlice(@NonNull Context context, @NonNull Uri uri,
+            @NonNull Set<SliceSpec> supportedSpecs) {
         if (getPinnedSlices(context).contains(uri)) {
             ProviderHolder holder = acquireClient(context.getContentResolver(), uri);
             if (holder.mProvider == null) {
@@ -499,7 +505,8 @@
     /**
      * Compat version of {@link android.app.slice.SliceManager#getPinnedSpecs(Uri)}.
      */
-    public static Set<SliceSpec> getPinnedSpecs(Context context, Uri uri) {
+    @Nullable
+    public static Set<SliceSpec> getPinnedSpecs(@NonNull Context context, @NonNull Uri uri) {
         ProviderHolder holder = acquireClient(context.getContentResolver(), uri);
         if (holder.mProvider == null) {
             throw new IllegalArgumentException("Unknown URI " + uri);
@@ -523,7 +530,8 @@
     /**
      * Compat version of {@link android.app.slice.SliceManager#mapIntentToUri}.
      */
-    public static Uri mapIntentToUri(Context context, Intent intent) {
+    @Nullable
+    public static Uri mapIntentToUri(@NonNull Context context, @NonNull Intent intent) {
         Preconditions.checkNotNull(intent, "intent");
         Preconditions.checkArgument(intent.getComponent() != null || intent.getPackage() != null
                         || intent.getData() != null,
@@ -577,7 +585,8 @@
     /**
      * Compat version of {@link android.app.slice.SliceManager#getSliceDescendants(Uri)}
      */
-    public static @NonNull Collection<Uri> getSliceDescendants(Context context, @NonNull Uri uri) {
+    @NonNull
+    public static Collection<Uri> getSliceDescendants(@NonNull Context context, @NonNull Uri uri) {
         ContentResolver resolver = context.getContentResolver();
         try (ProviderHolder holder = acquireClient(resolver, uri)) {
             Bundle extras = new Bundle();
@@ -596,8 +605,8 @@
     /**
      * Compat version of {@link android.app.slice.SliceManager#checkSlicePermission}.
      */
-    public static int checkSlicePermission(Context context, String packageName, Uri uri, int pid,
-            int uid) {
+    public static int checkSlicePermission(@NonNull Context context, @Nullable String packageName,
+            @NonNull Uri uri, int pid, int uid) {
         ContentResolver resolver = context.getContentResolver();
         try (ProviderHolder holder = acquireClient(resolver, uri)) {
             Bundle extras = new Bundle();
@@ -620,8 +629,8 @@
     /**
      * Compat version of {@link android.app.slice.SliceManager#grantSlicePermission}.
      */
-    public static void grantSlicePermission(Context context, String packageName, String toPackage,
-            Uri uri) {
+    public static void grantSlicePermission(@NonNull Context context, @Nullable String packageName,
+            @Nullable String toPackage, @NonNull Uri uri) {
         ContentResolver resolver = context.getContentResolver();
         try (ProviderHolder holder = acquireClient(resolver, uri)) {
             Bundle extras = new Bundle();
@@ -639,8 +648,8 @@
     /**
      * Compat version of {@link android.app.slice.SliceManager#revokeSlicePermission}.
      */
-    public static void revokeSlicePermission(Context context, String packageName, String toPackage,
-            Uri uri) {
+    public static void revokeSlicePermission(@NonNull Context context, @Nullable String packageName,
+            @Nullable String toPackage, @NonNull Uri uri) {
         ContentResolver resolver = context.getContentResolver();
         try (ProviderHolder holder = acquireClient(resolver, uri)) {
             Bundle extras = new Bundle();
@@ -658,7 +667,8 @@
     /**
      * Compat version of {@link android.app.slice.SliceManager#getPinnedSlices}.
      */
-    public static List<Uri> getPinnedSlices(Context context) {
+    @NonNull
+    public static List<Uri> getPinnedSlices(@NonNull Context context) {
         ArrayList<Uri> pinnedSlices = new ArrayList<>();
         SharedPreferences prefs = context.getSharedPreferences(ALL_FILES, 0);
         Set<String> prefSet = prefs.getStringSet(ALL_FILES, Collections.<String>emptySet());
diff --git a/slices/core/src/main/res/values-gl/strings.xml b/slices/core/src/main/res/values-gl/strings.xml
index ff9565e..617e5fc 100644
--- a/slices/core/src/main/res/values-gl/strings.xml
+++ b/slices/core/src/main/res/values-gl/strings.xml
@@ -17,11 +17,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="abc_slices_permission_request" msgid="3604847235923472451">"A aplicación <xliff:g id="APP_0">%1$s</xliff:g> quere mostrar partes de <xliff:g id="APP_2">%2$s</xliff:g>"</string>
-    <string name="abc_slice_permission_title" msgid="4175332421259324948">"Queres permitir que a aplicación <xliff:g id="APP_0">%1$s</xliff:g> mostre partes de <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
+    <string name="abc_slices_permission_request" msgid="3604847235923472451">"<xliff:g id="APP_0">%1$s</xliff:g> quere mostrar fragmentos de aplicación de <xliff:g id="APP_2">%2$s</xliff:g>"</string>
+    <string name="abc_slice_permission_title" msgid="4175332421259324948">"Queres permitir que <xliff:g id="APP_0">%1$s</xliff:g> mostre fragmentos de aplicación de <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
     <string name="abc_slice_permission_text_1" msgid="4525743640399572811">"- Pode ler información da aplicación <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="abc_slice_permission_text_2" msgid="7323565634860251794">"- Pode levar a cabo accións dentro da aplicación <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="abc_slice_permission_checkbox" msgid="5696872682700058611">"Permitir que a aplicación <xliff:g id="APP">%1$s</xliff:g> mostre partes de calquera aplicación"</string>
+    <string name="abc_slice_permission_checkbox" msgid="5696872682700058611">"Permitir que <xliff:g id="APP">%1$s</xliff:g> mostre fragmentos de calquera aplicación"</string>
     <string name="abc_slice_permission_allow" msgid="5024599872061409708">"Permitir"</string>
     <string name="abc_slice_permission_deny" msgid="3819478292430407705">"Denegar"</string>
 </resources>
diff --git a/slices/core/src/main/res/values-hi/strings.xml b/slices/core/src/main/res/values-hi/strings.xml
index a8e98b9..7a27498 100644
--- a/slices/core/src/main/res/values-hi/strings.xml
+++ b/slices/core/src/main/res/values-hi/strings.xml
@@ -21,7 +21,7 @@
     <string name="abc_slice_permission_title" msgid="4175332421259324948">"<xliff:g id="APP_0">%1$s</xliff:g> को <xliff:g id="APP_2">%2$s</xliff:g> के हिस्से (स्लाइस) दिखाने की मंज़ूरी दें?"</string>
     <string name="abc_slice_permission_text_1" msgid="4525743640399572811">"- यह <xliff:g id="APP">%1$s</xliff:g> से जानकारी पा सकता है"</string>
     <string name="abc_slice_permission_text_2" msgid="7323565634860251794">"- यह <xliff:g id="APP">%1$s</xliff:g> में कार्रवाई कर सकता है"</string>
-    <string name="abc_slice_permission_checkbox" msgid="5696872682700058611">"<xliff:g id="APP">%1$s</xliff:g> काे किसी भी एेप्लिकेशन के हिस्से (स्लाइस) दिखाने की मंज़ूरी दें"</string>
+    <string name="abc_slice_permission_checkbox" msgid="5696872682700058611">"<xliff:g id="APP">%1$s</xliff:g> काे किसी भी ऐप्लिकेशन के हिस्से (स्लाइस) दिखाने की मंज़ूरी दें"</string>
     <string name="abc_slice_permission_allow" msgid="5024599872061409708">"अनुमति दें"</string>
     <string name="abc_slice_permission_deny" msgid="3819478292430407705">"नामंज़ूर करें"</string>
 </resources>
diff --git a/slices/test/src/main/java/androidx/slice/test/SampleSliceProvider.java b/slices/test/src/main/java/androidx/slice/test/SampleSliceProvider.java
index 0a792dc..2ea78e3 100644
--- a/slices/test/src/main/java/androidx/slice/test/SampleSliceProvider.java
+++ b/slices/test/src/main/java/androidx/slice/test/SampleSliceProvider.java
@@ -129,12 +129,12 @@
 
     @NonNull
     @Override
-    public Uri onMapIntentToUri(Intent intent) {
+    public Uri onMapIntentToUri(@NonNull Intent intent) {
         return getUri("wifi", getContext());
     }
 
     @Override
-    public Slice onBindSlice(Uri sliceUri) {
+    public Slice onBindSlice(@NonNull Uri sliceUri) {
         String path = sliceUri.getPath();
         if (!path.equals("/loadlist")) {
             mListSummaries.clear();
diff --git a/slices/view/api/api_lint.ignore b/slices/view/api/api_lint.ignore
index 7e7ad54..404a3e7 100644
--- a/slices/view/api/api_lint.ignore
+++ b/slices/view/api/api_lint.ignore
@@ -7,3 +7,61 @@
     Context is distinct, so it must be the first argument (method `serializeSlice`)
 ContextFirst: androidx.slice.SliceUtils.SliceActionListener#onSliceAction(android.net.Uri, android.content.Context, android.content.Intent) parameter #1:
     Context is distinct, so it must be the first argument (method `onSliceAction`)
+
+
+MissingNullability: androidx.slice.SliceMetadata#from(android.content.Context, androidx.slice.Slice):
+    Missing nullability on method `from` return
+MissingNullability: androidx.slice.SliceMetadata#getToggles():
+    Missing nullability on method `getToggles` return
+MissingNullability: androidx.slice.SliceMetadata#sendToggleAction(androidx.slice.core.SliceAction, boolean) parameter #0:
+    Missing nullability on parameter `toggleAction` in method `sendToggleAction`
+MissingNullability: androidx.slice.SliceStructure#SliceStructure(androidx.slice.Slice) parameter #0:
+    Missing nullability on parameter `s` in method `SliceStructure`
+MissingNullability: androidx.slice.SliceStructure#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.slice.SliceUtils.SerializeOptions#setActionMode(int):
+    Missing nullability on method `setActionMode` return
+MissingNullability: androidx.slice.SliceUtils.SerializeOptions#setImageConversionFormat(android.graphics.Bitmap.CompressFormat, int):
+    Missing nullability on method `setImageConversionFormat` return
+MissingNullability: androidx.slice.SliceUtils.SerializeOptions#setImageConversionFormat(android.graphics.Bitmap.CompressFormat, int) parameter #0:
+    Missing nullability on parameter `format` in method `setImageConversionFormat`
+MissingNullability: androidx.slice.SliceUtils.SerializeOptions#setImageMode(int):
+    Missing nullability on method `setImageMode` return
+MissingNullability: androidx.slice.SliceUtils.SerializeOptions#setMaxImageHeight(int):
+    Missing nullability on method `setMaxImageHeight` return
+MissingNullability: androidx.slice.SliceUtils.SerializeOptions#setMaxImageWidth(int):
+    Missing nullability on method `setMaxImageWidth` return
+MissingNullability: androidx.slice.SliceUtils.SliceActionListener#onSliceAction(android.net.Uri, android.content.Context, android.content.Intent) parameter #0:
+    Missing nullability on parameter `actionUri` in method `onSliceAction`
+MissingNullability: androidx.slice.SliceUtils.SliceActionListener#onSliceAction(android.net.Uri, android.content.Context, android.content.Intent) parameter #1:
+    Missing nullability on parameter `context` in method `onSliceAction`
+MissingNullability: androidx.slice.SliceUtils.SliceActionListener#onSliceAction(android.net.Uri, android.content.Context, android.content.Intent) parameter #2:
+    Missing nullability on parameter `intent` in method `onSliceAction`
+MissingNullability: androidx.slice.widget.EventInfo#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.slice.widget.SliceLiveData#fromCachedSlice(android.content.Context, java.io.InputStream, androidx.slice.widget.SliceLiveData.OnErrorListener) parameter #2:
+    Missing nullability on parameter `listener` in method `fromCachedSlice`
+MissingNullability: androidx.slice.widget.SliceLiveData#fromStream(android.content.Context, java.io.InputStream, androidx.slice.widget.SliceLiveData.OnErrorListener) parameter #2:
+    Missing nullability on parameter `listener` in method `fromStream`
+MissingNullability: androidx.slice.widget.SliceView#SliceView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `SliceView`
+MissingNullability: androidx.slice.widget.SliceView#SliceView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `SliceView`
+MissingNullability: androidx.slice.widget.SliceView#SliceView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `SliceView`
+MissingNullability: androidx.slice.widget.SliceView#SliceView(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `SliceView`
+MissingNullability: androidx.slice.widget.SliceView#SliceView(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `SliceView`
+MissingNullability: androidx.slice.widget.SliceView#onClick(android.view.View) parameter #0:
+    Missing nullability on parameter `v` in method `onClick`
+MissingNullability: androidx.slice.widget.SliceView#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onInterceptTouchEvent`
+MissingNullability: androidx.slice.widget.SliceView#onTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onTouchEvent`
+MissingNullability: androidx.slice.widget.SliceView#onVisibilityChanged(android.view.View, int) parameter #0:
+    Missing nullability on parameter `changedView` in method `onVisibilityChanged`
+MissingNullability: androidx.slice.widget.SliceView#setOnClickListener(android.view.View.OnClickListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnClickListener`
+MissingNullability: androidx.slice.widget.SliceView#setOnLongClickListener(android.view.View.OnLongClickListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnLongClickListener`
diff --git a/slices/view/src/androidTest/java/androidx/slice/SliceViewManagerTest.java b/slices/view/src/androidTest/java/androidx/slice/SliceViewManagerTest.java
index 784796e..ca207d4 100644
--- a/slices/view/src/androidTest/java/androidx/slice/SliceViewManagerTest.java
+++ b/slices/view/src/androidTest/java/androidx/slice/SliceViewManagerTest.java
@@ -252,7 +252,7 @@
         }
 
         @Override
-        public Slice onBindSlice(Uri sliceUri) {
+        public Slice onBindSlice(@NonNull Uri sliceUri) {
             if (sSliceProviderReceiver != null) {
                 return sSliceProviderReceiver.onBindSlice(sliceUri);
             }
@@ -261,7 +261,7 @@
 
         @NonNull
         @Override
-        public Uri onMapIntentToUri(Intent intent) {
+        public Uri onMapIntentToUri(@NonNull Intent intent) {
             if (sSliceProviderReceiver != null) {
                 return sSliceProviderReceiver.onMapIntentToUri(intent);
             }
@@ -269,21 +269,22 @@
         }
 
         @Override
-        public void onSlicePinned(Uri sliceUri) {
+        public void onSlicePinned(@NonNull Uri sliceUri) {
             if (sSliceProviderReceiver != null) {
                 sSliceProviderReceiver.onSlicePinned(sliceUri);
             }
         }
 
         @Override
-        public void onSliceUnpinned(Uri sliceUri) {
+        public void onSliceUnpinned(@NonNull Uri sliceUri) {
             if (sSliceProviderReceiver != null) {
                 sSliceProviderReceiver.onSliceUnpinned(sliceUri);
             }
         }
 
+        @NonNull
         @Override
-        public Collection<Uri> onGetSliceDescendants(Uri uri) {
+        public Collection<Uri> onGetSliceDescendants(@NonNull Uri uri) {
             if (sSliceProviderReceiver != null) {
                 return sSliceProviderReceiver.onGetSliceDescendants(uri);
             }
diff --git a/slices/view/src/androidTest/java/androidx/slice/widget/SliceViewTest.java b/slices/view/src/androidTest/java/androidx/slice/widget/SliceViewTest.java
index bcd5c87..1d46209 100644
--- a/slices/view/src/androidTest/java/androidx/slice/widget/SliceViewTest.java
+++ b/slices/view/src/androidTest/java/androidx/slice/widget/SliceViewTest.java
@@ -450,13 +450,13 @@
         Slice s = lb.build();
 
         mSliceView.setSlice(s);
-        mSliceView.showTitleItems(true);
+        mSliceView.setShowTitleItems(true);
 
         RowContent row = (RowContent) mSliceView.mListContent.getRowItems().get(0);
         assertTrue(row.hasTitleItems());
         assertNotNull(row.getStartItem());
 
-        mSliceView.showTitleItems(false);
+        mSliceView.setShowTitleItems(false);
 
         assertFalse(row.hasTitleItems());
         assertNull(row.getStartItem());
@@ -473,7 +473,7 @@
         Slice s = lb.build();
 
         mSliceView.setSlice(s);
-        mSliceView.showHeaderDivider(true);
+        mSliceView.setShowHeaderDivider(true);
 
         assertFalse(mSliceView.mListContent.getHeader().hasBottomDivider());
     }
@@ -493,7 +493,7 @@
         Slice s = lb.build();
 
         mSliceView.setSlice(s);
-        mSliceView.showHeaderDivider(true);
+        mSliceView.setShowHeaderDivider(true);
 
         assertTrue(mSliceView.mListContent.getHeader().hasBottomDivider());
     }
@@ -525,7 +525,7 @@
         Slice s = lb.build();
 
         mSliceView.setSlice(s);
-        mSliceView.showActionDividers(true);
+        mSliceView.setShowActionDividers(true);
 
         RowContent row = (RowContent) mSliceView.mListContent.getRowItems().get(0);
         assertTrue(row.hasActionDivider());
diff --git a/slices/view/src/main/java/androidx/slice/widget/RowStyle.java b/slices/view/src/main/java/androidx/slice/widget/RowStyle.java
index 2f8e5e4..d6d6292 100644
--- a/slices/view/src/main/java/androidx/slice/widget/RowStyle.java
+++ b/slices/view/src/main/java/androidx/slice/widget/RowStyle.java
@@ -30,6 +30,9 @@
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 @RequiresApi(19)
 public class RowStyle {
+    public static final int UNBOUNDED = -1;
+
+    private int mTitleItemStartPadding;
     private int mTitleItemEndPadding;
     private int mContentStartPadding;
     private int mContentEndPadding;
@@ -42,27 +45,33 @@
     public RowStyle(Context context, int resId) {
         TypedArray a = context.getTheme().obtainStyledAttributes(resId, R.styleable.RowStyle);
         try {
+            mTitleItemStartPadding = (int) a.getDimension(
+                    R.styleable.RowStyle_titleItemStartPadding, UNBOUNDED);
             mTitleItemEndPadding = (int) a.getDimension(
-                    R.styleable.RowStyle_titleItemEndPadding, -1);
+                    R.styleable.RowStyle_titleItemEndPadding, UNBOUNDED);
             mContentStartPadding = (int) a.getDimension(
-                    R.styleable.RowStyle_contentStartPadding, -1);
+                    R.styleable.RowStyle_contentStartPadding, UNBOUNDED);
             mContentEndPadding = (int) a.getDimension(
-                    R.styleable.RowStyle_contentEndPadding, -1);
+                    R.styleable.RowStyle_contentEndPadding, UNBOUNDED);
             mEndItemStartPadding = (int) a.getDimension(
-                    R.styleable.RowStyle_endItemStartPadding, -1);
+                    R.styleable.RowStyle_endItemStartPadding, UNBOUNDED);
             mEndItemEndPadding = (int) a.getDimension(
-                    R.styleable.RowStyle_endItemEndPadding, -1);
+                    R.styleable.RowStyle_endItemEndPadding, UNBOUNDED);
             mBottomDividerStartPadding = (int) a.getDimension(
-                    R.styleable.RowStyle_bottomDividerStartPadding, -1);
+                    R.styleable.RowStyle_bottomDividerStartPadding, UNBOUNDED);
             mBottomDividerEndPadding = (int) a.getDimension(
-                    R.styleable.RowStyle_bottomDividerEndPadding, -1);
+                    R.styleable.RowStyle_bottomDividerEndPadding, UNBOUNDED);
             mActionDividerHeight = (int) a.getDimension(
-                    R.styleable.RowStyle_actionDividerHeight, -1);
+                    R.styleable.RowStyle_actionDividerHeight, UNBOUNDED);
         } finally {
             a.recycle();
         }
     }
 
+    public int getTitleItemStartPadding() {
+        return mTitleItemStartPadding;
+    }
+
     public int getTitleItemEndPadding() {
         return mTitleItemEndPadding;
     }
diff --git a/slices/view/src/main/java/androidx/slice/widget/RowView.java b/slices/view/src/main/java/androidx/slice/widget/RowView.java
index 105e7f6..56808ef 100644
--- a/slices/view/src/main/java/androidx/slice/widget/RowView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/RowView.java
@@ -209,7 +209,8 @@
         }
 
         final RowStyle rowStyle = mSliceStyle.getRowStyle();
-        setViewPaddingEnd(mStartContainer, rowStyle.getTitleItemEndPadding());
+        setViewSidePaddings(mStartContainer,
+                rowStyle.getTitleItemStartPadding(), rowStyle.getTitleItemEndPadding());
         setViewSidePaddings(mContent,
                 rowStyle.getContentStartPadding(), rowStyle.getContentEndPadding());
         setViewSidePaddings(mEndContainer,
@@ -219,25 +220,33 @@
         setViewHeight(mActionDivider, rowStyle.getActionDividerHeight());
     }
 
-    private void setViewPaddingEnd(View v, int end) {
-        if (v != null && end >= 0) {
-            v.setPaddingRelative(v.getPaddingStart(), v.getPaddingTop(), end, v.getPaddingBottom());
-        }
-    }
-
     private void setViewSidePaddings(View v, int start, int end) {
-        if (v != null && start >= 0 && end >= 0) {
-            v.setPaddingRelative(start, v.getPaddingTop(), end, v.getPaddingBottom());
+        final boolean isNoPaddingSet = start < 0 && end < 0;
+        if (v == null || isNoPaddingSet) {
+            return;
         }
+
+        v.setPaddingRelative(
+                start >= 0 ? start : v.getPaddingStart(),
+                v.getPaddingTop(),
+                end >= 0 ? end : v.getPaddingEnd(),
+                v.getPaddingBottom());
     }
 
     private void setViewSideMargins(View v, int start, int end) {
-        if (v != null && start >= 0 && end >= 0) {
-            final MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
-            params.setMarginStart(start);
-            params.setMarginEnd(end);
-            mBottomDivider.setLayoutParams(params);
+        final boolean isNoMarginSet = start < 0 && end < 0;
+        if (v == null || isNoMarginSet) {
+            return;
         }
+
+        final MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
+        if (start >= 0) {
+            params.setMarginStart(start);
+        }
+        if (end >= 0) {
+            params.setMarginEnd(end);
+        }
+        v.setLayoutParams(params);
     }
 
     private void setViewHeight(View v, int height) {
diff --git a/slices/view/src/main/res-public/values/public_attrs.xml b/slices/view/src/main/res-public/values/public_attrs.xml
index dd8e6b6..b1c4d63 100644
--- a/slices/view/src/main/res-public/values/public_attrs.xml
+++ b/slices/view/src/main/res-public/values/public_attrs.xml
@@ -33,6 +33,7 @@
     <public type="attr" name="gridBottomPadding" />
     <public type="attr" name="rowViewStyle" />
     <public type="attr" name="sliceViewStyle" />
+    <public type="attr" name="titleItemStartPadding" />
     <public type="attr" name="titleItemEndPadding" />
     <public type="attr" name="contentStartPadding" />
     <public type="attr" name="contentEndPadding" />
diff --git a/slices/view/src/main/res/values/attrs.xml b/slices/view/src/main/res/values/attrs.xml
index f6108fa..6000bf9 100644
--- a/slices/view/src/main/res/values/attrs.xml
+++ b/slices/view/src/main/res/values/attrs.xml
@@ -65,6 +65,8 @@
     <attr name="sliceViewStyle" format="reference" />
 
     <declare-styleable name="RowStyle">
+        <!-- Padding to the start edge of title items shown in the row. -->
+        <attr name="titleItemStartPadding" format="dimension" />
         <!-- Padding to the end edge of title items shown in the row. -->
         <attr name="titleItemEndPadding" format="dimension" />
 
diff --git a/slidingpanelayout/api/api_lint.ignore b/slidingpanelayout/api/api_lint.ignore
index 0c6e84a..0300f24 100644
--- a/slidingpanelayout/api/api_lint.ignore
+++ b/slidingpanelayout/api/api_lint.ignore
@@ -1,3 +1,45 @@
 // Baseline format: 1.0
 ListenerInterface: androidx.slidingpanelayout.widget.SlidingPaneLayout.SimplePanelSlideListener:
     Listeners should be an interface, or otherwise renamed Callback: SimplePanelSlideListener
+
+
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#canScroll(android.view.View, boolean, int, int, int) parameter #0:
+    Missing nullability on parameter `v` in method `canScroll`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#checkLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `checkLayoutParams`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `c` in method `draw`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#drawChild(android.graphics.Canvas, android.view.View, long) parameter #0:
+    Missing nullability on parameter `canvas` in method `drawChild`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#drawChild(android.graphics.Canvas, android.view.View, long) parameter #1:
+    Missing nullability on parameter `child` in method `drawChild`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#generateLayoutParams(android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#generateLayoutParams(android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#generateLayoutParams(android.view.ViewGroup.LayoutParams):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `generateLayoutParams`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onInterceptTouchEvent`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#onTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onTouchEvent`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#requestChildFocus(android.view.View, android.view.View) parameter #0:
+    Missing nullability on parameter `child` in method `requestChildFocus`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#requestChildFocus(android.view.View, android.view.View) parameter #1:
+    Missing nullability on parameter `focused` in method `requestChildFocus`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#setShadowDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `d` in method `setShadowDrawable`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout.SimplePanelSlideListener#onPanelClosed(android.view.View) parameter #0:
+    Missing nullability on parameter `panel` in method `onPanelClosed`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout.SimplePanelSlideListener#onPanelOpened(android.view.View) parameter #0:
+    Missing nullability on parameter `panel` in method `onPanelOpened`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout.SimplePanelSlideListener#onPanelSlide(android.view.View, float) parameter #0:
+    Missing nullability on parameter `panel` in method `onPanelSlide`
diff --git a/sqlite/sqlite-framework/api/2.1.0-alpha01.txt b/sqlite/sqlite-framework/api/2.1.0-alpha01.txt
index 9c05b84..a0f6163 100644
--- a/sqlite/sqlite-framework/api/2.1.0-alpha01.txt
+++ b/sqlite/sqlite-framework/api/2.1.0-alpha01.txt
@@ -3,7 +3,7 @@
 
   public final class FrameworkSQLiteOpenHelperFactory implements androidx.sqlite.db.SupportSQLiteOpenHelper.Factory {
     ctor public FrameworkSQLiteOpenHelperFactory();
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper! create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration!);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration);
   }
 
 }
diff --git a/sqlite/sqlite-framework/api/current.txt b/sqlite/sqlite-framework/api/current.txt
index 9c05b84..a0f6163 100644
--- a/sqlite/sqlite-framework/api/current.txt
+++ b/sqlite/sqlite-framework/api/current.txt
@@ -3,7 +3,7 @@
 
   public final class FrameworkSQLiteOpenHelperFactory implements androidx.sqlite.db.SupportSQLiteOpenHelper.Factory {
     ctor public FrameworkSQLiteOpenHelperFactory();
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper! create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration!);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration);
   }
 
 }
diff --git a/sqlite/sqlite-framework/api/restricted_2.1.0-alpha01.txt b/sqlite/sqlite-framework/api/restricted_2.1.0-alpha01.txt
index 9c05b84..a0f6163 100644
--- a/sqlite/sqlite-framework/api/restricted_2.1.0-alpha01.txt
+++ b/sqlite/sqlite-framework/api/restricted_2.1.0-alpha01.txt
@@ -3,7 +3,7 @@
 
   public final class FrameworkSQLiteOpenHelperFactory implements androidx.sqlite.db.SupportSQLiteOpenHelper.Factory {
     ctor public FrameworkSQLiteOpenHelperFactory();
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper! create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration!);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration);
   }
 
 }
diff --git a/sqlite/sqlite-framework/api/restricted_current.txt b/sqlite/sqlite-framework/api/restricted_current.txt
index 9c05b84..a0f6163 100644
--- a/sqlite/sqlite-framework/api/restricted_current.txt
+++ b/sqlite/sqlite-framework/api/restricted_current.txt
@@ -3,7 +3,7 @@
 
   public final class FrameworkSQLiteOpenHelperFactory implements androidx.sqlite.db.SupportSQLiteOpenHelper.Factory {
     ctor public FrameworkSQLiteOpenHelperFactory();
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper! create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration!);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration);
   }
 
 }
diff --git a/sqlite/sqlite-framework/lint-baseline.xml b/sqlite/sqlite-framework/lint-baseline.xml
index 6abcc27..95cca31 100644
--- a/sqlite/sqlite-framework/lint-baseline.xml
+++ b/sqlite/sqlite-framework/lint-baseline.xml
@@ -1,26 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 3.5.0-beta04" client="gradle" variant="debug" version="3.5.0-beta04">
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="    public SupportSQLiteOpenHelper create(SupportSQLiteOpenHelper.Configuration configuration) {"
-        errorLine2="           ~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/sqlite/db/framework/FrameworkSQLiteOpenHelperFactory.java"
-            line="28"
-            column="12"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="    public SupportSQLiteOpenHelper create(SupportSQLiteOpenHelper.Configuration configuration) {"
-        errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/sqlite/db/framework/FrameworkSQLiteOpenHelperFactory.java"
-            line="28"
-            column="43"/>
-    </issue>
+<issues format="5" by="lint 3.5.0-beta05" client="gradle" variant="all" version="3.5.0-beta05">
 
 </issues>
diff --git a/sqlite/sqlite-framework/src/main/java/androidx/sqlite/db/framework/FrameworkSQLiteOpenHelperFactory.java b/sqlite/sqlite-framework/src/main/java/androidx/sqlite/db/framework/FrameworkSQLiteOpenHelperFactory.java
index e65fabe2..d27abee 100644
--- a/sqlite/sqlite-framework/src/main/java/androidx/sqlite/db/framework/FrameworkSQLiteOpenHelperFactory.java
+++ b/sqlite/sqlite-framework/src/main/java/androidx/sqlite/db/framework/FrameworkSQLiteOpenHelperFactory.java
@@ -16,6 +16,7 @@
 
 package androidx.sqlite.db.framework;
 
+import androidx.annotation.NonNull;
 import androidx.sqlite.db.SupportSQLiteOpenHelper;
 
 /**
@@ -24,8 +25,10 @@
  */
 @SuppressWarnings("unused")
 public final class FrameworkSQLiteOpenHelperFactory implements SupportSQLiteOpenHelper.Factory {
+    @NonNull
     @Override
-    public SupportSQLiteOpenHelper create(SupportSQLiteOpenHelper.Configuration configuration) {
+    public SupportSQLiteOpenHelper create(
+            @NonNull SupportSQLiteOpenHelper.Configuration configuration) {
         return new FrameworkSQLiteOpenHelper(
                 configuration.context, configuration.name, configuration.callback);
     }
diff --git a/sqlite/sqlite/api/2.1.0-alpha01.txt b/sqlite/sqlite/api/2.1.0-alpha01.txt
index 99d1651..f4688a2f 100644
--- a/sqlite/sqlite/api/2.1.0-alpha01.txt
+++ b/sqlite/sqlite/api/2.1.0-alpha01.txt
@@ -53,7 +53,7 @@
 
   public interface SupportSQLiteOpenHelper extends java.io.Closeable {
     method public void close();
-    method public String! getDatabaseName();
+    method public String? getDatabaseName();
     method public androidx.sqlite.db.SupportSQLiteDatabase! getReadableDatabase();
     method public androidx.sqlite.db.SupportSQLiteDatabase! getWritableDatabase();
     method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public void setWriteAheadLoggingEnabled(boolean);
@@ -61,30 +61,30 @@
 
   public abstract static class SupportSQLiteOpenHelper.Callback {
     ctor public SupportSQLiteOpenHelper.Callback(int);
-    method public void onConfigure(androidx.sqlite.db.SupportSQLiteDatabase!);
-    method public void onCorruption(androidx.sqlite.db.SupportSQLiteDatabase!);
-    method public abstract void onCreate(androidx.sqlite.db.SupportSQLiteDatabase!);
-    method public void onDowngrade(androidx.sqlite.db.SupportSQLiteDatabase!, int, int);
-    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase!);
-    method public abstract void onUpgrade(androidx.sqlite.db.SupportSQLiteDatabase!, int, int);
+    method public void onConfigure(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onCorruption(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public abstract void onCreate(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onDowngrade(androidx.sqlite.db.SupportSQLiteDatabase, int, int);
+    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public abstract void onUpgrade(androidx.sqlite.db.SupportSQLiteDatabase, int, int);
     field public final int version;
   }
 
   public static class SupportSQLiteOpenHelper.Configuration {
-    method public static androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder! builder(android.content.Context!);
+    method public static androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder builder(android.content.Context);
     field public final androidx.sqlite.db.SupportSQLiteOpenHelper.Callback callback;
     field public final android.content.Context context;
     field public final String? name;
   }
 
   public static class SupportSQLiteOpenHelper.Configuration.Builder {
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration! build();
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder! callback(androidx.sqlite.db.SupportSQLiteOpenHelper.Callback);
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder! name(String?);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration build();
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder callback(androidx.sqlite.db.SupportSQLiteOpenHelper.Callback);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder name(String?);
   }
 
   public static interface SupportSQLiteOpenHelper.Factory {
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper! create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration!);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration);
   }
 
   public interface SupportSQLiteProgram extends java.io.Closeable {
diff --git a/sqlite/sqlite/api/api_lint.ignore b/sqlite/sqlite/api/api_lint.ignore
index 81bb000..633b461 100644
--- a/sqlite/sqlite/api/api_lint.ignore
+++ b/sqlite/sqlite/api/api_lint.ignore
@@ -17,3 +17,123 @@
     Acronyms should not be capitalized in class names: was `SupportSQLiteQueryBuilder`, should this be `SupportSqLiteQueryBuilder`?
 AcronymName: androidx.sqlite.db.SupportSQLiteStatement:
     Acronyms should not be capitalized in class names: was `SupportSQLiteStatement`, should this be `SupportSqLiteStatement`?
+
+
+MissingNullability: androidx.sqlite.db.SimpleSQLiteQuery#SimpleSQLiteQuery(String) parameter #0:
+    Missing nullability on parameter `query` in method `SimpleSQLiteQuery`
+MissingNullability: androidx.sqlite.db.SimpleSQLiteQuery#SimpleSQLiteQuery(String, Object[]) parameter #0:
+    Missing nullability on parameter `query` in method `SimpleSQLiteQuery`
+MissingNullability: androidx.sqlite.db.SimpleSQLiteQuery#bind(androidx.sqlite.db.SupportSQLiteProgram, Object[]) parameter #0:
+    Missing nullability on parameter `statement` in method `bind`
+MissingNullability: androidx.sqlite.db.SimpleSQLiteQuery#bind(androidx.sqlite.db.SupportSQLiteProgram, Object[]) parameter #1:
+    Missing nullability on parameter `bindArgs` in method `bind`
+MissingNullability: androidx.sqlite.db.SimpleSQLiteQuery#bindTo(androidx.sqlite.db.SupportSQLiteProgram) parameter #0:
+    Missing nullability on parameter `statement` in method `bindTo`
+MissingNullability: androidx.sqlite.db.SimpleSQLiteQuery#getSql():
+    Missing nullability on method `getSql` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#beginTransactionWithListener(android.database.sqlite.SQLiteTransactionListener) parameter #0:
+    Missing nullability on parameter `transactionListener` in method `beginTransactionWithListener`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#beginTransactionWithListenerNonExclusive(android.database.sqlite.SQLiteTransactionListener) parameter #0:
+    Missing nullability on parameter `transactionListener` in method `beginTransactionWithListenerNonExclusive`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#compileStatement(String):
+    Missing nullability on method `compileStatement` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#compileStatement(String) parameter #0:
+    Missing nullability on parameter `sql` in method `compileStatement`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#delete(String, String, Object[]) parameter #0:
+    Missing nullability on parameter `table` in method `delete`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#delete(String, String, Object[]) parameter #1:
+    Missing nullability on parameter `whereClause` in method `delete`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#delete(String, String, Object[]) parameter #2:
+    Missing nullability on parameter `whereArgs` in method `delete`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#execSQL(String) parameter #0:
+    Missing nullability on parameter `sql` in method `execSQL`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#execSQL(String, Object[]) parameter #0:
+    Missing nullability on parameter `sql` in method `execSQL`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#execSQL(String, Object[]) parameter #1:
+    Missing nullability on parameter `bindArgs` in method `execSQL`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#getAttachedDbs():
+    Missing nullability on method `getAttachedDbs` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#getPath():
+    Missing nullability on method `getPath` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#insert(String, int, android.content.ContentValues) parameter #0:
+    Missing nullability on parameter `table` in method `insert`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#insert(String, int, android.content.ContentValues) parameter #2:
+    Missing nullability on parameter `values` in method `insert`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#query(String):
+    Missing nullability on method `query` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#query(String) parameter #0:
+    Missing nullability on parameter `query` in method `query`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#query(String, Object[]):
+    Missing nullability on method `query` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#query(String, Object[]) parameter #0:
+    Missing nullability on parameter `query` in method `query`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#query(String, Object[]) parameter #1:
+    Missing nullability on parameter `bindArgs` in method `query`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#query(androidx.sqlite.db.SupportSQLiteQuery):
+    Missing nullability on method `query` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#query(androidx.sqlite.db.SupportSQLiteQuery) parameter #0:
+    Missing nullability on parameter `query` in method `query`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#query(androidx.sqlite.db.SupportSQLiteQuery, android.os.CancellationSignal):
+    Missing nullability on method `query` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#query(androidx.sqlite.db.SupportSQLiteQuery, android.os.CancellationSignal) parameter #0:
+    Missing nullability on parameter `query` in method `query`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#query(androidx.sqlite.db.SupportSQLiteQuery, android.os.CancellationSignal) parameter #1:
+    Missing nullability on parameter `cancellationSignal` in method `query`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#setLocale(java.util.Locale) parameter #0:
+    Missing nullability on parameter `locale` in method `setLocale`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#update(String, int, android.content.ContentValues, String, Object[]) parameter #0:
+    Missing nullability on parameter `table` in method `update`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#update(String, int, android.content.ContentValues, String, Object[]) parameter #2:
+    Missing nullability on parameter `values` in method `update`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#update(String, int, android.content.ContentValues, String, Object[]) parameter #3:
+    Missing nullability on parameter `whereClause` in method `update`
+MissingNullability: androidx.sqlite.db.SupportSQLiteDatabase#update(String, int, android.content.ContentValues, String, Object[]) parameter #4:
+    Missing nullability on parameter `whereArgs` in method `update`
+MissingNullability: androidx.sqlite.db.SupportSQLiteOpenHelper#getReadableDatabase():
+    Missing nullability on method `getReadableDatabase` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteOpenHelper#getWritableDatabase():
+    Missing nullability on method `getWritableDatabase` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteProgram#bindBlob(int, byte[]) parameter #1:
+    Missing nullability on parameter `value` in method `bindBlob`
+MissingNullability: androidx.sqlite.db.SupportSQLiteProgram#bindString(int, String) parameter #1:
+    Missing nullability on parameter `value` in method `bindString`
+MissingNullability: androidx.sqlite.db.SupportSQLiteQuery#bindTo(androidx.sqlite.db.SupportSQLiteProgram) parameter #0:
+    Missing nullability on parameter `statement` in method `bindTo`
+MissingNullability: androidx.sqlite.db.SupportSQLiteQuery#getSql():
+    Missing nullability on method `getSql` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#builder(String):
+    Missing nullability on method `builder` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#builder(String) parameter #0:
+    Missing nullability on parameter `tableName` in method `builder`
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#columns(String[]):
+    Missing nullability on method `columns` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#columns(String[]) parameter #0:
+    Missing nullability on parameter `columns` in method `columns`
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#create():
+    Missing nullability on method `create` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#distinct():
+    Missing nullability on method `distinct` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#groupBy(String):
+    Missing nullability on method `groupBy` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#groupBy(String) parameter #0:
+    Missing nullability on parameter `groupBy` in method `groupBy`
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#having(String):
+    Missing nullability on method `having` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#having(String) parameter #0:
+    Missing nullability on parameter `having` in method `having`
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#limit(String):
+    Missing nullability on method `limit` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#limit(String) parameter #0:
+    Missing nullability on parameter `limit` in method `limit`
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#orderBy(String):
+    Missing nullability on method `orderBy` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#orderBy(String) parameter #0:
+    Missing nullability on parameter `orderBy` in method `orderBy`
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#selection(String, Object[]):
+    Missing nullability on method `selection` return
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#selection(String, Object[]) parameter #0:
+    Missing nullability on parameter `selection` in method `selection`
+MissingNullability: androidx.sqlite.db.SupportSQLiteQueryBuilder#selection(String, Object[]) parameter #1:
+    Missing nullability on parameter `bindArgs` in method `selection`
+MissingNullability: androidx.sqlite.db.SupportSQLiteStatement#simpleQueryForString():
+    Missing nullability on method `simpleQueryForString` return
diff --git a/sqlite/sqlite/api/current.txt b/sqlite/sqlite/api/current.txt
index 99d1651..f4688a2f 100644
--- a/sqlite/sqlite/api/current.txt
+++ b/sqlite/sqlite/api/current.txt
@@ -53,7 +53,7 @@
 
   public interface SupportSQLiteOpenHelper extends java.io.Closeable {
     method public void close();
-    method public String! getDatabaseName();
+    method public String? getDatabaseName();
     method public androidx.sqlite.db.SupportSQLiteDatabase! getReadableDatabase();
     method public androidx.sqlite.db.SupportSQLiteDatabase! getWritableDatabase();
     method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public void setWriteAheadLoggingEnabled(boolean);
@@ -61,30 +61,30 @@
 
   public abstract static class SupportSQLiteOpenHelper.Callback {
     ctor public SupportSQLiteOpenHelper.Callback(int);
-    method public void onConfigure(androidx.sqlite.db.SupportSQLiteDatabase!);
-    method public void onCorruption(androidx.sqlite.db.SupportSQLiteDatabase!);
-    method public abstract void onCreate(androidx.sqlite.db.SupportSQLiteDatabase!);
-    method public void onDowngrade(androidx.sqlite.db.SupportSQLiteDatabase!, int, int);
-    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase!);
-    method public abstract void onUpgrade(androidx.sqlite.db.SupportSQLiteDatabase!, int, int);
+    method public void onConfigure(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onCorruption(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public abstract void onCreate(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onDowngrade(androidx.sqlite.db.SupportSQLiteDatabase, int, int);
+    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public abstract void onUpgrade(androidx.sqlite.db.SupportSQLiteDatabase, int, int);
     field public final int version;
   }
 
   public static class SupportSQLiteOpenHelper.Configuration {
-    method public static androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder! builder(android.content.Context!);
+    method public static androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder builder(android.content.Context);
     field public final androidx.sqlite.db.SupportSQLiteOpenHelper.Callback callback;
     field public final android.content.Context context;
     field public final String? name;
   }
 
   public static class SupportSQLiteOpenHelper.Configuration.Builder {
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration! build();
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder! callback(androidx.sqlite.db.SupportSQLiteOpenHelper.Callback);
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder! name(String?);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration build();
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder callback(androidx.sqlite.db.SupportSQLiteOpenHelper.Callback);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder name(String?);
   }
 
   public static interface SupportSQLiteOpenHelper.Factory {
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper! create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration!);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration);
   }
 
   public interface SupportSQLiteProgram extends java.io.Closeable {
diff --git a/sqlite/sqlite/api/restricted_2.1.0-alpha01.txt b/sqlite/sqlite/api/restricted_2.1.0-alpha01.txt
index 99d1651..f4688a2f 100644
--- a/sqlite/sqlite/api/restricted_2.1.0-alpha01.txt
+++ b/sqlite/sqlite/api/restricted_2.1.0-alpha01.txt
@@ -53,7 +53,7 @@
 
   public interface SupportSQLiteOpenHelper extends java.io.Closeable {
     method public void close();
-    method public String! getDatabaseName();
+    method public String? getDatabaseName();
     method public androidx.sqlite.db.SupportSQLiteDatabase! getReadableDatabase();
     method public androidx.sqlite.db.SupportSQLiteDatabase! getWritableDatabase();
     method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public void setWriteAheadLoggingEnabled(boolean);
@@ -61,30 +61,30 @@
 
   public abstract static class SupportSQLiteOpenHelper.Callback {
     ctor public SupportSQLiteOpenHelper.Callback(int);
-    method public void onConfigure(androidx.sqlite.db.SupportSQLiteDatabase!);
-    method public void onCorruption(androidx.sqlite.db.SupportSQLiteDatabase!);
-    method public abstract void onCreate(androidx.sqlite.db.SupportSQLiteDatabase!);
-    method public void onDowngrade(androidx.sqlite.db.SupportSQLiteDatabase!, int, int);
-    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase!);
-    method public abstract void onUpgrade(androidx.sqlite.db.SupportSQLiteDatabase!, int, int);
+    method public void onConfigure(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onCorruption(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public abstract void onCreate(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onDowngrade(androidx.sqlite.db.SupportSQLiteDatabase, int, int);
+    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public abstract void onUpgrade(androidx.sqlite.db.SupportSQLiteDatabase, int, int);
     field public final int version;
   }
 
   public static class SupportSQLiteOpenHelper.Configuration {
-    method public static androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder! builder(android.content.Context!);
+    method public static androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder builder(android.content.Context);
     field public final androidx.sqlite.db.SupportSQLiteOpenHelper.Callback callback;
     field public final android.content.Context context;
     field public final String? name;
   }
 
   public static class SupportSQLiteOpenHelper.Configuration.Builder {
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration! build();
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder! callback(androidx.sqlite.db.SupportSQLiteOpenHelper.Callback);
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder! name(String?);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration build();
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder callback(androidx.sqlite.db.SupportSQLiteOpenHelper.Callback);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder name(String?);
   }
 
   public static interface SupportSQLiteOpenHelper.Factory {
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper! create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration!);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration);
   }
 
   public interface SupportSQLiteProgram extends java.io.Closeable {
diff --git a/sqlite/sqlite/api/restricted_current.txt b/sqlite/sqlite/api/restricted_current.txt
index 99d1651..f4688a2f 100644
--- a/sqlite/sqlite/api/restricted_current.txt
+++ b/sqlite/sqlite/api/restricted_current.txt
@@ -53,7 +53,7 @@
 
   public interface SupportSQLiteOpenHelper extends java.io.Closeable {
     method public void close();
-    method public String! getDatabaseName();
+    method public String? getDatabaseName();
     method public androidx.sqlite.db.SupportSQLiteDatabase! getReadableDatabase();
     method public androidx.sqlite.db.SupportSQLiteDatabase! getWritableDatabase();
     method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public void setWriteAheadLoggingEnabled(boolean);
@@ -61,30 +61,30 @@
 
   public abstract static class SupportSQLiteOpenHelper.Callback {
     ctor public SupportSQLiteOpenHelper.Callback(int);
-    method public void onConfigure(androidx.sqlite.db.SupportSQLiteDatabase!);
-    method public void onCorruption(androidx.sqlite.db.SupportSQLiteDatabase!);
-    method public abstract void onCreate(androidx.sqlite.db.SupportSQLiteDatabase!);
-    method public void onDowngrade(androidx.sqlite.db.SupportSQLiteDatabase!, int, int);
-    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase!);
-    method public abstract void onUpgrade(androidx.sqlite.db.SupportSQLiteDatabase!, int, int);
+    method public void onConfigure(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onCorruption(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public abstract void onCreate(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onDowngrade(androidx.sqlite.db.SupportSQLiteDatabase, int, int);
+    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public abstract void onUpgrade(androidx.sqlite.db.SupportSQLiteDatabase, int, int);
     field public final int version;
   }
 
   public static class SupportSQLiteOpenHelper.Configuration {
-    method public static androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder! builder(android.content.Context!);
+    method public static androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder builder(android.content.Context);
     field public final androidx.sqlite.db.SupportSQLiteOpenHelper.Callback callback;
     field public final android.content.Context context;
     field public final String? name;
   }
 
   public static class SupportSQLiteOpenHelper.Configuration.Builder {
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration! build();
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder! callback(androidx.sqlite.db.SupportSQLiteOpenHelper.Callback);
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder! name(String?);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration build();
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder callback(androidx.sqlite.db.SupportSQLiteOpenHelper.Callback);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder name(String?);
   }
 
   public static interface SupportSQLiteOpenHelper.Factory {
-    method public androidx.sqlite.db.SupportSQLiteOpenHelper! create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration!);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration);
   }
 
   public interface SupportSQLiteProgram extends java.io.Closeable {
diff --git a/sqlite/sqlite/lint-baseline.xml b/sqlite/sqlite/lint-baseline.xml
index aba96a0..06b60f6 100644
--- a/sqlite/sqlite/lint-baseline.xml
+++ b/sqlite/sqlite/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 3.5.0-beta04" client="gradle" variant="debug" version="3.5.0-beta04">
+<issues format="5" by="lint 3.5.0-beta05" client="gradle" variant="all" version="3.5.0-beta05">
 
     <issue
         id="UnknownNullness"
@@ -389,22 +389,11 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="    String getDatabaseName();"
-        errorLine2="    ~~~~~~">
-        <location
-            file="src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java"
-            line="46"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
         errorLine1="    SupportSQLiteDatabase getWritableDatabase();"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java"
-            line="80"
+            line="82"
             column="5"/>
     </issue>
 
@@ -415,156 +404,13 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java"
-            line="100"
+            line="102"
             column="5"/>
     </issue>
 
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="        public void onConfigure(SupportSQLiteDatabase db) {"
-        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java"
-            line="149"
-            column="33"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="        public abstract void onCreate(SupportSQLiteDatabase db);"
-        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java"
-            line="159"
-            column="39"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="        public abstract void onUpgrade(SupportSQLiteDatabase db, int oldVersion, int newVersion);"
-        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java"
-            line="181"
-            column="40"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="        public void onDowngrade(SupportSQLiteDatabase db, int oldVersion, int newVersion) {"
-        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java"
-            line="200"
-            column="33"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="        public void onOpen(SupportSQLiteDatabase db) {"
-        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java"
-            line="218"
-            column="28"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="        public void onCorruption(SupportSQLiteDatabase db) {"
-        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java"
-            line="229"
-            column="34"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="        public static Builder builder(Context context) {"
-        errorLine2="                      ~~~~~~~">
-        <location
-            file="src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java"
-            line="330"
-            column="23"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="        public static Builder builder(Context context) {"
-        errorLine2="                                      ~~~~~~~">
-        <location
-            file="src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java"
-            line="330"
-            column="39"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="            public Configuration build() {"
-        errorLine2="                   ~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java"
-            line="342"
-            column="20"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="            public Builder name(@Nullable String name) {"
-        errorLine2="                   ~~~~~~~">
-        <location
-            file="src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java"
-            line="362"
-            column="20"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="            public Builder callback(@NonNull Callback callback) {"
-        errorLine2="                   ~~~~~~~">
-        <location
-            file="src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java"
-            line="371"
-            column="20"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="        SupportSQLiteOpenHelper create(Configuration configuration);"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java"
-            line="390"
-            column="9"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
-        errorLine1="        SupportSQLiteOpenHelper create(Configuration configuration);"
-        errorLine2="                                       ~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java"
-            line="390"
-            column="40"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
         errorLine1="    void bindString(int index, String value);"
         errorLine2="                               ~~~~~~">
         <location
diff --git a/sqlite/sqlite/src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java b/sqlite/sqlite/src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java
index 014af07..8c0b7f6 100644
--- a/sqlite/sqlite/src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java
+++ b/sqlite/sqlite/src/main/java/androidx/sqlite/db/SupportSQLiteOpenHelper.java
@@ -42,8 +42,9 @@
 public interface SupportSQLiteOpenHelper extends Closeable {
     /**
      * Return the name of the SQLite database being opened, as given to
-     * the constructor.
+     * the constructor. {@code null} indicates an in-memory database.
      */
+    @Nullable
     String getDatabaseName();
 
     /**
@@ -147,7 +148,7 @@
          *
          * @param db The database.
          */
-        public void onConfigure(SupportSQLiteDatabase db) {
+        public void onConfigure(@NonNull SupportSQLiteDatabase db) {
 
         }
 
@@ -157,7 +158,7 @@
          *
          * @param db The database.
          */
-        public abstract void onCreate(SupportSQLiteDatabase db);
+        public abstract void onCreate(@NonNull SupportSQLiteDatabase db);
 
         /**
          * Called when the database needs to be upgraded. The implementation
@@ -179,7 +180,8 @@
          * @param oldVersion The old database version.
          * @param newVersion The new database version.
          */
-        public abstract void onUpgrade(SupportSQLiteDatabase db, int oldVersion, int newVersion);
+        public abstract void onUpgrade(@NonNull SupportSQLiteDatabase db, int oldVersion,
+                int newVersion);
 
         /**
          * Called when the database needs to be downgraded. This is strictly similar to
@@ -198,7 +200,7 @@
          * @param oldVersion The old database version.
          * @param newVersion The new database version.
          */
-        public void onDowngrade(SupportSQLiteDatabase db, int oldVersion, int newVersion) {
+        public void onDowngrade(@NonNull SupportSQLiteDatabase db, int oldVersion, int newVersion) {
             throw new SQLiteException("Can't downgrade database from version "
                     + oldVersion + " to " + newVersion);
         }
@@ -216,7 +218,7 @@
          *
          * @param db The database.
          */
-        public void onOpen(SupportSQLiteDatabase db) {
+        public void onOpen(@NonNull SupportSQLiteDatabase db) {
 
         }
 
@@ -227,7 +229,7 @@
          * @param db the {@link SupportSQLiteDatabase} object representing the database on which
          *           corruption is detected.
          */
-        public void onCorruption(SupportSQLiteDatabase db) {
+        public void onCorruption(@NonNull SupportSQLiteDatabase db) {
             // the following implementation is taken from {@link DefaultDatabaseErrorHandler}.
 
             Log.e(TAG, "Corruption reported by sqlite on database: " + db.getPath());
@@ -299,7 +301,6 @@
     /**
      * The configuration to create an SQLite open helper object using {@link Factory}.
      */
-    @SuppressWarnings("WeakerAccess")
     class Configuration {
         /**
          * Context to use to open or create the database.
@@ -328,7 +329,8 @@
          *
          * @param context to use to open or create the database.
          */
-        public static Builder builder(Context context) {
+        @NonNull
+        public static Builder builder(@NonNull Context context) {
             return new Builder(context);
         }
 
@@ -340,6 +342,7 @@
             String mName;
             SupportSQLiteOpenHelper.Callback mCallback;
 
+            @NonNull
             public Configuration build() {
                 if (mCallback == null) {
                     throw new IllegalArgumentException("Must set a callback to create the"
@@ -360,6 +363,7 @@
              * @param name Name of the database file, or null for an in-memory database.
              * @return This
              */
+            @NonNull
             public Builder name(@Nullable String name) {
                 mName = name;
                 return this;
@@ -369,6 +373,7 @@
              * @param callback The callback class to handle creation, upgrade and downgrade.
              * @return this
              */
+            @NonNull
             public Builder callback(@NonNull Callback callback) {
                 mCallback = callback;
                 return this;
@@ -388,6 +393,7 @@
          *
          * @return A SupportSQLiteOpenHelper which can be used to open a database.
          */
-        SupportSQLiteOpenHelper create(Configuration configuration);
+        @NonNull
+        SupportSQLiteOpenHelper create(@NonNull Configuration configuration);
     }
 }
diff --git a/swiperefreshlayout/api/api_lint.ignore b/swiperefreshlayout/api/api_lint.ignore
new file mode 100644
index 0000000..7147b31
--- /dev/null
+++ b/swiperefreshlayout/api/api_lint.ignore
@@ -0,0 +1,67 @@
+// Baseline format: 1.0
+MissingNullability: androidx.swiperefreshlayout.widget.CircularProgressDrawable#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
+MissingNullability: androidx.swiperefreshlayout.widget.CircularProgressDrawable#setColorFilter(android.graphics.ColorFilter) parameter #0:
+    Missing nullability on parameter `colorFilter` in method `setColorFilter`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#dispatchNestedPreScroll(int, int, int[], int[]) parameter #2:
+    Missing nullability on parameter `consumed` in method `dispatchNestedPreScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#dispatchNestedPreScroll(int, int, int[], int[]) parameter #3:
+    Missing nullability on parameter `offsetInWindow` in method `dispatchNestedPreScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#dispatchNestedPreScroll(int, int, int[], int[], int) parameter #2:
+    Missing nullability on parameter `consumed` in method `dispatchNestedPreScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#dispatchNestedPreScroll(int, int, int[], int[], int) parameter #3:
+    Missing nullability on parameter `offsetInWindow` in method `dispatchNestedPreScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#dispatchNestedScroll(int, int, int, int, int[]) parameter #4:
+    Missing nullability on parameter `offsetInWindow` in method `dispatchNestedScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#dispatchNestedScroll(int, int, int, int, int[], int) parameter #4:
+    Missing nullability on parameter `offsetInWindow` in method `dispatchNestedScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onInterceptTouchEvent`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onNestedFling(android.view.View, float, float, boolean) parameter #0:
+    Missing nullability on parameter `target` in method `onNestedFling`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onNestedPreFling(android.view.View, float, float) parameter #0:
+    Missing nullability on parameter `target` in method `onNestedPreFling`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onNestedPreScroll(android.view.View, int, int, int[]) parameter #0:
+    Missing nullability on parameter `target` in method `onNestedPreScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onNestedPreScroll(android.view.View, int, int, int[]) parameter #3:
+    Missing nullability on parameter `consumed` in method `onNestedPreScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onNestedPreScroll(android.view.View, int, int, int[], int) parameter #0:
+    Missing nullability on parameter `target` in method `onNestedPreScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onNestedPreScroll(android.view.View, int, int, int[], int) parameter #3:
+    Missing nullability on parameter `consumed` in method `onNestedPreScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onNestedScroll(android.view.View, int, int, int, int) parameter #0:
+    Missing nullability on parameter `target` in method `onNestedScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onNestedScroll(android.view.View, int, int, int, int, int) parameter #0:
+    Missing nullability on parameter `target` in method `onNestedScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onNestedScrollAccepted(android.view.View, android.view.View, int) parameter #0:
+    Missing nullability on parameter `child` in method `onNestedScrollAccepted`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onNestedScrollAccepted(android.view.View, android.view.View, int) parameter #1:
+    Missing nullability on parameter `target` in method `onNestedScrollAccepted`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onNestedScrollAccepted(android.view.View, android.view.View, int, int) parameter #0:
+    Missing nullability on parameter `child` in method `onNestedScrollAccepted`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onNestedScrollAccepted(android.view.View, android.view.View, int, int) parameter #1:
+    Missing nullability on parameter `target` in method `onNestedScrollAccepted`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onStartNestedScroll(android.view.View, android.view.View, int) parameter #0:
+    Missing nullability on parameter `child` in method `onStartNestedScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onStartNestedScroll(android.view.View, android.view.View, int) parameter #1:
+    Missing nullability on parameter `target` in method `onStartNestedScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onStartNestedScroll(android.view.View, android.view.View, int, int) parameter #0:
+    Missing nullability on parameter `child` in method `onStartNestedScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onStartNestedScroll(android.view.View, android.view.View, int, int) parameter #1:
+    Missing nullability on parameter `target` in method `onStartNestedScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onStopNestedScroll(android.view.View) parameter #0:
+    Missing nullability on parameter `target` in method `onStopNestedScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onStopNestedScroll(android.view.View, int) parameter #0:
+    Missing nullability on parameter `target` in method `onStopNestedScroll`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onTouchEvent`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#setColorScheme(int...) parameter #0:
+    Missing nullability on parameter `colors` in method `setColorScheme`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#setColorSchemeColors(int...) parameter #0:
+    Missing nullability on parameter `colors` in method `setColorSchemeColors`
+MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#setColorSchemeResources(int...) parameter #0:
+    Missing nullability on parameter `colorResIds` in method `setColorSchemeResources`
diff --git a/testutils-ktx/build.gradle b/testutils-ktx/build.gradle
index 357afcf..54e885b1 100644
--- a/testutils-ktx/build.gradle
+++ b/testutils-ktx/build.gradle
@@ -22,8 +22,9 @@
 }
 
 dependencies {
-    compile(KOTLIN_STDLIB)
-    compile(TRUTH)
+    api(TRUTH)
+    api(KOTLIN_STDLIB)
+    api(KOTLIN_COROUTINES)
 }
 
 androidx {
diff --git a/testutils-ktx/src/main/java/androidx/testutils/TestDispatcher.kt b/testutils-ktx/src/main/java/androidx/testutils/TestDispatcher.kt
new file mode 100644
index 0000000..127eaef
--- /dev/null
+++ b/testutils-ktx/src/main/java/androidx/testutils/TestDispatcher.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2019 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.testutils
+
+import kotlinx.coroutines.CoroutineDispatcher
+import java.util.concurrent.ConcurrentLinkedQueue
+import kotlin.coroutines.CoroutineContext
+
+/**
+ * [CoroutineDispatcher] which keeps track of all its queues jobs.
+ */
+class TestDispatcher : CoroutineDispatcher() {
+    val queue = ConcurrentLinkedQueue<Runnable>()
+
+    override fun dispatch(context: CoroutineContext, block: Runnable) {
+        queue.add(block)
+    }
+
+    fun executeAll() {
+        while (queue.peek() != null) {
+            queue.poll()!!.run()
+        }
+    }
+}
diff --git a/textclassifier/api/api_lint.ignore b/textclassifier/api/api_lint.ignore
index 235b2b8..c5d738d 100644
--- a/textclassifier/api/api_lint.ignore
+++ b/textclassifier/api/api_lint.ignore
@@ -13,3 +13,47 @@
     Must avoid boxed primitives (`java.lang.Long`)
 AutoBoxing: androidx.textclassifier.TextLinksParams.Builder#setReferenceTime(Long) parameter #0:
     Must avoid boxed primitives (`java.lang.Long`)
+
+
+MissingNullability: androidx.textclassifier.TextClassification#getConfidenceScore(String) parameter #0:
+    Missing nullability on parameter `entity` in method `getConfidenceScore`
+MissingNullability: androidx.textclassifier.TextClassification#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.textclassifier.TextClassification.Builder#setEntityType(String, float):
+    Missing nullability on method `setEntityType` return
+MissingNullability: androidx.textclassifier.TextClassification.Builder#setText(CharSequence):
+    Missing nullability on method `setText` return
+MissingNullability: androidx.textclassifier.TextClassification.Request#createFromBundle(android.os.Bundle):
+    Missing nullability on method `createFromBundle` return
+MissingNullability: androidx.textclassifier.TextClassificationContext#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.textclassifier.TextClassificationContext.Builder#setWidgetVersion(String):
+    Missing nullability on method `setWidgetVersion` return
+MissingNullability: androidx.textclassifier.TextClassificationManager#of(android.content.Context):
+    Missing nullability on method `of` return
+MissingNullability: androidx.textclassifier.TextClassificationSessionId#equals(Object) parameter #0:
+    Missing nullability on parameter `obj` in method `equals`
+MissingNullability: androidx.textclassifier.TextClassificationSessionId#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.textclassifier.TextClassifier#NO_OP:
+    Missing nullability on field `NO_OP` in class `class androidx.textclassifier.TextClassifier`
+MissingNullability: androidx.textclassifier.TextClassifier.EntityConfig#resolveTypes(java.util.Collection<java.lang.String>):
+    Missing nullability on method `resolveTypes` return
+MissingNullability: androidx.textclassifier.TextClassifier.EntityConfig.Builder#includeTypesFromTextClassifier(boolean):
+    Missing nullability on method `includeTypesFromTextClassifier` return
+MissingNullability: androidx.textclassifier.TextClassifier.EntityConfig.Builder#setExcludedTypes(java.util.Collection<java.lang.String>):
+    Missing nullability on method `setExcludedTypes` return
+MissingNullability: androidx.textclassifier.TextClassifier.EntityConfig.Builder#setHints(java.util.Collection<java.lang.String>):
+    Missing nullability on method `setHints` return
+MissingNullability: androidx.textclassifier.TextClassifier.EntityConfig.Builder#setIncludedTypes(java.util.Collection<java.lang.String>):
+    Missing nullability on method `setIncludedTypes` return
+MissingNullability: androidx.textclassifier.TextLinks.SpanFactory#createSpan(androidx.textclassifier.TextLinks.TextLinkSpanData):
+    Missing nullability on method `createSpan` return
+MissingNullability: androidx.textclassifier.TextLinks.TextLink#getConfidenceScore(String) parameter #0:
+    Missing nullability on parameter `entityType` in method `getConfidenceScore`
+MissingNullability: androidx.textclassifier.TextLinksParams#DEFAULT_PARAMS:
+    Missing nullability on field `DEFAULT_PARAMS` in class `class androidx.textclassifier.TextLinksParams`
+MissingNullability: androidx.textclassifier.TextSelection#getConfidenceScore(String) parameter #0:
+    Missing nullability on parameter `entity` in method `getConfidenceScore`
+MissingNullability: androidx.textclassifier.TextSelection#toString():
+    Missing nullability on method `toString` return
diff --git a/transition/transition/api/api_lint.ignore b/transition/transition/api/api_lint.ignore
index 0a7434f..ffc32e2 100644
--- a/transition/transition/api/api_lint.ignore
+++ b/transition/transition/api/api_lint.ignore
@@ -3,6 +3,280 @@
     Context is distinct, so it must be the first argument (method `getSceneForLayout`)
 
 
+MissingNullability: androidx.transition.ArcMotion#ArcMotion(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `ArcMotion`
+MissingNullability: androidx.transition.ArcMotion#ArcMotion(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `ArcMotion`
+MissingNullability: androidx.transition.ArcMotion#getPath(float, float, float, float):
+    Missing nullability on method `getPath` return
+MissingNullability: androidx.transition.AutoTransition#AutoTransition(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `AutoTransition`
+MissingNullability: androidx.transition.AutoTransition#AutoTransition(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `AutoTransition`
+MissingNullability: androidx.transition.ChangeBounds#ChangeBounds(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `ChangeBounds`
+MissingNullability: androidx.transition.ChangeBounds#ChangeBounds(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `ChangeBounds`
+MissingNullability: androidx.transition.ChangeClipBounds#ChangeClipBounds(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `ChangeClipBounds`
+MissingNullability: androidx.transition.ChangeClipBounds#ChangeClipBounds(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `ChangeClipBounds`
+MissingNullability: androidx.transition.ChangeClipBounds#createAnimator(android.view.ViewGroup, androidx.transition.TransitionValues, androidx.transition.TransitionValues):
+    Missing nullability on method `createAnimator` return
+MissingNullability: androidx.transition.ChangeClipBounds#createAnimator(android.view.ViewGroup, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #1:
+    Missing nullability on parameter `startValues` in method `createAnimator`
+MissingNullability: androidx.transition.ChangeClipBounds#createAnimator(android.view.ViewGroup, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #2:
+    Missing nullability on parameter `endValues` in method `createAnimator`
+MissingNullability: androidx.transition.ChangeClipBounds#getTransitionProperties():
+    Missing nullability on method `getTransitionProperties` return
+MissingNullability: androidx.transition.ChangeImageTransform#ChangeImageTransform(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `ChangeImageTransform`
+MissingNullability: androidx.transition.ChangeImageTransform#ChangeImageTransform(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `ChangeImageTransform`
+MissingNullability: androidx.transition.ChangeImageTransform#createAnimator(android.view.ViewGroup, androidx.transition.TransitionValues, androidx.transition.TransitionValues):
+    Missing nullability on method `createAnimator` return
+MissingNullability: androidx.transition.ChangeImageTransform#createAnimator(android.view.ViewGroup, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #1:
+    Missing nullability on parameter `startValues` in method `createAnimator`
+MissingNullability: androidx.transition.ChangeImageTransform#createAnimator(android.view.ViewGroup, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #2:
+    Missing nullability on parameter `endValues` in method `createAnimator`
+MissingNullability: androidx.transition.ChangeImageTransform#getTransitionProperties():
+    Missing nullability on method `getTransitionProperties` return
+MissingNullability: androidx.transition.ChangeScroll#ChangeScroll(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `ChangeScroll`
+MissingNullability: androidx.transition.ChangeScroll#ChangeScroll(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `ChangeScroll`
+MissingNullability: androidx.transition.ChangeTransform#ChangeTransform(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `ChangeTransform`
+MissingNullability: androidx.transition.ChangeTransform#ChangeTransform(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `ChangeTransform`
+MissingNullability: androidx.transition.ChangeTransform#createAnimator(android.view.ViewGroup, androidx.transition.TransitionValues, androidx.transition.TransitionValues):
+    Missing nullability on method `createAnimator` return
+MissingNullability: androidx.transition.ChangeTransform#createAnimator(android.view.ViewGroup, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #1:
+    Missing nullability on parameter `startValues` in method `createAnimator`
+MissingNullability: androidx.transition.ChangeTransform#createAnimator(android.view.ViewGroup, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #2:
+    Missing nullability on parameter `endValues` in method `createAnimator`
+MissingNullability: androidx.transition.ChangeTransform#getTransitionProperties():
+    Missing nullability on method `getTransitionProperties` return
+MissingNullability: androidx.transition.CircularPropagation#getStartDelay(android.view.ViewGroup, androidx.transition.Transition, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `sceneRoot` in method `getStartDelay`
+MissingNullability: androidx.transition.CircularPropagation#getStartDelay(android.view.ViewGroup, androidx.transition.Transition, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #1:
+    Missing nullability on parameter `transition` in method `getStartDelay`
+MissingNullability: androidx.transition.CircularPropagation#getStartDelay(android.view.ViewGroup, androidx.transition.Transition, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #2:
+    Missing nullability on parameter `startValues` in method `getStartDelay`
+MissingNullability: androidx.transition.CircularPropagation#getStartDelay(android.view.ViewGroup, androidx.transition.Transition, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #3:
+    Missing nullability on parameter `endValues` in method `getStartDelay`
+MissingNullability: androidx.transition.Explode#Explode(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `Explode`
+MissingNullability: androidx.transition.Explode#Explode(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `Explode`
+MissingNullability: androidx.transition.Explode#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues):
+    Missing nullability on method `onAppear` return
+MissingNullability: androidx.transition.Explode#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `sceneRoot` in method `onAppear`
+MissingNullability: androidx.transition.Explode#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #1:
+    Missing nullability on parameter `view` in method `onAppear`
+MissingNullability: androidx.transition.Explode#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #2:
+    Missing nullability on parameter `startValues` in method `onAppear`
+MissingNullability: androidx.transition.Explode#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #3:
+    Missing nullability on parameter `endValues` in method `onAppear`
+MissingNullability: androidx.transition.Explode#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues):
+    Missing nullability on method `onDisappear` return
+MissingNullability: androidx.transition.Explode#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `sceneRoot` in method `onDisappear`
+MissingNullability: androidx.transition.Explode#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #1:
+    Missing nullability on parameter `view` in method `onDisappear`
+MissingNullability: androidx.transition.Explode#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #2:
+    Missing nullability on parameter `startValues` in method `onDisappear`
+MissingNullability: androidx.transition.Explode#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #3:
+    Missing nullability on parameter `endValues` in method `onDisappear`
+MissingNullability: androidx.transition.Fade#Fade(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `Fade`
+MissingNullability: androidx.transition.Fade#Fade(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `Fade`
+MissingNullability: androidx.transition.Fade#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues):
+    Missing nullability on method `onAppear` return
+MissingNullability: androidx.transition.Fade#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `sceneRoot` in method `onAppear`
+MissingNullability: androidx.transition.Fade#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #1:
+    Missing nullability on parameter `view` in method `onAppear`
+MissingNullability: androidx.transition.Fade#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #2:
+    Missing nullability on parameter `startValues` in method `onAppear`
+MissingNullability: androidx.transition.Fade#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #3:
+    Missing nullability on parameter `endValues` in method `onAppear`
+MissingNullability: androidx.transition.Fade#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues):
+    Missing nullability on method `onDisappear` return
+MissingNullability: androidx.transition.Fade#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `sceneRoot` in method `onDisappear`
+MissingNullability: androidx.transition.Fade#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #1:
+    Missing nullability on parameter `view` in method `onDisappear`
+MissingNullability: androidx.transition.Fade#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #2:
+    Missing nullability on parameter `startValues` in method `onDisappear`
+MissingNullability: androidx.transition.Fade#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #3:
+    Missing nullability on parameter `endValues` in method `onDisappear`
+MissingNullability: androidx.transition.PathMotion#PathMotion(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `PathMotion`
+MissingNullability: androidx.transition.PathMotion#PathMotion(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `PathMotion`
+MissingNullability: androidx.transition.PathMotion#getPath(float, float, float, float):
+    Missing nullability on method `getPath` return
+MissingNullability: androidx.transition.PatternPathMotion#PatternPathMotion(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `PatternPathMotion`
+MissingNullability: androidx.transition.PatternPathMotion#PatternPathMotion(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `PatternPathMotion`
+MissingNullability: androidx.transition.PatternPathMotion#PatternPathMotion(android.graphics.Path) parameter #0:
+    Missing nullability on parameter `patternPath` in method `PatternPathMotion`
+MissingNullability: androidx.transition.PatternPathMotion#getPath(float, float, float, float):
+    Missing nullability on method `getPath` return
+MissingNullability: androidx.transition.PatternPathMotion#getPatternPath():
+    Missing nullability on method `getPatternPath` return
+MissingNullability: androidx.transition.PatternPathMotion#setPatternPath(android.graphics.Path) parameter #0:
+    Missing nullability on parameter `patternPath` in method `setPatternPath`
+MissingNullability: androidx.transition.SidePropagation#getStartDelay(android.view.ViewGroup, androidx.transition.Transition, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `sceneRoot` in method `getStartDelay`
+MissingNullability: androidx.transition.SidePropagation#getStartDelay(android.view.ViewGroup, androidx.transition.Transition, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #1:
+    Missing nullability on parameter `transition` in method `getStartDelay`
+MissingNullability: androidx.transition.SidePropagation#getStartDelay(android.view.ViewGroup, androidx.transition.Transition, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #2:
+    Missing nullability on parameter `startValues` in method `getStartDelay`
+MissingNullability: androidx.transition.SidePropagation#getStartDelay(android.view.ViewGroup, androidx.transition.Transition, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #3:
+    Missing nullability on parameter `endValues` in method `getStartDelay`
+MissingNullability: androidx.transition.Slide#Slide(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `Slide`
+MissingNullability: androidx.transition.Slide#Slide(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `Slide`
+MissingNullability: androidx.transition.Slide#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues):
+    Missing nullability on method `onAppear` return
+MissingNullability: androidx.transition.Slide#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `sceneRoot` in method `onAppear`
+MissingNullability: androidx.transition.Slide#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #1:
+    Missing nullability on parameter `view` in method `onAppear`
+MissingNullability: androidx.transition.Slide#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #2:
+    Missing nullability on parameter `startValues` in method `onAppear`
+MissingNullability: androidx.transition.Slide#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #3:
+    Missing nullability on parameter `endValues` in method `onAppear`
+MissingNullability: androidx.transition.Slide#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues):
+    Missing nullability on method `onDisappear` return
+MissingNullability: androidx.transition.Slide#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `sceneRoot` in method `onDisappear`
+MissingNullability: androidx.transition.Slide#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #1:
+    Missing nullability on parameter `view` in method `onDisappear`
+MissingNullability: androidx.transition.Slide#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #2:
+    Missing nullability on parameter `startValues` in method `onDisappear`
+MissingNullability: androidx.transition.Slide#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #3:
+    Missing nullability on parameter `endValues` in method `onDisappear`
+MissingNullability: androidx.transition.Transition#Transition(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `Transition`
+MissingNullability: androidx.transition.Transition#Transition(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `Transition`
+MissingNullability: androidx.transition.Transition#clone():
+    Missing nullability on method `clone` return
+MissingNullability: androidx.transition.Transition#setMatchOrder(int...) parameter #0:
+    Missing nullability on parameter `matches` in method `setMatchOrder`
+MissingNullability: androidx.transition.Transition#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.transition.Transition.EpicenterCallback#onGetEpicenter(androidx.transition.Transition):
+    Missing nullability on method `onGetEpicenter` return
+MissingNullability: androidx.transition.TransitionInflater#from(android.content.Context):
+    Missing nullability on method `from` return
+MissingNullability: androidx.transition.TransitionInflater#from(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `from`
+MissingNullability: androidx.transition.TransitionInflater#inflateTransition(int):
+    Missing nullability on method `inflateTransition` return
+MissingNullability: androidx.transition.TransitionInflater#inflateTransitionManager(int, android.view.ViewGroup):
+    Missing nullability on method `inflateTransitionManager` return
+MissingNullability: androidx.transition.TransitionInflater#inflateTransitionManager(int, android.view.ViewGroup) parameter #1:
+    Missing nullability on parameter `sceneRoot` in method `inflateTransitionManager`
+MissingNullability: androidx.transition.TransitionManager#endTransitions(android.view.ViewGroup) parameter #0:
+    Missing nullability on parameter `sceneRoot` in method `endTransitions`
+MissingNullability: androidx.transition.TransitionPropagation#captureValues(androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `transitionValues` in method `captureValues`
+MissingNullability: androidx.transition.TransitionPropagation#getPropagationProperties():
+    Missing nullability on method `getPropagationProperties` return
+MissingNullability: androidx.transition.TransitionPropagation#getStartDelay(android.view.ViewGroup, androidx.transition.Transition, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `sceneRoot` in method `getStartDelay`
+MissingNullability: androidx.transition.TransitionPropagation#getStartDelay(android.view.ViewGroup, androidx.transition.Transition, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #1:
+    Missing nullability on parameter `transition` in method `getStartDelay`
+MissingNullability: androidx.transition.TransitionPropagation#getStartDelay(android.view.ViewGroup, androidx.transition.Transition, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #2:
+    Missing nullability on parameter `startValues` in method `getStartDelay`
+MissingNullability: androidx.transition.TransitionPropagation#getStartDelay(android.view.ViewGroup, androidx.transition.Transition, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #3:
+    Missing nullability on parameter `endValues` in method `getStartDelay`
+MissingNullability: androidx.transition.TransitionSet#TransitionSet(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `TransitionSet`
+MissingNullability: androidx.transition.TransitionSet#TransitionSet(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `TransitionSet`
+MissingNullability: androidx.transition.TransitionSet#clone():
+    Missing nullability on method `clone` return
+MissingNullability: androidx.transition.TransitionSet#setEpicenterCallback(androidx.transition.Transition.EpicenterCallback) parameter #0:
+    Missing nullability on parameter `epicenterCallback` in method `setEpicenterCallback`
+MissingNullability: androidx.transition.TransitionSet#setPathMotion(androidx.transition.PathMotion) parameter #0:
+    Missing nullability on parameter `pathMotion` in method `setPathMotion`
+MissingNullability: androidx.transition.TransitionSet#setPropagation(androidx.transition.TransitionPropagation) parameter #0:
+    Missing nullability on parameter `propagation` in method `setPropagation`
+MissingNullability: androidx.transition.TransitionValues#equals(Object) parameter #0:
+    Missing nullability on parameter `other` in method `equals`
+MissingNullability: androidx.transition.TransitionValues#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.transition.TransitionValues#values:
+    Missing nullability on field `values` in class `class androidx.transition.TransitionValues`
+MissingNullability: androidx.transition.TransitionValues#view:
+    Missing nullability on field `view` in class `class androidx.transition.TransitionValues`
+MissingNullability: androidx.transition.Visibility#Visibility(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `Visibility`
+MissingNullability: androidx.transition.Visibility#Visibility(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `Visibility`
+MissingNullability: androidx.transition.Visibility#isTransitionRequired(androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `startValues` in method `isTransitionRequired`
+MissingNullability: androidx.transition.Visibility#isTransitionRequired(androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #1:
+    Missing nullability on parameter `newValues` in method `isTransitionRequired`
+MissingNullability: androidx.transition.Visibility#isVisible(androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `values` in method `isVisible`
+MissingNullability: androidx.transition.Visibility#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues):
+    Missing nullability on method `onAppear` return
+MissingNullability: androidx.transition.Visibility#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `sceneRoot` in method `onAppear`
+MissingNullability: androidx.transition.Visibility#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #1:
+    Missing nullability on parameter `view` in method `onAppear`
+MissingNullability: androidx.transition.Visibility#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #2:
+    Missing nullability on parameter `startValues` in method `onAppear`
+MissingNullability: androidx.transition.Visibility#onAppear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #3:
+    Missing nullability on parameter `endValues` in method `onAppear`
+MissingNullability: androidx.transition.Visibility#onAppear(android.view.ViewGroup, androidx.transition.TransitionValues, int, androidx.transition.TransitionValues, int):
+    Missing nullability on method `onAppear` return
+MissingNullability: androidx.transition.Visibility#onAppear(android.view.ViewGroup, androidx.transition.TransitionValues, int, androidx.transition.TransitionValues, int) parameter #0:
+    Missing nullability on parameter `sceneRoot` in method `onAppear`
+MissingNullability: androidx.transition.Visibility#onAppear(android.view.ViewGroup, androidx.transition.TransitionValues, int, androidx.transition.TransitionValues, int) parameter #1:
+    Missing nullability on parameter `startValues` in method `onAppear`
+MissingNullability: androidx.transition.Visibility#onAppear(android.view.ViewGroup, androidx.transition.TransitionValues, int, androidx.transition.TransitionValues, int) parameter #3:
+    Missing nullability on parameter `endValues` in method `onAppear`
+MissingNullability: androidx.transition.Visibility#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues):
+    Missing nullability on method `onDisappear` return
+MissingNullability: androidx.transition.Visibility#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `sceneRoot` in method `onDisappear`
+MissingNullability: androidx.transition.Visibility#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #1:
+    Missing nullability on parameter `view` in method `onDisappear`
+MissingNullability: androidx.transition.Visibility#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #2:
+    Missing nullability on parameter `startValues` in method `onDisappear`
+MissingNullability: androidx.transition.Visibility#onDisappear(android.view.ViewGroup, android.view.View, androidx.transition.TransitionValues, androidx.transition.TransitionValues) parameter #3:
+    Missing nullability on parameter `endValues` in method `onDisappear`
+MissingNullability: androidx.transition.Visibility#onDisappear(android.view.ViewGroup, androidx.transition.TransitionValues, int, androidx.transition.TransitionValues, int):
+    Missing nullability on method `onDisappear` return
+MissingNullability: androidx.transition.Visibility#onDisappear(android.view.ViewGroup, androidx.transition.TransitionValues, int, androidx.transition.TransitionValues, int) parameter #0:
+    Missing nullability on parameter `sceneRoot` in method `onDisappear`
+MissingNullability: androidx.transition.Visibility#onDisappear(android.view.ViewGroup, androidx.transition.TransitionValues, int, androidx.transition.TransitionValues, int) parameter #1:
+    Missing nullability on parameter `startValues` in method `onDisappear`
+MissingNullability: androidx.transition.Visibility#onDisappear(android.view.ViewGroup, androidx.transition.TransitionValues, int, androidx.transition.TransitionValues, int) parameter #3:
+    Missing nullability on parameter `endValues` in method `onDisappear`
+MissingNullability: androidx.transition.VisibilityPropagation#captureValues(androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `values` in method `captureValues`
+MissingNullability: androidx.transition.VisibilityPropagation#getPropagationProperties():
+    Missing nullability on method `getPropagationProperties` return
+MissingNullability: androidx.transition.VisibilityPropagation#getViewVisibility(androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `values` in method `getViewVisibility`
+MissingNullability: androidx.transition.VisibilityPropagation#getViewX(androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `values` in method `getViewX`
+MissingNullability: androidx.transition.VisibilityPropagation#getViewY(androidx.transition.TransitionValues) parameter #0:
+    Missing nullability on parameter `values` in method `getViewY`
+
+
 NoClone: androidx.transition.Transition#clone():
     Provide an explicit copy constructor instead of implementing `clone()`
 NoClone: androidx.transition.TransitionSet#clone():
diff --git a/tv-provider/api/api_lint.ignore b/tv-provider/api/api_lint.ignore
index dcf4d5f..9f1ac87 100644
--- a/tv-provider/api/api_lint.ignore
+++ b/tv-provider/api/api_lint.ignore
@@ -49,3 +49,387 @@
     Intent action constant name must be ACTION_FOO: COLUMN_INTERACTION_COUNT
 IntentName: androidx.tvprovider.media.tv.TvContractCompat.WatchNextPrograms#COLUMN_INTERACTION_TYPE:
     Intent action constant name must be ACTION_FOO: COLUMN_INTERACTION_TYPE
+
+
+MissingNullability: androidx.tvprovider.media.tv.Channel#equals(Object) parameter #0:
+    Missing nullability on parameter `other` in method `equals`
+MissingNullability: androidx.tvprovider.media.tv.Channel#fromCursor(android.database.Cursor):
+    Missing nullability on method `fromCursor` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#fromCursor(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `cursor` in method `fromCursor`
+MissingNullability: androidx.tvprovider.media.tv.Channel#getAppLinkIconUri():
+    Missing nullability on method `getAppLinkIconUri` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getAppLinkIntent():
+    Missing nullability on method `getAppLinkIntent` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getAppLinkIntentUri():
+    Missing nullability on method `getAppLinkIntentUri` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getAppLinkPosterArtUri():
+    Missing nullability on method `getAppLinkPosterArtUri` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getAppLinkText():
+    Missing nullability on method `getAppLinkText` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getDescription():
+    Missing nullability on method `getDescription` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getDisplayName():
+    Missing nullability on method `getDisplayName` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getDisplayNumber():
+    Missing nullability on method `getDisplayNumber` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getInputId():
+    Missing nullability on method `getInputId` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getInternalProviderDataByteArray():
+    Missing nullability on method `getInternalProviderDataByteArray` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getInternalProviderFlag1():
+    Missing nullability on method `getInternalProviderFlag1` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getInternalProviderFlag2():
+    Missing nullability on method `getInternalProviderFlag2` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getInternalProviderFlag3():
+    Missing nullability on method `getInternalProviderFlag3` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getInternalProviderFlag4():
+    Missing nullability on method `getInternalProviderFlag4` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getInternalProviderId():
+    Missing nullability on method `getInternalProviderId` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getNetworkAffiliation():
+    Missing nullability on method `getNetworkAffiliation` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getPackageName():
+    Missing nullability on method `getPackageName` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getServiceType():
+    Missing nullability on method `getServiceType` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getSystemChannelKey():
+    Missing nullability on method `getSystemChannelKey` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getType():
+    Missing nullability on method `getType` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#getVideoFormat():
+    Missing nullability on method `getVideoFormat` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#toContentValues():
+    Missing nullability on method `toContentValues` return
+MissingNullability: androidx.tvprovider.media.tv.Channel#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#Builder(androidx.tvprovider.media.tv.Channel) parameter #0:
+    Missing nullability on parameter `other` in method `Builder`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setAppLinkColor(int):
+    Missing nullability on method `setAppLinkColor` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setAppLinkIconUri(android.net.Uri):
+    Missing nullability on method `setAppLinkIconUri` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setAppLinkIconUri(android.net.Uri) parameter #0:
+    Missing nullability on parameter `appLinkIconUri` in method `setAppLinkIconUri`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setAppLinkIntent(android.content.Intent):
+    Missing nullability on method `setAppLinkIntent` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setAppLinkIntent(android.content.Intent) parameter #0:
+    Missing nullability on parameter `appLinkIntent` in method `setAppLinkIntent`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setAppLinkIntentUri(android.net.Uri):
+    Missing nullability on method `setAppLinkIntentUri` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setAppLinkIntentUri(android.net.Uri) parameter #0:
+    Missing nullability on parameter `appLinkIntentUri` in method `setAppLinkIntentUri`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setAppLinkPosterArtUri(android.net.Uri):
+    Missing nullability on method `setAppLinkPosterArtUri` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setAppLinkPosterArtUri(android.net.Uri) parameter #0:
+    Missing nullability on parameter `appLinkPosterArtUri` in method `setAppLinkPosterArtUri`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setAppLinkText(String):
+    Missing nullability on method `setAppLinkText` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setAppLinkText(String) parameter #0:
+    Missing nullability on parameter `appLinkText` in method `setAppLinkText`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setConfigurationDisplayOrder(int):
+    Missing nullability on method `setConfigurationDisplayOrder` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setDescription(String):
+    Missing nullability on method `setDescription` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setDescription(String) parameter #0:
+    Missing nullability on parameter `description` in method `setDescription`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setDisplayName(String):
+    Missing nullability on method `setDisplayName` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setDisplayName(String) parameter #0:
+    Missing nullability on parameter `displayName` in method `setDisplayName`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setDisplayNumber(String):
+    Missing nullability on method `setDisplayNumber` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setDisplayNumber(String) parameter #0:
+    Missing nullability on parameter `displayNumber` in method `setDisplayNumber`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setInputId(String):
+    Missing nullability on method `setInputId` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setInputId(String) parameter #0:
+    Missing nullability on parameter `inputId` in method `setInputId`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setInternalProviderData(String):
+    Missing nullability on method `setInternalProviderData` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setInternalProviderData(String) parameter #0:
+    Missing nullability on parameter `internalProviderData` in method `setInternalProviderData`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setInternalProviderData(byte[]):
+    Missing nullability on method `setInternalProviderData` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setInternalProviderData(byte[]) parameter #0:
+    Missing nullability on parameter `internalProviderData` in method `setInternalProviderData`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setInternalProviderFlag1(long):
+    Missing nullability on method `setInternalProviderFlag1` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setInternalProviderFlag2(long):
+    Missing nullability on method `setInternalProviderFlag2` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setInternalProviderFlag3(long):
+    Missing nullability on method `setInternalProviderFlag3` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setInternalProviderFlag4(long):
+    Missing nullability on method `setInternalProviderFlag4` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setInternalProviderId(String):
+    Missing nullability on method `setInternalProviderId` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setInternalProviderId(String) parameter #0:
+    Missing nullability on parameter `internalProviderId` in method `setInternalProviderId`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setNetworkAffiliation(String):
+    Missing nullability on method `setNetworkAffiliation` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setNetworkAffiliation(String) parameter #0:
+    Missing nullability on parameter `networkAffiliation` in method `setNetworkAffiliation`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setOriginalNetworkId(int):
+    Missing nullability on method `setOriginalNetworkId` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setSearchable(boolean):
+    Missing nullability on method `setSearchable` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setServiceId(int):
+    Missing nullability on method `setServiceId` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setServiceType(String):
+    Missing nullability on method `setServiceType` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setServiceType(String) parameter #0:
+    Missing nullability on parameter `serviceType` in method `setServiceType`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setSystemChannelKey(String):
+    Missing nullability on method `setSystemChannelKey` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setSystemChannelKey(String) parameter #0:
+    Missing nullability on parameter `value` in method `setSystemChannelKey`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setTransient(boolean):
+    Missing nullability on method `setTransient` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setTransportStreamId(int):
+    Missing nullability on method `setTransportStreamId` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setType(String):
+    Missing nullability on method `setType` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setType(String) parameter #0:
+    Missing nullability on parameter `type` in method `setType`
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setVideoFormat(String):
+    Missing nullability on method `setVideoFormat` return
+MissingNullability: androidx.tvprovider.media.tv.Channel.Builder#setVideoFormat(String) parameter #0:
+    Missing nullability on parameter `videoFormat` in method `setVideoFormat`
+MissingNullability: androidx.tvprovider.media.tv.ChannelLogoUtils#loadChannelLogo(android.content.Context, long):
+    Missing nullability on method `loadChannelLogo` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#equals(Object) parameter #0:
+    Missing nullability on parameter `other` in method `equals`
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#fromCursor(android.database.Cursor):
+    Missing nullability on method `fromCursor` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#fromCursor(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `cursor` in method `fromCursor`
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#getAppLinkIntent():
+    Missing nullability on method `getAppLinkIntent` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#getAppLinkIntentUri():
+    Missing nullability on method `getAppLinkIntentUri` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#getDescription():
+    Missing nullability on method `getDescription` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#getDisplayName():
+    Missing nullability on method `getDisplayName` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#getInternalProviderDataByteArray():
+    Missing nullability on method `getInternalProviderDataByteArray` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#getInternalProviderFlag1():
+    Missing nullability on method `getInternalProviderFlag1` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#getInternalProviderFlag2():
+    Missing nullability on method `getInternalProviderFlag2` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#getInternalProviderFlag3():
+    Missing nullability on method `getInternalProviderFlag3` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#getInternalProviderFlag4():
+    Missing nullability on method `getInternalProviderFlag4` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#getInternalProviderId():
+    Missing nullability on method `getInternalProviderId` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#getLogo(android.content.Context):
+    Missing nullability on method `getLogo` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#getLogo(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `getLogo`
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#getPackageName():
+    Missing nullability on method `getPackageName` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#getType():
+    Missing nullability on method `getType` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#hasAnyUpdatedValues(androidx.tvprovider.media.tv.PreviewChannel) parameter #0:
+    Missing nullability on parameter `update` in method `hasAnyUpdatedValues`
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#Builder(androidx.tvprovider.media.tv.PreviewChannel) parameter #0:
+    Missing nullability on parameter `other` in method `Builder`
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setAppLinkIntent(android.content.Intent):
+    Missing nullability on method `setAppLinkIntent` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setAppLinkIntent(android.content.Intent) parameter #0:
+    Missing nullability on parameter `appLinkIntent` in method `setAppLinkIntent`
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setAppLinkIntentUri(android.net.Uri):
+    Missing nullability on method `setAppLinkIntentUri` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setAppLinkIntentUri(android.net.Uri) parameter #0:
+    Missing nullability on parameter `appLinkIntentUri` in method `setAppLinkIntentUri`
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setDescription(CharSequence):
+    Missing nullability on method `setDescription` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setDescription(CharSequence) parameter #0:
+    Missing nullability on parameter `description` in method `setDescription`
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setDisplayName(CharSequence):
+    Missing nullability on method `setDisplayName` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setDisplayName(CharSequence) parameter #0:
+    Missing nullability on parameter `displayName` in method `setDisplayName`
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setInternalProviderData(byte[]):
+    Missing nullability on method `setInternalProviderData` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setInternalProviderData(byte[]) parameter #0:
+    Missing nullability on parameter `internalProviderData` in method `setInternalProviderData`
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setInternalProviderFlag1(long):
+    Missing nullability on method `setInternalProviderFlag1` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setInternalProviderFlag2(long):
+    Missing nullability on method `setInternalProviderFlag2` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setInternalProviderFlag3(long):
+    Missing nullability on method `setInternalProviderFlag3` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setInternalProviderFlag4(long):
+    Missing nullability on method `setInternalProviderFlag4` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setInternalProviderId(String):
+    Missing nullability on method `setInternalProviderId` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setInternalProviderId(String) parameter #0:
+    Missing nullability on parameter `internalProviderId` in method `setInternalProviderId`
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setLogo(android.graphics.Bitmap):
+    Missing nullability on method `setLogo` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannel.Builder#setLogo(android.net.Uri):
+    Missing nullability on method `setLogo` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannelHelper#PreviewChannelHelper(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `PreviewChannelHelper`
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannelHelper#PreviewChannelHelper(android.content.Context, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `PreviewChannelHelper`
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannelHelper#downloadBitmap(android.net.Uri):
+    Missing nullability on method `downloadBitmap` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannelHelper#getAllChannels():
+    Missing nullability on method `getAllChannels` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannelHelper#getPreviewChannel(long):
+    Missing nullability on method `getPreviewChannel` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannelHelper#getPreviewProgram(long):
+    Missing nullability on method `getPreviewProgram` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewChannelHelper#getWatchNextProgram(long):
+    Missing nullability on method `getWatchNextProgram` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewProgram#equals(Object) parameter #0:
+    Missing nullability on parameter `other` in method `equals`
+MissingNullability: androidx.tvprovider.media.tv.PreviewProgram#fromCursor(android.database.Cursor):
+    Missing nullability on method `fromCursor` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewProgram#fromCursor(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `cursor` in method `fromCursor`
+MissingNullability: androidx.tvprovider.media.tv.PreviewProgram#hasAnyUpdatedValues(androidx.tvprovider.media.tv.PreviewProgram) parameter #0:
+    Missing nullability on parameter `update` in method `hasAnyUpdatedValues`
+MissingNullability: androidx.tvprovider.media.tv.PreviewProgram#toContentValues():
+    Missing nullability on method `toContentValues` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewProgram#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewProgram.Builder#Builder(androidx.tvprovider.media.tv.PreviewProgram) parameter #0:
+    Missing nullability on parameter `other` in method `Builder`
+MissingNullability: androidx.tvprovider.media.tv.PreviewProgram.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewProgram.Builder#setChannelId(long):
+    Missing nullability on method `setChannelId` return
+MissingNullability: androidx.tvprovider.media.tv.PreviewProgram.Builder#setWeight(int):
+    Missing nullability on method `setWeight` return
+MissingNullability: androidx.tvprovider.media.tv.Program#equals(Object) parameter #0:
+    Missing nullability on parameter `other` in method `equals`
+MissingNullability: androidx.tvprovider.media.tv.Program#fromCursor(android.database.Cursor):
+    Missing nullability on method `fromCursor` return
+MissingNullability: androidx.tvprovider.media.tv.Program#fromCursor(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `cursor` in method `fromCursor`
+MissingNullability: androidx.tvprovider.media.tv.Program#getBroadcastGenres():
+    Missing nullability on method `getBroadcastGenres` return
+MissingNullability: androidx.tvprovider.media.tv.Program#toContentValues():
+    Missing nullability on method `toContentValues` return
+MissingNullability: androidx.tvprovider.media.tv.Program#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.tvprovider.media.tv.Program.Builder#Builder(androidx.tvprovider.media.tv.Program) parameter #0:
+    Missing nullability on parameter `other` in method `Builder`
+MissingNullability: androidx.tvprovider.media.tv.Program.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.tvprovider.media.tv.Program.Builder#setBroadcastGenres(String[]):
+    Missing nullability on method `setBroadcastGenres` return
+MissingNullability: androidx.tvprovider.media.tv.Program.Builder#setBroadcastGenres(String[]) parameter #0:
+    Missing nullability on parameter `genres` in method `setBroadcastGenres`
+MissingNullability: androidx.tvprovider.media.tv.Program.Builder#setChannelId(long):
+    Missing nullability on method `setChannelId` return
+MissingNullability: androidx.tvprovider.media.tv.Program.Builder#setEndTimeUtcMillis(long):
+    Missing nullability on method `setEndTimeUtcMillis` return
+MissingNullability: androidx.tvprovider.media.tv.Program.Builder#setRecordingProhibited(boolean):
+    Missing nullability on method `setRecordingProhibited` return
+MissingNullability: androidx.tvprovider.media.tv.Program.Builder#setStartTimeUtcMillis(long):
+    Missing nullability on method `setStartTimeUtcMillis` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildChannelLogoUri(android.net.Uri):
+    Missing nullability on method `buildChannelLogoUri` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildChannelLogoUri(android.net.Uri) parameter #0:
+    Missing nullability on parameter `channelUri` in method `buildChannelLogoUri`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildChannelLogoUri(long):
+    Missing nullability on method `buildChannelLogoUri` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildChannelUri(long):
+    Missing nullability on method `buildChannelUri` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildChannelUriForPassthroughInput(String):
+    Missing nullability on method `buildChannelUriForPassthroughInput` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildChannelUriForPassthroughInput(String) parameter #0:
+    Missing nullability on parameter `inputId` in method `buildChannelUriForPassthroughInput`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildChannelsUriForInput(String):
+    Missing nullability on method `buildChannelsUriForInput` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildInputId(android.content.ComponentName):
+    Missing nullability on method `buildInputId` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildInputId(android.content.ComponentName) parameter #0:
+    Missing nullability on parameter `name` in method `buildInputId`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildPreviewProgramUri(long):
+    Missing nullability on method `buildPreviewProgramUri` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildPreviewProgramsUriForChannel(android.net.Uri):
+    Missing nullability on method `buildPreviewProgramsUriForChannel` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildPreviewProgramsUriForChannel(android.net.Uri) parameter #0:
+    Missing nullability on parameter `channelUri` in method `buildPreviewProgramsUriForChannel`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildPreviewProgramsUriForChannel(long):
+    Missing nullability on method `buildPreviewProgramsUriForChannel` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildProgramUri(long):
+    Missing nullability on method `buildProgramUri` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildProgramsUriForChannel(android.net.Uri):
+    Missing nullability on method `buildProgramsUriForChannel` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildProgramsUriForChannel(android.net.Uri) parameter #0:
+    Missing nullability on parameter `channelUri` in method `buildProgramsUriForChannel`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildProgramsUriForChannel(android.net.Uri, long, long):
+    Missing nullability on method `buildProgramsUriForChannel` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildProgramsUriForChannel(android.net.Uri, long, long) parameter #0:
+    Missing nullability on parameter `channelUri` in method `buildProgramsUriForChannel`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildProgramsUriForChannel(long):
+    Missing nullability on method `buildProgramsUriForChannel` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildProgramsUriForChannel(long, long, long):
+    Missing nullability on method `buildProgramsUriForChannel` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildRecordedProgramUri(long):
+    Missing nullability on method `buildRecordedProgramUri` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#buildWatchNextProgramUri(long):
+    Missing nullability on method `buildWatchNextProgramUri` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#isChannelUri(android.net.Uri) parameter #0:
+    Missing nullability on parameter `uri` in method `isChannelUri`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#isChannelUriForPassthroughInput(android.net.Uri) parameter #0:
+    Missing nullability on parameter `uri` in method `isChannelUriForPassthroughInput`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#isChannelUriForTunerInput(android.net.Uri) parameter #0:
+    Missing nullability on parameter `uri` in method `isChannelUriForTunerInput`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#isProgramUri(android.net.Uri) parameter #0:
+    Missing nullability on parameter `uri` in method `isProgramUri`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#isRecordedProgramUri(android.net.Uri) parameter #0:
+    Missing nullability on parameter `uri` in method `isRecordedProgramUri`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat#requestChannelBrowsable(android.content.Context, long) parameter #0:
+    Missing nullability on parameter `context` in method `requestChannelBrowsable`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat.Channels#CONTENT_URI:
+    Missing nullability on field `CONTENT_URI` in class `class androidx.tvprovider.media.tv.TvContractCompat.Channels`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat.Channels#getVideoResolution(String) parameter #0:
+    Missing nullability on parameter `videoFormat` in method `getVideoResolution`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#CONTENT_URI:
+    Missing nullability on field `CONTENT_URI` in class `class androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat.Programs#CONTENT_URI:
+    Missing nullability on field `CONTENT_URI` in class `class androidx.tvprovider.media.tv.TvContractCompat.Programs`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat.Programs.Genres#decode(String):
+    Missing nullability on method `decode` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat.Programs.Genres#encode(java.lang.String...):
+    Missing nullability on method `encode` return
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat.Programs.Genres#isCanonical(String) parameter #0:
+    Missing nullability on parameter `genre` in method `isCanonical`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat.RecordedPrograms#CONTENT_URI:
+    Missing nullability on field `CONTENT_URI` in class `class androidx.tvprovider.media.tv.TvContractCompat.RecordedPrograms`
+MissingNullability: androidx.tvprovider.media.tv.TvContractCompat.WatchNextPrograms#CONTENT_URI:
+    Missing nullability on field `CONTENT_URI` in class `class androidx.tvprovider.media.tv.TvContractCompat.WatchNextPrograms`
+MissingNullability: androidx.tvprovider.media.tv.WatchNextProgram#equals(Object) parameter #0:
+    Missing nullability on parameter `other` in method `equals`
+MissingNullability: androidx.tvprovider.media.tv.WatchNextProgram#fromCursor(android.database.Cursor):
+    Missing nullability on method `fromCursor` return
+MissingNullability: androidx.tvprovider.media.tv.WatchNextProgram#fromCursor(android.database.Cursor) parameter #0:
+    Missing nullability on parameter `cursor` in method `fromCursor`
+MissingNullability: androidx.tvprovider.media.tv.WatchNextProgram#hasAnyUpdatedValues(androidx.tvprovider.media.tv.WatchNextProgram) parameter #0:
+    Missing nullability on parameter `update` in method `hasAnyUpdatedValues`
+MissingNullability: androidx.tvprovider.media.tv.WatchNextProgram#toContentValues():
+    Missing nullability on method `toContentValues` return
+MissingNullability: androidx.tvprovider.media.tv.WatchNextProgram#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.tvprovider.media.tv.WatchNextProgram.Builder#Builder(androidx.tvprovider.media.tv.WatchNextProgram) parameter #0:
+    Missing nullability on parameter `other` in method `Builder`
+MissingNullability: androidx.tvprovider.media.tv.WatchNextProgram.Builder#build():
+    Missing nullability on method `build` return
+MissingNullability: androidx.tvprovider.media.tv.WatchNextProgram.Builder#setLastEngagementTimeUtcMillis(long):
+    Missing nullability on method `setLastEngagementTimeUtcMillis` return
+MissingNullability: androidx.tvprovider.media.tv.WatchNextProgram.Builder#setWatchNextType(int):
+    Missing nullability on method `setWatchNextType` return
diff --git a/ui/integration-tests/benchmark/build.gradle b/ui/integration-tests/benchmark/build.gradle
index 44c1326..ed6d87d 100644
--- a/ui/integration-tests/benchmark/build.gradle
+++ b/ui/integration-tests/benchmark/build.gradle
@@ -43,6 +43,7 @@
     androidTestImplementation 'androidx.test.ext:junit:1.1.0'
     androidTestImplementation(TRUTH)
     androidTestImplementation(ANDROIDX_TEST_RULES)
+    androidTestCompile project(path: ':ui:ui-layout')
 }
 
 androidx {
@@ -54,7 +55,7 @@
     description = "UI Benchmarks"
 }
 
-android.defaultConfig.minSdkVersion 29 // RenderNode requires 29+
+android.defaultConfig.minSdkVersion 21
 
 tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
     kotlinOptions {
diff --git a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/NestedScrollerBenchmark.kt b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/NestedScrollerBenchmark.kt
new file mode 100644
index 0000000..472ff08
--- /dev/null
+++ b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/NestedScrollerBenchmark.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2019 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.ui.benchmark.test
+
+import android.app.Activity
+import androidx.benchmark.junit4.BenchmarkRule
+import androidx.test.filters.LargeTest
+import androidx.test.rule.ActivityTestRule
+import androidx.ui.benchmark.measureDrawPerf
+import androidx.ui.benchmark.measureFirstCompose
+import androidx.ui.benchmark.measureFirstDraw
+import androidx.ui.benchmark.measureFirstLayout
+import androidx.ui.benchmark.measureFirstMeasure
+import androidx.ui.benchmark.measureLayoutPerf
+import androidx.ui.benchmark.toggleStateMeasureDraw
+import androidx.ui.benchmark.toggleStateMeasureLayout
+import androidx.ui.benchmark.toggleStateMeasureMeasure
+import androidx.ui.test.DisableTransitions
+import androidx.ui.test.cases.NestedScrollerTestCase
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@LargeTest
+@RunWith(JUnit4::class)
+class NestedScrollerBenchmark {
+    @get:Rule
+    val benchmarkRule = BenchmarkRule()
+
+    @get:Rule
+    val activityRule = ActivityTestRule(Activity::class.java)
+
+    @get:Rule
+    val disableAnimationRule = DisableTransitions()
+
+    private val activity: Activity get() = activityRule.activity
+
+    @Test
+    fun first_compose() {
+        benchmarkRule.measureFirstCompose(activity, NestedScrollerTestCase(activity))
+    }
+
+    @Test
+    fun first_measure() {
+        benchmarkRule.measureFirstMeasure(activity, NestedScrollerTestCase(activity))
+    }
+
+    @Test
+    fun first_layout() {
+        benchmarkRule.measureFirstLayout(activity, NestedScrollerTestCase(activity))
+    }
+
+    @Test
+    fun first_draw() {
+        benchmarkRule.measureFirstDraw(activity, NestedScrollerTestCase(activity))
+    }
+
+    @Test
+    fun changeScroll_measure() {
+        benchmarkRule.toggleStateMeasureMeasure(activity, NestedScrollerTestCase(activity),
+            toggleCausesRecompose = false, firstDrawCausesRecompose = true)
+    }
+
+    @Test
+    fun changeScroll_layout() {
+        benchmarkRule.toggleStateMeasureLayout(activity, NestedScrollerTestCase(activity),
+            toggleCausesRecompose = false, firstDrawCausesRecompose = true)
+    }
+
+    @Test
+    fun changeScroll_draw() {
+        benchmarkRule.toggleStateMeasureDraw(activity, NestedScrollerTestCase(activity),
+            toggleCausesRecompose = false, firstDrawCausesRecompose = true)
+    }
+
+    @Test
+    fun layout() {
+        benchmarkRule.measureLayoutPerf(activity, NestedScrollerTestCase(activity))
+    }
+
+    @Test
+    fun draw() {
+        benchmarkRule.measureDrawPerf(activity, NestedScrollerTestCase(activity))
+    }
+}
diff --git a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/ScrollerBenchmark.kt b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/ScrollerBenchmark.kt
new file mode 100644
index 0000000..95f6760
--- /dev/null
+++ b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/ScrollerBenchmark.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2019 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.ui.benchmark.test
+
+import android.app.Activity
+import androidx.benchmark.junit4.BenchmarkRule
+import androidx.test.filters.LargeTest
+import androidx.test.rule.ActivityTestRule
+import androidx.ui.benchmark.measureDrawPerf
+import androidx.ui.benchmark.measureFirstCompose
+import androidx.ui.benchmark.measureFirstDraw
+import androidx.ui.benchmark.measureFirstLayout
+import androidx.ui.benchmark.measureFirstMeasure
+import androidx.ui.benchmark.measureLayoutPerf
+import androidx.ui.benchmark.toggleStateMeasureDraw
+import androidx.ui.benchmark.toggleStateMeasureLayout
+import androidx.ui.benchmark.toggleStateMeasureMeasure
+import androidx.ui.test.DisableTransitions
+import androidx.ui.test.cases.ScrollerTestCase
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@LargeTest
+@RunWith(JUnit4::class)
+class ScrollerBenchmark {
+    @get:Rule
+    val benchmarkRule = BenchmarkRule()
+
+    @get:Rule
+    val activityRule = ActivityTestRule(Activity::class.java)
+
+    @get:Rule
+    val disableAnimationRule = DisableTransitions()
+
+    private val activity: Activity get() = activityRule.activity
+
+    @Test
+    fun first_compose() {
+        benchmarkRule.measureFirstCompose(activity, ScrollerTestCase(activity))
+    }
+
+    @Test
+    fun first_measure() {
+        benchmarkRule.measureFirstMeasure(activity, ScrollerTestCase(activity))
+    }
+
+    @Test
+    fun first_layout() {
+        benchmarkRule.measureFirstLayout(activity, ScrollerTestCase(activity))
+    }
+
+    @Test
+    fun first_draw() {
+        benchmarkRule.measureFirstDraw(activity, ScrollerTestCase(activity))
+    }
+
+    @Test
+    fun changeScroll_measure() {
+        benchmarkRule.toggleStateMeasureMeasure(activity, ScrollerTestCase(activity),
+            toggleCausesRecompose = false, firstDrawCausesRecompose = true)
+    }
+
+    @Test
+    fun changeScroll_layout() {
+        benchmarkRule.toggleStateMeasureLayout(activity, ScrollerTestCase(activity),
+            toggleCausesRecompose = false, firstDrawCausesRecompose = true)
+    }
+
+    @Test
+    fun changeScroll_draw() {
+        benchmarkRule.toggleStateMeasureDraw(activity, ScrollerTestCase(activity),
+            toggleCausesRecompose = false, firstDrawCausesRecompose = true)
+    }
+
+    @Test
+    fun layout() {
+        benchmarkRule.measureLayoutPerf(activity, ScrollerTestCase(activity))
+    }
+
+    @Test
+    fun draw() {
+        benchmarkRule.measureDrawPerf(activity, ScrollerTestCase(activity))
+    }
+}
diff --git a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/view/AndroidNestedScrollViewBenchmark.kt b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/view/AndroidNestedScrollViewBenchmark.kt
new file mode 100644
index 0000000..54b1c4c
--- /dev/null
+++ b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/view/AndroidNestedScrollViewBenchmark.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2019 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.ui.benchmark.test.view
+
+import android.app.Activity
+import androidx.benchmark.junit4.BenchmarkRule
+import androidx.test.filters.LargeTest
+import androidx.test.rule.ActivityTestRule
+import androidx.ui.benchmark.measureDrawPerf
+import androidx.ui.benchmark.measureFirstDraw
+import androidx.ui.benchmark.measureFirstLayout
+import androidx.ui.benchmark.measureFirstMeasure
+import androidx.ui.benchmark.measureFirstSetContent
+import androidx.ui.benchmark.measureLayoutPerf
+import androidx.ui.benchmark.toggleStateMeasureDraw
+import androidx.ui.benchmark.toggleStateMeasureLayout
+import androidx.ui.benchmark.toggleStateMeasureMeasure
+import androidx.ui.test.DisableTransitions
+import androidx.ui.test.cases.view.AndroidNestedScrollViewTestCase
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+/**
+ * Benchmark that runs [AndroidNestedScrollViewTestCase].
+ */
+@LargeTest
+@RunWith(JUnit4::class)
+class AndroidNestedScrollViewBenchmark {
+
+    @get:Rule
+    val benchmarkRule = BenchmarkRule()
+
+    @get:Rule
+    val activityRule = ActivityTestRule(Activity::class.java)
+
+    @get:Rule
+    val disableAnimationRule = DisableTransitions()
+
+    private val activity: Activity get() = activityRule.activity
+
+    @Test
+    fun first_setContent() {
+        benchmarkRule.measureFirstSetContent(activity,
+            AndroidNestedScrollViewTestCase(activity))
+    }
+
+    @Test
+    fun first_measure() {
+        benchmarkRule.measureFirstMeasure(activity,
+            AndroidNestedScrollViewTestCase(activity))
+    }
+
+    @Test
+    fun first_layout() {
+        benchmarkRule.measureFirstLayout(activity,
+            AndroidNestedScrollViewTestCase(activity))
+    }
+
+    @Test
+    fun first_draw() {
+        benchmarkRule.measureFirstDraw(activity,
+            AndroidNestedScrollViewTestCase(activity))
+    }
+
+    @Test
+    fun changeScroll_measure() {
+        benchmarkRule.toggleStateMeasureMeasure(activity,
+            AndroidNestedScrollViewTestCase(activity))
+    }
+
+    @Test
+    fun changeScroll_layout() {
+        benchmarkRule.toggleStateMeasureLayout(activity,
+            AndroidNestedScrollViewTestCase(activity))
+    }
+
+    @Test
+    fun changeScroll_draw() {
+        benchmarkRule.toggleStateMeasureDraw(activity,
+            AndroidNestedScrollViewTestCase(activity))
+    }
+
+    @Test
+    fun layout() {
+        benchmarkRule.measureLayoutPerf(activity,
+            AndroidNestedScrollViewTestCase(activity))
+    }
+
+    @Test
+    fun draw() {
+        benchmarkRule.measureDrawPerf(activity,
+            AndroidNestedScrollViewTestCase(activity))
+    }
+}
\ No newline at end of file
diff --git a/ui/integration-tests/benchmark/src/main/java/androidx/ui/benchmark/BenchmarksExtensions.kt b/ui/integration-tests/benchmark/src/main/java/androidx/ui/benchmark/BenchmarksExtensions.kt
index bc6446b..6797ff0 100644
--- a/ui/integration-tests/benchmark/src/main/java/androidx/ui/benchmark/BenchmarksExtensions.kt
+++ b/ui/integration-tests/benchmark/src/main/java/androidx/ui/benchmark/BenchmarksExtensions.kt
@@ -20,12 +20,14 @@
 import android.view.View
 import androidx.benchmark.junit4.BenchmarkRule
 import androidx.benchmark.junit4.measureRepeated
+import androidx.compose.FrameManager
 import androidx.compose.disposeComposition
 import androidx.ui.test.AndroidTestCase
 import androidx.ui.test.ComposeTestCase
 import androidx.ui.test.TestCase
 import androidx.ui.test.ToggleableTestCase
 import androidx.ui.test.invalidateViews
+import androidx.ui.test.recomposeSyncAssert
 import androidx.ui.test.recomposeSyncAssertHadChanges
 import androidx.ui.test.recomposeSyncAssertNoChanges
 import androidx.ui.test.requestLayout
@@ -240,16 +242,17 @@
  */
 fun <T> BenchmarkRule.toggleStateMeasureMeasure(
     activity: Activity,
-    testCase: T
+    testCase: T,
+    toggleCausesRecompose: Boolean = true,
+    firstDrawCausesRecompose: Boolean = false
 ) where T : ComposeTestCase, T : ToggleableTestCase {
     activity.runOnUiThreadSync {
-        testCase.runToFirstDraw()
-        testCase.recomposeSyncAssertNoChanges()
+        runToFirstDraw(testCase, firstDrawCausesRecompose)
 
         measureRepeated {
             runWithTimingDisabled {
                 testCase.toggleState()
-                testCase.recomposeSyncAssertHadChanges()
+                testCase.recomposeSyncAssert(toggleCausesRecompose)
                 testCase.requestLayout()
             }
             testCase.measure()
@@ -263,16 +266,17 @@
  */
 fun <T> BenchmarkRule.toggleStateMeasureLayout(
     activity: Activity,
-    testCase: T
+    testCase: T,
+    toggleCausesRecompose: Boolean = true,
+    firstDrawCausesRecompose: Boolean = false
 ) where T : ComposeTestCase, T : ToggleableTestCase {
     activity.runOnUiThreadSync {
-        testCase.runToFirstDraw()
-        testCase.recomposeSyncAssertNoChanges()
+        runToFirstDraw(testCase, firstDrawCausesRecompose)
 
         measureRepeated {
             runWithTimingDisabled {
                 testCase.toggleState()
-                testCase.recomposeSyncAssertHadChanges()
+                testCase.recomposeSyncAssert(toggleCausesRecompose)
                 testCase.requestLayout()
                 testCase.measure()
             }
@@ -287,16 +291,17 @@
  */
 fun <T> BenchmarkRule.toggleStateMeasureDraw(
     activity: Activity,
-    testCase: T
+    testCase: T,
+    toggleCausesRecompose: Boolean = true,
+    firstDrawCausesRecompose: Boolean = false
 ) where T : ComposeTestCase, T : ToggleableTestCase {
     activity.runOnUiThreadSync {
-        testCase.runToFirstDraw()
-        testCase.recomposeSyncAssertNoChanges()
+        runToFirstDraw(testCase, firstDrawCausesRecompose)
 
         measureRepeated {
             runWithTimingDisabled {
                 testCase.toggleState()
-                testCase.recomposeSyncAssertHadChanges()
+                testCase.recomposeSyncAssert(toggleCausesRecompose)
                 testCase.requestLayout()
                 testCase.measure()
                 testCase.layout()
@@ -310,3 +315,84 @@
         activity.disposeComposition()
     }
 }
+
+/**
+ * Runs first draw on the test case and runs recomposition. Some layout/draw cycles
+ * cause recomposition changes ([firstDrawCausesRecompose]). Changes are expected only
+ * when [firstDrawCausesRecompose] is `true`.
+ */
+private fun <T> runToFirstDraw(
+    testCase: T,
+    firstDrawCausesRecompose: Boolean
+) where T : ComposeTestCase {
+    testCase.runToFirstDraw()
+    FrameManager.nextFrame()
+    testCase.recomposeSyncAssert(firstDrawCausesRecompose)
+}
+
+/**
+ *  Measures measure time of the hierarchy after changing a state.
+ */
+fun <T> BenchmarkRule.toggleStateMeasureMeasure(
+    activity: Activity,
+    testCase: T
+) where T : AndroidTestCase, T : ToggleableTestCase {
+    activity.runOnUiThreadSync {
+        testCase.runToFirstDraw()
+
+        measureRepeated {
+            runWithTimingDisabled {
+                testCase.toggleState()
+            }
+            testCase.measure()
+        }
+        activity.disposeComposition()
+    }
+}
+
+/**
+ *  Measures layout time of the hierarchy after changing a state.
+ */
+fun <T> BenchmarkRule.toggleStateMeasureLayout(
+    activity: Activity,
+    testCase: T
+) where T : AndroidTestCase, T : ToggleableTestCase {
+    activity.runOnUiThreadSync {
+        testCase.runToFirstDraw()
+
+        measureRepeated {
+            runWithTimingDisabled {
+                testCase.toggleState()
+                testCase.measure()
+            }
+            testCase.layout()
+        }
+        activity.disposeComposition()
+    }
+}
+
+/**
+ *  Measures draw time of the hierarchy after changing a state.
+ */
+fun <T> BenchmarkRule.toggleStateMeasureDraw(
+    activity: Activity,
+    testCase: T
+) where T : AndroidTestCase, T : ToggleableTestCase {
+    activity.runOnUiThreadSync {
+        testCase.runToFirstDraw()
+
+        measureRepeated {
+            runWithTimingDisabled {
+                testCase.toggleState()
+                testCase.measure()
+                testCase.layout()
+                testCase.prepareDraw()
+            }
+            testCase.draw()
+            runWithTimingDisabled {
+                testCase.finishDraw()
+            }
+        }
+        activity.disposeComposition()
+    }
+}
diff --git a/ui/integration-tests/test/build.gradle b/ui/integration-tests/test/build.gradle
index 2853179..e77af3a 100644
--- a/ui/integration-tests/test/build.gradle
+++ b/ui/integration-tests/test/build.gradle
@@ -57,7 +57,7 @@
     description = "UI Integration Tests"
 }
 
-android.defaultConfig.minSdkVersion 29 // RenderNode requires 29+
+android.defaultConfig.minSdkVersion 21
 
 tasks.withType(KotlinCompile).all {
     kotlinOptions {
diff --git a/ui/integration-tests/test/src/main/java/androidx/ui/test/TestCase.kt b/ui/integration-tests/test/src/main/java/androidx/ui/test/TestCase.kt
index c5297e2..2caa19d 100644
--- a/ui/integration-tests/test/src/main/java/androidx/ui/test/TestCase.kt
+++ b/ui/integration-tests/test/src/main/java/androidx/ui/test/TestCase.kt
@@ -16,33 +16,31 @@
 
 package androidx.ui.test
 
+import android.annotation.TargetApi
 import android.app.Activity
 import android.graphics.Bitmap
 import android.graphics.Canvas
 import android.graphics.Picture
 import android.graphics.RenderNode
+import android.os.Build
 import android.util.DisplayMetrics
 import android.view.View
 import android.view.ViewGroup
 import android.widget.ImageView
-import androidx.compose.Children
-import androidx.compose.Composable
 import androidx.compose.CompositionContext
 import androidx.compose.FrameManager
 import androidx.ui.core.AndroidCraneView
 import androidx.ui.core.ComponentNode
 import androidx.ui.core.DrawNode
-import androidx.ui.core.setContent
 import com.google.common.truth.Truth
 import org.junit.Assert
 
 abstract class TestCase(
     val activity: Activity
 ) {
-
     private val screenWithSpec: Int
     private val screenHeightSpec: Int
-    private val renderNode = RenderNode("test")
+    private val capture = if (SupportsRenderNode) RenderNodeCapture() else PictureCapture()
     private var canvas: Canvas? = null
 
     lateinit var view: ViewGroup
@@ -93,8 +91,7 @@
      * Do not measure this in benchmark.
      */
     fun prepareDraw() {
-        renderNode.setPosition(0, 0, view.width, view.height)
-        canvas = renderNode.beginRecording()
+        canvas = capture.beginRecording(view.width, view.height)
     }
 
     /**
@@ -108,7 +105,7 @@
      * Do not measure this in benchmark.
      */
     fun finishDraw() {
-        renderNode.endRecording()
+        capture.endRecording()
     }
 
     /**
@@ -126,6 +123,10 @@
     fun layout() {
         view.layout(view.left, view.top, view.right, view.bottom)
     }
+
+    companion object {
+        private val SupportsRenderNode = Build.VERSION.SDK_INT >= 29
+    }
 }
 
 abstract class AndroidTestCase(
@@ -133,7 +134,7 @@
 ) : TestCase(activity) {
 
     override fun setupContentInternal(activity: Activity) = createViewContent(activity)
-        .apply { activity.setContentView(this) }
+        .also { activity.setContentView(it) }
 
     abstract fun createViewContent(activity: Activity): ViewGroup
 }
@@ -203,22 +204,29 @@
  * Performs recomposition and asserts that there were some pending changes.
  */
 fun ComposeTestCase.recomposeSyncAssertHadChanges() {
-    val hadChanges = compositionContext.recomposeSync()
-    Assert.assertTrue(
-        "Expected pending changes on recomposition but there were none. Did " +
-                "you forget to call FrameManager.next()?", hadChanges
-    )
+    recomposeSyncAssert(expectingChanges = true)
 }
 
 /**
  * Performs recomposition and asserts that there were no pending changes.
  */
 fun ComposeTestCase.recomposeSyncAssertNoChanges() {
+    recomposeSyncAssert(expectingChanges = false)
+}
+
+/**
+ * Performs recomposition and asserts that there were or weren't pending changes based on
+ * [expectingChanges].
+ */
+fun ComposeTestCase.recomposeSyncAssert(expectingChanges: Boolean) {
+    val message = if (expectingChanges) {
+        "Expected pending changes on recomposition but there were none. Did " +
+                "you forget to call FrameManager.next()?"
+    } else {
+        "Expected no pending changes on recomposition but there were some."
+    }
     val hadChanges = compositionContext.recomposeSync()
-    Assert.assertFalse(
-        "Expected no pending changes on recomposition but there were some.",
-        hadChanges
-    )
+    Assert.assertEquals(message, expectingChanges, hadChanges)
 }
 
 /**
@@ -234,7 +242,16 @@
     view.draw(canvas)
     picture.endRecording()
     val imageView = ImageView(activity)
-    imageView.setImageBitmap(Bitmap.createBitmap(picture))
+    val bitmap: Bitmap
+    if (Build.VERSION.SDK_INT >= 28) {
+        bitmap = Bitmap.createBitmap(picture)
+    } else {
+        val width = picture.width.coerceAtLeast(1)
+        val height = picture.height.coerceAtLeast(1)
+        bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
+        Canvas(bitmap).drawPicture(picture)
+    }
+    imageView.setImageBitmap(bitmap)
     activity.setContentView(imageView)
 }
 
@@ -265,4 +282,38 @@
         }
     }
     return null
-}
\ No newline at end of file
+}
+
+// We must separate the use of RenderNode so that it isn't referenced in any
+// way on platforms that don't have it. This extracts RenderNode use to a
+// potentially unloaded class, RenderNodeCapture.
+private interface DrawCapture {
+    fun beginRecording(width: Int, height: Int): Canvas
+    fun endRecording()
+}
+
+@TargetApi(Build.VERSION_CODES.Q)
+private class RenderNodeCapture : DrawCapture {
+    private val renderNode = RenderNode("Test")
+
+    override fun beginRecording(width: Int, height: Int): Canvas {
+        renderNode.setPosition(0, 0, width, height)
+        return renderNode.beginRecording()
+    }
+
+    override fun endRecording() {
+        renderNode.endRecording()
+    }
+}
+
+private class PictureCapture : DrawCapture {
+    private val picture = Picture()
+
+    override fun beginRecording(width: Int, height: Int): Canvas {
+        return picture.beginRecording(width, height)
+    }
+
+    override fun endRecording() {
+        picture.endRecording()
+    }
+}
diff --git a/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/NestedScrollerTestCase.kt b/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/NestedScrollerTestCase.kt
new file mode 100644
index 0000000..97af4e8
--- /dev/null
+++ b/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/NestedScrollerTestCase.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2019 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.ui.test.cases
+
+import android.app.Activity
+import androidx.compose.composer
+import androidx.compose.Composable
+import androidx.compose.FrameManager
+import androidx.compose.memo
+import androidx.compose.unaryPlus
+import androidx.ui.core.Text
+import androidx.ui.core.WithDensity
+import androidx.ui.core.px
+import androidx.ui.core.setContent
+import androidx.ui.foundation.ColoredRect
+import androidx.ui.graphics.Color
+import androidx.ui.layout.Column
+import androidx.ui.layout.CrossAxisAlignment
+import androidx.ui.layout.FlexColumn
+import androidx.ui.layout.HorizontalScroller
+import androidx.ui.layout.Row
+import androidx.ui.layout.ScrollerPosition
+import androidx.ui.layout.VerticalScroller
+import androidx.ui.material.MaterialTheme
+import androidx.ui.material.surface.Surface
+import androidx.ui.test.ComposeTestCase
+import androidx.ui.test.ToggleableTestCase
+import androidx.ui.text.TextStyle
+import kotlin.random.Random
+
+/**
+ * Test case that puts many horizontal scrollers in a vertical scroller
+ */
+class NestedScrollerTestCase(
+    activity: Activity
+) : ComposeTestCase(activity), ToggleableTestCase {
+    private val scrollerPosition = ScrollerPosition()
+
+    override fun setComposeContent(activity: Activity) = activity.setContent {
+        MaterialTheme {
+            Surface {
+                VerticalScroller {
+                    Column {
+                        repeat(5) { index ->
+                            SquareRow(index == 0)
+                        }
+                    }
+                }
+            }
+        }
+    }!!
+
+    override fun toggleState() {
+        scrollerPosition.position = if (scrollerPosition.position == 0.px) 10.px else 0.px
+        FrameManager.nextFrame()
+    }
+
+    @Composable
+    fun SquareRow(useScrollerPosition: Boolean) {
+        val playStoreColor = Color(red = 0x00, green = 0x00, blue = 0x80)
+        val content = @Composable {
+            Row {
+                repeat(6) {
+                    WithDensity {
+                        FlexColumn(crossAxisAlignment = CrossAxisAlignment.Start) {
+                            val color = +memo {
+                                val red = Random.nextInt(256)
+                                val green = Random.nextInt(256)
+                                val blue = Random.nextInt(256)
+                                Color(red = red, green = green, blue = blue)
+                            }
+                            inflexible {
+                                ColoredRect(
+                                    width = 350.px.toDp(),
+                                    height = 350.px.toDp(),
+                                    color = color)
+                                Text(
+                                    text = "Some title",
+                                    style = TextStyle(Color.Black, 60.px.toSp())
+                                )
+                                Row(crossAxisAlignment = CrossAxisAlignment.Center) {
+                                    Text("3.5 ★", TextStyle(fontSize = 40.px.toSp()))
+                                    ColoredRect(
+                                        width = 40.px.toDp(),
+                                        height = 40.px.toDp(),
+                                        color = playStoreColor
+                                    )
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (useScrollerPosition) {
+            HorizontalScroller(scrollerPosition = scrollerPosition, child = content)
+        } else {
+            HorizontalScroller(child = content)
+        }
+    }
+}
diff --git a/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/ScrollerTestCase.kt b/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/ScrollerTestCase.kt
new file mode 100644
index 0000000..40d97a8
--- /dev/null
+++ b/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/ScrollerTestCase.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2019 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.ui.test.cases
+
+import android.app.Activity
+import androidx.compose.composer
+import androidx.compose.Composable
+import androidx.compose.CompositionContext
+import androidx.compose.FrameManager
+import androidx.compose.memo
+import androidx.compose.unaryPlus
+import androidx.ui.core.Draw
+import androidx.ui.core.dp
+import androidx.ui.core.px
+import androidx.ui.core.setContent
+import androidx.ui.core.toRect
+import androidx.ui.graphics.Color
+import androidx.ui.layout.Column
+import androidx.ui.layout.Container
+import androidx.ui.layout.CrossAxisAlignment
+import androidx.ui.layout.ScrollerPosition
+import androidx.ui.layout.VerticalScroller
+import androidx.ui.painting.Paint
+import androidx.ui.painting.PaintingStyle
+import androidx.ui.test.ComposeTestCase
+import androidx.ui.test.ToggleableTestCase
+
+/**
+ * Test case that puts a large number of boxes in a column in a vertical scroller to force scrolling.
+ */
+class ScrollerTestCase(
+    activity: Activity
+) : ComposeTestCase(activity), ToggleableTestCase {
+    private val scrollerPosition = ScrollerPosition()
+
+    override fun setComposeContent(activity: Activity): CompositionContext = activity.setContent {
+        VerticalScroller(
+            scrollerPosition = scrollerPosition
+        ) {
+            Column(crossAxisAlignment = CrossAxisAlignment.Start) {
+                for (green in 0..0xFF) {
+                    ColorStripe(0xFF, green, 0)
+                }
+                for (red in 0xFF downTo 0) {
+                    ColorStripe(red, 0xFF, 0)
+                }
+                for (blue in 0..0xFF) {
+                    ColorStripe(0, 0xFF, blue)
+                }
+                for (green in 0xFF downTo 0) {
+                    ColorStripe(0, green, 0xFF)
+                }
+                for (red in 0..0xFF) {
+                    ColorStripe(red, 0, 0xFF)
+                }
+                for (blue in 0xFF downTo 0) {
+                    ColorStripe(0xFF, 0, blue)
+                }
+            }
+        }
+    }!!
+
+    override fun toggleState() {
+        scrollerPosition.position = if (scrollerPosition.position == 0.px) 10.px else 0.px
+        FrameManager.nextFrame()
+    }
+
+    @Composable
+    fun ColorStripe(red: Int, green: Int, blue: Int) {
+        val paint = +memo { Paint() }
+        Container(height = 5.dp, width = 45.dp) {
+            Draw { canvas, parentSize ->
+                paint.color = Color(red = red, green = green, blue = blue)
+                paint.style = PaintingStyle.fill
+                canvas.drawRect(parentSize.toRect(), paint)
+            }
+        }
+    }
+}
diff --git a/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/view/AndroidCheckboxesInLinearLayoutTestCase.kt b/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/view/AndroidCheckboxesInLinearLayoutTestCase.kt
index 8941a79..03bd230 100644
--- a/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/view/AndroidCheckboxesInLinearLayoutTestCase.kt
+++ b/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/view/AndroidCheckboxesInLinearLayoutTestCase.kt
@@ -24,7 +24,7 @@
 import android.widget.TextView
 import androidx.ui.test.AndroidTestCase
 import androidx.ui.test.R
-import androidx.ui.test.TestCase
+import androidx.ui.test.cases.CheckboxesInRowsTestCase
 
 /**
  * Version of [CheckboxesInRowsTestCase] using Android views.
diff --git a/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/view/AndroidNestedScrollViewTestCase.kt b/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/view/AndroidNestedScrollViewTestCase.kt
new file mode 100644
index 0000000..8c4a119
--- /dev/null
+++ b/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/view/AndroidNestedScrollViewTestCase.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2019 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.ui.test.cases.view
+
+import android.app.Activity
+import android.view.View
+import android.view.ViewGroup
+import android.widget.HorizontalScrollView
+import androidx.ui.graphics.Color
+import androidx.ui.test.AndroidTestCase
+import androidx.ui.test.R
+import androidx.ui.test.ToggleableTestCase
+import androidx.ui.test.cases.NestedScrollerTestCase
+import kotlin.random.Random
+
+/**
+ * Version of [NestedScrollerTestCase] using Android views.
+ */
+class AndroidNestedScrollViewTestCase(
+    activity: Activity
+) : AndroidTestCase(activity), ToggleableTestCase {
+    lateinit var firstScrollView: HorizontalScrollView
+
+    override fun createViewContent(activity: Activity): ViewGroup {
+        val scrollView = activity.layoutInflater.inflate(R.layout.simple_store, null) as ViewGroup
+        visitImages(scrollView) { view ->
+            val color = Color(
+                red = Random.nextInt(256),
+                green = Random.nextInt(256),
+                blue = Random.nextInt(256)
+            ).toArgb()
+            view.setBackgroundColor(color)
+        }
+        firstScrollView = scrollView.findViewById(R.id.first_row)
+        return scrollView
+    }
+
+    fun visitImages(viewGroup: ViewGroup, block: (View) -> Unit) {
+        for (i in 0 until viewGroup.childCount) {
+            val child = viewGroup.getChildAt(i)
+            if (child is ViewGroup) {
+                visitImages(child, block)
+            } else if (child.id == R.id.item_image) {
+                block(child)
+            }
+        }
+    }
+
+    /**
+     * This scrolls the first HorizontalScrollView. Views are well optimized for this operation,
+     * so it is good to have a metric to compare against. Compose UI does more during scrolling,
+     * and it is important that it doesn't explode. This View example helps compare
+     * measure/layout/draw times for scrolling operations.
+     */
+    override fun toggleState() {
+        firstScrollView.scrollX = if (firstScrollView.scrollX == 0) 5 else 0
+    }
+}
diff --git a/ui/integration-tests/test/src/main/res/layout/simple_store.xml b/ui/integration-tests/test/src/main/res/layout/simple_store.xml
new file mode 100644
index 0000000..286711c
--- /dev/null
+++ b/ui/integration-tests/test/src/main/res/layout/simple_store.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+    <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"
+                  android:orientation="vertical">
+        <include layout="@layout/store_row" android:id="@+id/first_row"/>
+        <include layout="@layout/store_row"/>
+        <include layout="@layout/store_row"/>
+        <include layout="@layout/store_row"/>
+        <include layout="@layout/store_row"/>
+    </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/ui/integration-tests/test/src/main/res/layout/store_item.xml b/ui/integration-tests/test/src/main/res/layout/store_item.xml
new file mode 100644
index 0000000..f0ec68d
--- /dev/null
+++ b/ui/integration-tests/test/src/main/res/layout/store_item.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+    <!-- We use px instead of dip so that the benchmark is independent of
+         density -->
+    <View android:id="@+id/item_image"
+          android:layout_width="350px"
+          android:layout_height="350px"
+          android:background="#808"/>
+    <TextView android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:text="Some title"
+              android:textSize="60px"/>
+    <LinearLayout android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:orientation="horizontal">
+        <TextView android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:layout_gravity="center"
+                  android:text="3.5 ★" android:textSize="40px"/>
+        <View android:layout_width="40px"
+              android:layout_height="40px"
+              android:layout_gravity="center"
+              android:background="#008"/>
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/ui/integration-tests/test/src/main/res/layout/store_row.xml b/ui/integration-tests/test/src/main/res/layout/store_row.xml
new file mode 100644
index 0000000..65cbbb3
--- /dev/null
+++ b/ui/integration-tests/test/src/main/res/layout/store_row.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+                      android:layout_width="match_parent"
+                      android:layout_height="match_parent">
+    <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"
+                  android:orientation="horizontal">
+        <include layout="@layout/store_item"/>
+        <include layout="@layout/store_item"/>
+        <include layout="@layout/store_item"/>
+        <include layout="@layout/store_item"/>
+        <include layout="@layout/store_item"/>
+        <include layout="@layout/store_item"/>
+    </LinearLayout>
+</HorizontalScrollView>
\ No newline at end of file
diff --git a/ui/settings.gradle b/ui/settings.gradle
index 2063fef..0b3e8fb 100644
--- a/ui/settings.gradle
+++ b/ui/settings.gradle
@@ -55,10 +55,8 @@
 includeProject(":ui:ui-test", "ui-test")
 includeProject(":ui:ui-text", "ui-text")
 includeProject(":ui:ui-text:integration-tests:ui-text-demos", "ui-text/integration-tests/text-demos")
+includeProject(":ui:ui-tooling", "ui-tooling")
 includeProject(":ui:ui-vector", "ui-vector")
-includeProject(":compose:compose-runtime:integration-tests", "../compose/compose-runtime/integration-tests")
-includeProject(":compose:compose-runtime:integration-tests:android-tests", "../compose/compose-runtime/integration-tests/android-tests")
-
 
 /////////////////////////////
 //
diff --git a/ui/ui-android-text/src/main/java/androidx/text/TextLayout.kt b/ui/ui-android-text/src/main/java/androidx/text/TextLayout.kt
index f9e5c59..73709d0 100644
--- a/ui/ui-android-text/src/main/java/androidx/text/TextLayout.kt
+++ b/ui/ui-android-text/src/main/java/androidx/text/TextLayout.kt
@@ -86,9 +86,11 @@
         val frameworkTextDir = getTextDirectionHeuristic(textDirectionHeuristic)
         val boringMetrics = BoringLayoutCompat.isBoring(charSequence, textPaint, frameworkTextDir)
 
+        // TODO(haoyuchang): we didn't pass the TextDirection to Layout.getDesiredWidth(), check if
+        //  there is any behavior difference from
+        //  Layout.getWidthWithLimits(charSequence, start, end, paint, dir)
         maxIntrinsicWidth = boringMetrics?.width?.toFloat()
-                // we may need to getWidthWithLimits(maxWidth: Int, maxLines: Int)
-                ?: Layout.getDesiredWidth(charSequence, start, end, textPaint)
+            ?: Layout.getDesiredWidth(charSequence, start, end, textPaint)
 
         val finalWidth = width.toInt()
         val ellipsizeWidth = finalWidth
@@ -164,6 +166,12 @@
 
     fun getLineRight(lineIndex: Int): Float = layout.getLineRight(lineIndex)
 
+    fun getLineTop(line: Int): Float = layout.getLineTop(line).toFloat()
+
+    fun getLineBottom(line: Int): Float = layout.getLineBottom(line).toFloat()
+
+    fun getLineBaseline(line: Int): Float = layout.getLineBaseline(line).toFloat()
+
     fun getLineHeight(lineIndex: Int): Float =
         (layout.getLineBottom(lineIndex) - layout.getLineTop(lineIndex)).toFloat()
 
@@ -178,10 +186,6 @@
 
     fun getLineForOffset(offset: Int): Int = layout.getLineForOffset(offset)
 
-    fun getLineTop(line: Int): Float = layout.getLineTop(line).toFloat()
-
-    fun getLineBottom(line: Int): Float = layout.getLineBottom(line).toFloat()
-
     fun getSelectionPath(start: Int, end: Int, dest: Path) =
         layout.getSelectionPath(start, end, dest)
 
diff --git a/ui/ui-animation-core/build.gradle b/ui/ui-animation-core/build.gradle
index 0bbf704..a901e83 100644
--- a/ui/ui-animation-core/build.gradle
+++ b/ui/ui-animation-core/build.gradle
@@ -57,6 +57,6 @@
 
 tasks.withType(KotlinCompile).configureEach {
     kotlinOptions {
-        freeCompilerArgs += ["-Werror", "-Xuse-experimental=kotlin.Experimental"]
+        freeCompilerArgs += ["-Xuse-experimental=kotlin.Experimental"]
     }
 }
diff --git a/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/AnimatableSeekBar.kt b/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/AnimatableSeekBar.kt
index 7da4b16..373a945 100644
--- a/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/AnimatableSeekBar.kt
+++ b/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/AnimatableSeekBar.kt
@@ -28,7 +28,7 @@
 import androidx.ui.core.PxPosition
 import androidx.ui.core.Text
 import androidx.ui.core.dp
-import androidx.ui.core.gesture.DragGestureDetector
+import androidx.ui.core.gesture.RawDragGestureDetector
 import androidx.ui.core.gesture.DragObserver
 import androidx.ui.core.gesture.PressGestureDetector
 import androidx.ui.core.setContent
@@ -62,7 +62,7 @@
     @Composable
     fun MovingTargetExample() {
             val animValue = +animatedFloat(0f)
-            DragGestureDetector(canDrag = { true }, dragObserver = object : DragObserver {
+            RawDragGestureDetector(dragObserver = object : DragObserver {
                 override fun onDrag(dragDistance: PxPosition): PxPosition {
                     animValue.snapTo(animValue.targetValue + dragDistance.x.value)
                     return dragDistance
diff --git a/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/FancyScrolling.kt b/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/FancyScrolling.kt
index f76c445..4c98b42 100644
--- a/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/FancyScrolling.kt
+++ b/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/FancyScrolling.kt
@@ -35,7 +35,7 @@
 import androidx.ui.core.PxPosition
 import androidx.ui.core.Text
 import androidx.ui.core.dp
-import androidx.ui.core.gesture.DragGestureDetector
+import androidx.ui.core.gesture.RawDragGestureDetector
 import androidx.ui.core.gesture.DragObserver
 import androidx.ui.core.setContent
 import androidx.ui.core.sp
@@ -65,7 +65,7 @@
             }
             val animScroll = +animatedFloat(0f)
             val itemWidth = +state { 0f }
-            DragGestureDetector(canDrag = { true }, dragObserver = object : DragObserver {
+            RawDragGestureDetector(dragObserver = object : DragObserver {
                 override fun onDrag(dragDistance: PxPosition): PxPosition {
                     // Snap to new drag position
                     animScroll.snapTo(animScroll.value + dragDistance.x.value)
@@ -100,9 +100,9 @@
                         drawItems(canvas, scroll, width, parentSize.height.value, paint)
                     }
                 }
-                Layout(children = children, layoutBlock = { _, constraints ->
+                Layout(children) { _, constraints ->
                     layout(constraints.maxWidth, IntPx(1200)) {}
-                })
+                }
             }
         }
     }
diff --git a/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/HelloAnimationActivity.kt b/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/HelloAnimationActivity.kt
index ab11074..887043da 100644
--- a/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/HelloAnimationActivity.kt
+++ b/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/HelloAnimationActivity.kt
@@ -46,9 +46,9 @@
 
 @Composable
 fun HelloAnimation() {
-    Layout(children = { ColorRect() }, layoutBlock = { _, constraints ->
+    Layout(children = { ColorRect() }) { _, constraints ->
         layout(constraints.maxWidth, constraints.maxHeight) {}
-    })
+    }
 }
 
 private val background = ColorPropKey()
diff --git a/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/HelloGestureBasedAnimationActivity.kt b/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/HelloGestureBasedAnimationActivity.kt
index 868f2fa..a3e6399 100644
--- a/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/HelloGestureBasedAnimationActivity.kt
+++ b/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/HelloGestureBasedAnimationActivity.kt
@@ -75,9 +75,9 @@
                 DrawScaledRect(scale = state[scale], color = state[color])
             }
         }
-        Layout(children = children, layoutBlock = { _, constraints ->
+        Layout(children) { _, constraints ->
             layout(constraints.maxWidth, constraints.maxHeight) {}
-        })
+        }
     }
 }
 
diff --git a/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/SpringBackScrolling.kt b/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/SpringBackScrolling.kt
index 311cce6..a4f4214 100644
--- a/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/SpringBackScrolling.kt
+++ b/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/SpringBackScrolling.kt
@@ -35,7 +35,7 @@
 import androidx.ui.core.PxSize
 import androidx.ui.core.Text
 import androidx.ui.core.dp
-import androidx.ui.core.gesture.DragGestureDetector
+import androidx.ui.core.gesture.RawDragGestureDetector
 import androidx.ui.core.gesture.DragObserver
 import androidx.ui.core.setContent
 import androidx.ui.core.sp
@@ -66,7 +66,7 @@
             val animScroll = +animatedFloat(0f)
             val itemWidth = +state { 0f }
             var isFlinging = +state { false }
-            DragGestureDetector(canDrag = { true }, dragObserver = object : DragObserver {
+            RawDragGestureDetector(dragObserver = object : DragObserver {
                 override fun onDrag(dragDistance: PxPosition): PxPosition {
                     animScroll.snapTo(animScroll.targetValue + dragDistance.x.value)
                     return dragDistance
@@ -110,9 +110,9 @@
                         drawRects(canvas, parentSize, paint, animScroll.value)
                     }
                 }
-                Layout(children = children, layoutBlock = { _, constraints ->
+                Layout(children) { _, constraints ->
                     layout(constraints.maxWidth, IntPx(1200)) {}
-                })
+                }
             }
         }
     }
diff --git a/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/SwipeToDismiss.kt b/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/SwipeToDismiss.kt
index 72fe6ca..dd8968e0 100644
--- a/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/SwipeToDismiss.kt
+++ b/ui/ui-animation/integration-tests/animation-demos/src/main/java/androidx/ui/animation/demos/SwipeToDismiss.kt
@@ -36,7 +36,7 @@
 import androidx.ui.core.PxPosition
 import androidx.ui.core.Text
 import androidx.ui.core.dp
-import androidx.ui.core.gesture.DragGestureDetector
+import androidx.ui.core.gesture.RawDragGestureDetector
 import androidx.ui.core.gesture.DragObserver
 import androidx.ui.core.setContent
 import androidx.ui.core.sp
@@ -73,7 +73,7 @@
         val index = +state { 0 }
         val itemWidth = +state { 0f }
         val isFlinging = +state { false }
-        DragGestureDetector(canDrag = { true }, dragObserver = object : DragObserver {
+        RawDragGestureDetector(dragObserver = object : DragObserver {
             override fun onStart() {
                 itemBottom.setBounds(0f, height)
                 if (isFlinging.value && itemBottom.targetValue < 100f) {
@@ -136,9 +136,9 @@
             OnChildPositioned({ coordinates ->
                 itemWidth.value = coordinates.size.width.value * 2 / 3f
             }) {
-                Layout(children = children, layoutBlock = { _, constraints ->
-                layout(constraints.maxWidth, IntPx(height.toInt())) {}
-            })
+                Layout(children) { _, constraints ->
+                    layout(constraints.maxWidth, IntPx(height.toInt())) {}
+                }
             }
         }
     }
diff --git a/ui/ui-core/api/1.0.0-alpha01.txt b/ui/ui-core/api/1.0.0-alpha01.txt
index 195ecdf..0a4e798 100644
--- a/ui/ui-core/api/1.0.0-alpha01.txt
+++ b/ui/ui-core/api/1.0.0-alpha01.txt
@@ -31,6 +31,42 @@
 
 }
 
+package androidx.ui.autofill {
+
+  public interface Autofill {
+    method public void cancelAutofillForNode(androidx.ui.autofill.AutofillNode autofillNode);
+    method public void requestAutofillForNode(androidx.ui.autofill.AutofillNode autofillNode);
+  }
+
+  public final class AutofillNode {
+    ctor public AutofillNode(java.util.List<? extends androidx.ui.autofill.AutofillType> autofillTypes, android.graphics.Rect? boundingBox, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit>? onFill);
+    method public java.util.List<androidx.ui.autofill.AutofillType> component1();
+    method public android.graphics.Rect? component2();
+    method public kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit>? component3();
+    method public androidx.ui.autofill.AutofillNode copy(java.util.List<? extends androidx.ui.autofill.AutofillType> autofillTypes, android.graphics.Rect? boundingBox, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit>? onFill);
+    method public java.util.List<androidx.ui.autofill.AutofillType> getAutofillTypes();
+    method public android.graphics.Rect? getBoundingBox();
+    method public int getId();
+    method public kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit>? getOnFill();
+    method public void setBoundingBox(android.graphics.Rect? p);
+    property public final int id;
+  }
+
+  public final class AutofillTree {
+    ctor public AutofillTree();
+    method public java.util.Map<java.lang.Integer,androidx.ui.autofill.AutofillNode> getChildren();
+    method public kotlin.Unit? performAutofill(int id, String value);
+    method public operator void plusAssign(androidx.ui.autofill.AutofillNode autofillNode);
+    property public final java.util.Map<java.lang.Integer,androidx.ui.autofill.AutofillNode> children;
+  }
+
+  public enum AutofillType {
+    enum_constant public static final androidx.ui.autofill.AutofillType EmailAddress;
+    enum_constant public static final androidx.ui.autofill.AutofillType Name;
+  }
+
+}
+
 package androidx.ui.core {
 
   public final class Bounds {
@@ -396,6 +432,11 @@
     method public androidx.ui.core.IntPx getWidth();
   }
 
+  public enum LayoutDirection {
+    enum_constant public static final androidx.ui.core.LayoutDirection Ltr;
+    enum_constant public static final androidx.ui.core.LayoutDirection Rtl;
+  }
+
   public enum PointerEventPass {
     enum_constant public static final androidx.ui.core.PointerEventPass InitialDown;
     enum_constant public static final androidx.ui.core.PointerEventPass PostDown;
@@ -710,74 +751,6 @@
 
 }
 
-package androidx.ui.core.semantics {
-
-  public final class SemanticsAction<T> {
-    ctor public SemanticsAction(androidx.ui.core.semantics.SemanticsActionType<T> type, T handler);
-    method public androidx.ui.core.semantics.SemanticsActionType<T> component1();
-    method public T component2();
-    method public androidx.ui.core.semantics.SemanticsAction<T> copy(androidx.ui.core.semantics.SemanticsActionType<T> type, T handler);
-    method public T getHandler();
-    method public androidx.ui.core.semantics.SemanticsActionType<T> getType();
-    method public void invokeHandler(Object? args);
-  }
-
-  public final class SemanticsActionType<T> {
-    method public int getBitmask();
-    field public static final androidx.ui.core.semantics.SemanticsActionType.Companion! Companion;
-  }
-
-  public static final class SemanticsActionType.Companion {
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getCopy();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getCustomAction();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getCut();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getDecrease();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getDidGainAccessibilityFocus();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getDidLoseAccessibilityFocus();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getDismiss();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getIncrease();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getLongPress();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> getMoveCursorBackwardByCharacter();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> getMoveCursorBackwardByWord();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> getMoveCursorForwardByCharacter();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> getMoveCursorForwardByWord();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getPaste();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getScrollDown();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getScrollLeft();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getScrollRight();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getScrollUp();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<androidx.ui.text.TextSelection,kotlin.Unit>> getSetSelection();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getShowOnScreen();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getTap();
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Copy;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> CustomAction;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Cut;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Decrease;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> DidGainAccessibilityFocus;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> DidLoseAccessibilityFocus;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Dismiss;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Increase;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> LongPress;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> MoveCursorBackwardByCharacter;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> MoveCursorBackwardByWord;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> MoveCursorForwardByCharacter;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> MoveCursorForwardByWord;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Paste;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ScrollDown;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ScrollLeft;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ScrollRight;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ScrollUp;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<androidx.ui.text.TextSelection,kotlin.Unit>> SetSelection;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ShowOnScreen;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Tap;
-  }
-
-  public final class SemanticsActionsKt {
-    ctor public SemanticsActionsKt();
-  }
-
-}
-
 package androidx.ui.engine.geometry {
 
   public final class Offset implements androidx.ui.engine.geometry.OffsetBase {
@@ -1078,6 +1051,24 @@
 
 package androidx.ui.graphics {
 
+  public interface Brush {
+    method public void applyBrush(androidx.ui.painting.Paint p);
+  }
+
+  public final class BrushKt {
+    ctor public BrushKt();
+    method public static androidx.ui.graphics.LinearGradient HorizontalGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startX, androidx.ui.core.Px endX, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.Brush HorizontalGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startX, androidx.ui.core.Px endX, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.LinearGradient LinearGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.LinearGradient LinearGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.RadialGradient RadialGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.RadialGradient RadialGradient(androidx.ui.graphics.Color![] colors, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.LinearGradient VerticalGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startY, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.LinearGradient VerticalGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startY, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.Brush getEmptyBrush();
+    method public static androidx.ui.graphics.Brush obtainBrush(Object? brush);
+  }
+
   @AnyThread public final class Color {
     method public operator int compareTo(androidx.ui.graphics.Color other);
     method public androidx.ui.graphics.Color convert(androidx.ui.graphics.ColorSpace colorSpace);
@@ -1320,83 +1311,26 @@
     method public double getG();
   }
 
+  public final class LinearGradient implements androidx.ui.graphics.Brush {
+    method public void applyBrush(androidx.ui.painting.Paint p);
+    method public androidx.ui.graphics.LinearGradient copy(java.util.List<androidx.ui.graphics.Color> colors, java.util.List<java.lang.Float>? stops, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode);
+  }
+
+  public final class RadialGradient implements androidx.ui.graphics.Brush {
+    method public void applyBrush(androidx.ui.painting.Paint p);
+    method public androidx.ui.graphics.RadialGradient copy(java.util.List<androidx.ui.graphics.Color> colors, java.util.List<java.lang.Float>? stops, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode);
+  }
+
+  public final class SolidColor implements androidx.ui.graphics.Brush {
+    ctor public SolidColor(androidx.ui.graphics.Color value);
+    method public void applyBrush(androidx.ui.painting.Paint p);
+    method public androidx.ui.graphics.SolidColor copy(androidx.ui.graphics.Color value);
+  }
+
 }
 
 package androidx.ui.graphics.vectorgraphics {
 
-  public interface Brush {
-    method public void applyBrush(androidx.ui.painting.Paint p);
-  }
-
-  public final class BrushKt {
-    ctor public BrushKt();
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient HorizontalGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startX, androidx.ui.core.Px endX, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.Brush HorizontalGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startX, androidx.ui.core.Px endX, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient LinearGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient LinearGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.RadialGradient RadialGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.RadialGradient RadialGradient(androidx.ui.graphics.Color![] colors, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient VerticalGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startY, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient VerticalGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startY, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.Brush getEmptyBrush();
-    method public static androidx.ui.graphics.vectorgraphics.Brush obtainBrush(Object? brush);
-  }
-
-  public final class GroupComponent extends androidx.ui.graphics.vectorgraphics.VNode {
-    ctor public GroupComponent(String name);
-    ctor public GroupComponent();
-    method public void draw(androidx.ui.painting.Canvas canvas);
-    method public androidx.ui.graphics.vectorgraphics.PathNode![] getClipPathNodes();
-    method public String getName();
-    method public float getPivotX();
-    method public float getPivotY();
-    method public float getRotation();
-    method public float getScaleX();
-    method public float getScaleY();
-    method public int getSize();
-    method public float getTranslationX();
-    method public float getTranslationY();
-    method public void insertAt(int index, androidx.ui.graphics.vectorgraphics.VNode instance);
-    method public void move(int from, int to, int count);
-    method public void remove(int index, int count);
-    method public void setClipPathNodes(androidx.ui.graphics.vectorgraphics.PathNode![] value);
-    method public void setPivotX(float value);
-    method public void setPivotY(float value);
-    method public void setRotation(float value);
-    method public void setScaleX(float value);
-    method public void setScaleY(float value);
-    method public void setTranslationX(float value);
-    method public void setTranslationY(float value);
-    property public final androidx.ui.graphics.vectorgraphics.PathNode![] clipPathNodes;
-    property public final float pivotX;
-    property public final float pivotY;
-    property public final float rotation;
-    property public final float scaleX;
-    property public final float scaleY;
-    property public final int size;
-    property public final float translationX;
-    property public final float translationY;
-  }
-
-  public final class LinearGradient implements androidx.ui.graphics.vectorgraphics.Brush {
-    method public void applyBrush(androidx.ui.painting.Paint p);
-    method public java.util.List<androidx.ui.graphics.Color> component1();
-    method public java.util.List<java.lang.Float>? component2();
-    method public androidx.ui.core.Px component3();
-    method public androidx.ui.core.Px component4();
-    method public androidx.ui.core.Px component5();
-    method public androidx.ui.core.Px component6();
-    method public androidx.ui.painting.TileMode component7();
-    method public androidx.ui.graphics.vectorgraphics.LinearGradient copy(java.util.List<androidx.ui.graphics.Color> colors, java.util.List<java.lang.Float>? stops, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode);
-    method public java.util.List<androidx.ui.graphics.Color> getColors();
-    method public androidx.ui.core.Px getEndX();
-    method public androidx.ui.core.Px getEndY();
-    method public androidx.ui.core.Px getStartX();
-    method public androidx.ui.core.Px getStartY();
-    method public java.util.List<java.lang.Float>? getStops();
-    method public androidx.ui.painting.TileMode getTileMode();
-  }
-
   public final class PathBuilder {
     ctor public PathBuilder();
     method public androidx.ui.graphics.vectorgraphics.PathBuilder arcTo(float horizontalEllipseRadius, float verticalEllipseRadius, float theta, float largeArcFlag, float sweepFlag, float x1, float y1);
@@ -1450,44 +1384,6 @@
     method public static androidx.ui.graphics.vectorgraphics.PathCommand toPathCommand(char);
   }
 
-  public final class PathComponent extends androidx.ui.graphics.vectorgraphics.VNode {
-    ctor public PathComponent(String name);
-    method public void draw(androidx.ui.painting.Canvas canvas);
-    method public androidx.ui.graphics.vectorgraphics.Brush getFill();
-    method public float getFillAlpha();
-    method public String getName();
-    method public androidx.ui.graphics.vectorgraphics.PathNode![] getPathNodes();
-    method public androidx.ui.graphics.vectorgraphics.Brush getStroke();
-    method public float getStrokeAlpha();
-    method public androidx.ui.painting.StrokeCap getStrokeLineCap();
-    method public androidx.ui.painting.StrokeJoin getStrokeLineJoin();
-    method public float getStrokeLineMiter();
-    method public float getStrokeLineWidth();
-    method public void setFill(androidx.ui.graphics.vectorgraphics.Brush value);
-    method public void setFillAlpha(float value);
-    method public void setPathNodes(androidx.ui.graphics.vectorgraphics.PathNode![] value);
-    method public void setStroke(androidx.ui.graphics.vectorgraphics.Brush value);
-    method public void setStrokeAlpha(float value);
-    method public void setStrokeLineCap(androidx.ui.painting.StrokeCap value);
-    method public void setStrokeLineJoin(androidx.ui.painting.StrokeJoin value);
-    method public void setStrokeLineMiter(float value);
-    method public void setStrokeLineWidth(float value);
-    property public final androidx.ui.graphics.vectorgraphics.Brush fill;
-    property public final float fillAlpha;
-    property public final androidx.ui.graphics.vectorgraphics.PathNode![] pathNodes;
-    property public final androidx.ui.graphics.vectorgraphics.Brush stroke;
-    property public final float strokeAlpha;
-    property public final androidx.ui.painting.StrokeCap strokeLineCap;
-    property public final androidx.ui.painting.StrokeJoin strokeLineJoin;
-    property public final float strokeLineMiter;
-    property public final float strokeLineWidth;
-  }
-
-  public final class PathDelegate {
-    ctor public PathDelegate(kotlin.jvm.functions.Function1<? super androidx.ui.graphics.vectorgraphics.PathBuilder,kotlin.Unit> delegate);
-    method public kotlin.jvm.functions.Function1<androidx.ui.graphics.vectorgraphics.PathBuilder,kotlin.Unit> getDelegate();
-  }
-
   public final class PathNode {
     ctor public PathNode(androidx.ui.graphics.vectorgraphics.PathCommand command, float[] args);
     method public androidx.ui.graphics.vectorgraphics.PathCommand component1();
@@ -1515,60 +1411,6 @@
     ctor public PathParserKt();
   }
 
-  public final class RadialGradient implements androidx.ui.graphics.vectorgraphics.Brush {
-    method public void applyBrush(androidx.ui.painting.Paint p);
-    method public androidx.ui.graphics.vectorgraphics.RadialGradient copy(java.util.List<androidx.ui.graphics.Color> colors, java.util.List<java.lang.Float>? stops, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode);
-  }
-
-  public final class SolidColor implements androidx.ui.graphics.vectorgraphics.Brush {
-    ctor public SolidColor(androidx.ui.graphics.Color value);
-    method public void applyBrush(androidx.ui.painting.Paint p);
-    method public androidx.ui.graphics.vectorgraphics.SolidColor copy(androidx.ui.graphics.Color value);
-  }
-
-  public abstract sealed class VNode {
-    method public abstract void draw(androidx.ui.painting.Canvas canvas);
-  }
-
-  public final class VectorComponent extends androidx.ui.graphics.vectorgraphics.VNode {
-    ctor public VectorComponent(String name, float viewportWidth, float viewportHeight, androidx.ui.core.Px defaultWidth, androidx.ui.core.Px defaultHeight);
-    method public void draw(androidx.ui.painting.Canvas canvas);
-    method public androidx.ui.core.Px getDefaultHeight();
-    method public androidx.ui.core.Px getDefaultWidth();
-    method public String getName();
-    method public androidx.ui.graphics.vectorgraphics.GroupComponent getRoot();
-    method public int getSize();
-    method public float getViewportHeight();
-    method public float getViewportWidth();
-    method public void setDefaultHeight(androidx.ui.core.Px p);
-    method public void setDefaultWidth(androidx.ui.core.Px p);
-    method public void setViewportHeight(float p);
-    method public void setViewportWidth(float p);
-    property public final androidx.ui.graphics.vectorgraphics.GroupComponent root;
-    property public final int size;
-  }
-
-  public final class VectorKt {
-    ctor public VectorKt();
-    method public static androidx.ui.graphics.vectorgraphics.PathNode![] addPathNodes(String? pathStr);
-    method public static androidx.ui.graphics.vectorgraphics.PathNode![] createPath(Object? pathData);
-    method public static androidx.ui.painting.StrokeCap getDefaultStrokeLineCap();
-    method public static androidx.ui.painting.StrokeJoin getDefaultStrokeLineJoin();
-    method public static androidx.ui.graphics.vectorgraphics.PathNode![] getEmptyPath();
-    field public static final float DefaultAlpha = 1.0f;
-    field public static final String DefaultGroupName = "";
-    field public static final String DefaultPathName = "";
-    field public static final float DefaultPivotX = 0.0f;
-    field public static final float DefaultPivotY = 0.0f;
-    field public static final float DefaultRotation = 0.0f;
-    field public static final float DefaultScaleX = 1.0f;
-    field public static final float DefaultScaleY = 1.0f;
-    field public static final float DefaultStrokeLineMiter = 4.0f;
-    field public static final float DefaultStrokeLineWidth = 0.0f;
-    field public static final float DefaultTranslationX = 0.0f;
-    field public static final float DefaultTranslationY = 0.0f;
-  }
-
 }
 
 package androidx.ui.painting {
@@ -1920,6 +1762,31 @@
 
 }
 
+package androidx.ui.semantics {
+
+  public final class AccessibilityAction<T extends kotlin.Function<? extends kotlin.Unit>> {
+    ctor public AccessibilityAction(String? label, T action);
+    method public String? component1();
+    method public T component2();
+    method public androidx.ui.semantics.AccessibilityAction<T> copy(String? label, T action);
+    method public T getAction();
+    method public String? getLabel();
+  }
+
+  public class SemanticsPropertyKey<T> implements kotlin.properties.ReadWriteProperty<androidx.ui.semantics.SemanticsPropertyReceiver,T> {
+    ctor public SemanticsPropertyKey(String name);
+    method public final String getName();
+    method public final T! getValue(androidx.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property);
+    method public T! merge(T? existingValue, T? newValue);
+    method public final void setValue(androidx.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property, T? value);
+  }
+
+  public interface SemanticsPropertyReceiver {
+    method public operator <T> void set(androidx.ui.semantics.SemanticsPropertyKey<T> key, T? value);
+  }
+
+}
+
 package androidx.ui.temputils {
 
   public final class CoroutineUtilsKt {
diff --git a/ui/ui-core/api/api_lint.ignore b/ui/ui-core/api/api_lint.ignore
index c321320..35dd316 100644
--- a/ui/ui-core/api/api_lint.ignore
+++ b/ui/ui-core/api/api_lint.ignore
@@ -121,3 +121,85 @@
 
 MethodNameUnits: androidx.ui.core.Durations#inSeconds(androidx.ui.core.Duration):
     Returned time values must be in milliseconds, was `inSeconds`
+
+
+MissingNullability: androidx.ui.core.Constraints#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.core.Constraints`
+MissingNullability: androidx.ui.core.Dp#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.core.Dp`
+MissingNullability: androidx.ui.core.DpCubed#equals(Object) parameter #0:
+    Missing nullability on parameter `p` in method `equals`
+MissingNullability: androidx.ui.core.DpCubed#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.ui.core.DpInverse#equals(Object) parameter #0:
+    Missing nullability on parameter `p` in method `equals`
+MissingNullability: androidx.ui.core.DpInverse#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.ui.core.DpSquared#equals(Object) parameter #0:
+    Missing nullability on parameter `p` in method `equals`
+MissingNullability: androidx.ui.core.DpSquared#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.ui.core.Duration#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.core.Duration`
+MissingNullability: androidx.ui.core.IntPx#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.core.IntPx`
+MissingNullability: androidx.ui.core.Px#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.core.Px`
+MissingNullability: androidx.ui.core.PxCubed#equals(Object) parameter #0:
+    Missing nullability on parameter `p` in method `equals`
+MissingNullability: androidx.ui.core.PxCubed#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.ui.core.PxInverse#equals(Object) parameter #0:
+    Missing nullability on parameter `p` in method `equals`
+MissingNullability: androidx.ui.core.PxInverse#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.ui.core.PxKt#getMinDimension(androidx.ui.core.PxSize):
+    Missing nullability on method `getMinDimension` return
+MissingNullability: androidx.ui.core.PxPosition#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.core.PxPosition`
+MissingNullability: androidx.ui.core.PxSize#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.core.PxSize`
+MissingNullability: androidx.ui.core.PxSquared#equals(Object) parameter #0:
+    Missing nullability on parameter `p` in method `equals`
+MissingNullability: androidx.ui.core.PxSquared#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.ui.core.Sp#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.core.Sp`
+MissingNullability: androidx.ui.core.Velocity#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.core.Velocity`
+MissingNullability: androidx.ui.engine.geometry.Offset#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.engine.geometry.Offset`
+MissingNullability: androidx.ui.engine.geometry.RRect#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.engine.geometry.RRect`
+MissingNullability: androidx.ui.engine.geometry.Radius#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.engine.geometry.Radius`
+MissingNullability: androidx.ui.engine.geometry.Rect#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.engine.geometry.Rect`
+MissingNullability: androidx.ui.engine.geometry.Size#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.engine.geometry.Size`
+MissingNullability: androidx.ui.graphics.Color#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.graphics.Color`
+MissingNullability: androidx.ui.graphics.ColorSpace#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.graphics.ColorSpace`
+MissingNullability: androidx.ui.graphics.ColorSpace.Connector#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.graphics.ColorSpace.Connector`
+MissingNullability: androidx.ui.graphics.ColorSpace.Named#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.graphics.ColorSpace.Named`
+MissingNullability: androidx.ui.graphics.ColorSpace.Rgb#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.graphics.ColorSpace.Rgb`
+MissingNullability: androidx.ui.painting.Gradient#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.painting.Gradient`
+MissingNullability: androidx.ui.painting.MaskFilter#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.painting.MaskFilter`
+MissingNullability: androidx.ui.painting.Path#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.painting.Path`
+MissingNullability: androidx.ui.text.TextSelection#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.text.TextSelection`
+MissingNullability: androidx.ui.util.Float16#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.util.Float16`
+MissingNullability: androidx.ui.vectormath64.Matrix2#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.vectormath64.Matrix2`
+MissingNullability: androidx.ui.vectormath64.Matrix3#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.vectormath64.Matrix3`
+MissingNullability: androidx.ui.vectormath64.Matrix4#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.vectormath64.Matrix4`
diff --git a/ui/ui-core/api/current.txt b/ui/ui-core/api/current.txt
index 195ecdf..0a4e798 100644
--- a/ui/ui-core/api/current.txt
+++ b/ui/ui-core/api/current.txt
@@ -31,6 +31,42 @@
 
 }
 
+package androidx.ui.autofill {
+
+  public interface Autofill {
+    method public void cancelAutofillForNode(androidx.ui.autofill.AutofillNode autofillNode);
+    method public void requestAutofillForNode(androidx.ui.autofill.AutofillNode autofillNode);
+  }
+
+  public final class AutofillNode {
+    ctor public AutofillNode(java.util.List<? extends androidx.ui.autofill.AutofillType> autofillTypes, android.graphics.Rect? boundingBox, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit>? onFill);
+    method public java.util.List<androidx.ui.autofill.AutofillType> component1();
+    method public android.graphics.Rect? component2();
+    method public kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit>? component3();
+    method public androidx.ui.autofill.AutofillNode copy(java.util.List<? extends androidx.ui.autofill.AutofillType> autofillTypes, android.graphics.Rect? boundingBox, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit>? onFill);
+    method public java.util.List<androidx.ui.autofill.AutofillType> getAutofillTypes();
+    method public android.graphics.Rect? getBoundingBox();
+    method public int getId();
+    method public kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit>? getOnFill();
+    method public void setBoundingBox(android.graphics.Rect? p);
+    property public final int id;
+  }
+
+  public final class AutofillTree {
+    ctor public AutofillTree();
+    method public java.util.Map<java.lang.Integer,androidx.ui.autofill.AutofillNode> getChildren();
+    method public kotlin.Unit? performAutofill(int id, String value);
+    method public operator void plusAssign(androidx.ui.autofill.AutofillNode autofillNode);
+    property public final java.util.Map<java.lang.Integer,androidx.ui.autofill.AutofillNode> children;
+  }
+
+  public enum AutofillType {
+    enum_constant public static final androidx.ui.autofill.AutofillType EmailAddress;
+    enum_constant public static final androidx.ui.autofill.AutofillType Name;
+  }
+
+}
+
 package androidx.ui.core {
 
   public final class Bounds {
@@ -396,6 +432,11 @@
     method public androidx.ui.core.IntPx getWidth();
   }
 
+  public enum LayoutDirection {
+    enum_constant public static final androidx.ui.core.LayoutDirection Ltr;
+    enum_constant public static final androidx.ui.core.LayoutDirection Rtl;
+  }
+
   public enum PointerEventPass {
     enum_constant public static final androidx.ui.core.PointerEventPass InitialDown;
     enum_constant public static final androidx.ui.core.PointerEventPass PostDown;
@@ -710,74 +751,6 @@
 
 }
 
-package androidx.ui.core.semantics {
-
-  public final class SemanticsAction<T> {
-    ctor public SemanticsAction(androidx.ui.core.semantics.SemanticsActionType<T> type, T handler);
-    method public androidx.ui.core.semantics.SemanticsActionType<T> component1();
-    method public T component2();
-    method public androidx.ui.core.semantics.SemanticsAction<T> copy(androidx.ui.core.semantics.SemanticsActionType<T> type, T handler);
-    method public T getHandler();
-    method public androidx.ui.core.semantics.SemanticsActionType<T> getType();
-    method public void invokeHandler(Object? args);
-  }
-
-  public final class SemanticsActionType<T> {
-    method public int getBitmask();
-    field public static final androidx.ui.core.semantics.SemanticsActionType.Companion! Companion;
-  }
-
-  public static final class SemanticsActionType.Companion {
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getCopy();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getCustomAction();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getCut();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getDecrease();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getDidGainAccessibilityFocus();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getDidLoseAccessibilityFocus();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getDismiss();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getIncrease();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getLongPress();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> getMoveCursorBackwardByCharacter();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> getMoveCursorBackwardByWord();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> getMoveCursorForwardByCharacter();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> getMoveCursorForwardByWord();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getPaste();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getScrollDown();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getScrollLeft();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getScrollRight();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getScrollUp();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<androidx.ui.text.TextSelection,kotlin.Unit>> getSetSelection();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getShowOnScreen();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getTap();
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Copy;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> CustomAction;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Cut;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Decrease;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> DidGainAccessibilityFocus;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> DidLoseAccessibilityFocus;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Dismiss;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Increase;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> LongPress;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> MoveCursorBackwardByCharacter;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> MoveCursorBackwardByWord;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> MoveCursorForwardByCharacter;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> MoveCursorForwardByWord;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Paste;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ScrollDown;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ScrollLeft;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ScrollRight;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ScrollUp;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<androidx.ui.text.TextSelection,kotlin.Unit>> SetSelection;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ShowOnScreen;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Tap;
-  }
-
-  public final class SemanticsActionsKt {
-    ctor public SemanticsActionsKt();
-  }
-
-}
-
 package androidx.ui.engine.geometry {
 
   public final class Offset implements androidx.ui.engine.geometry.OffsetBase {
@@ -1078,6 +1051,24 @@
 
 package androidx.ui.graphics {
 
+  public interface Brush {
+    method public void applyBrush(androidx.ui.painting.Paint p);
+  }
+
+  public final class BrushKt {
+    ctor public BrushKt();
+    method public static androidx.ui.graphics.LinearGradient HorizontalGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startX, androidx.ui.core.Px endX, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.Brush HorizontalGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startX, androidx.ui.core.Px endX, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.LinearGradient LinearGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.LinearGradient LinearGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.RadialGradient RadialGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.RadialGradient RadialGradient(androidx.ui.graphics.Color![] colors, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.LinearGradient VerticalGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startY, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.LinearGradient VerticalGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startY, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.Brush getEmptyBrush();
+    method public static androidx.ui.graphics.Brush obtainBrush(Object? brush);
+  }
+
   @AnyThread public final class Color {
     method public operator int compareTo(androidx.ui.graphics.Color other);
     method public androidx.ui.graphics.Color convert(androidx.ui.graphics.ColorSpace colorSpace);
@@ -1320,83 +1311,26 @@
     method public double getG();
   }
 
+  public final class LinearGradient implements androidx.ui.graphics.Brush {
+    method public void applyBrush(androidx.ui.painting.Paint p);
+    method public androidx.ui.graphics.LinearGradient copy(java.util.List<androidx.ui.graphics.Color> colors, java.util.List<java.lang.Float>? stops, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode);
+  }
+
+  public final class RadialGradient implements androidx.ui.graphics.Brush {
+    method public void applyBrush(androidx.ui.painting.Paint p);
+    method public androidx.ui.graphics.RadialGradient copy(java.util.List<androidx.ui.graphics.Color> colors, java.util.List<java.lang.Float>? stops, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode);
+  }
+
+  public final class SolidColor implements androidx.ui.graphics.Brush {
+    ctor public SolidColor(androidx.ui.graphics.Color value);
+    method public void applyBrush(androidx.ui.painting.Paint p);
+    method public androidx.ui.graphics.SolidColor copy(androidx.ui.graphics.Color value);
+  }
+
 }
 
 package androidx.ui.graphics.vectorgraphics {
 
-  public interface Brush {
-    method public void applyBrush(androidx.ui.painting.Paint p);
-  }
-
-  public final class BrushKt {
-    ctor public BrushKt();
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient HorizontalGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startX, androidx.ui.core.Px endX, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.Brush HorizontalGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startX, androidx.ui.core.Px endX, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient LinearGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient LinearGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.RadialGradient RadialGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.RadialGradient RadialGradient(androidx.ui.graphics.Color![] colors, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient VerticalGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startY, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient VerticalGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startY, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.Brush getEmptyBrush();
-    method public static androidx.ui.graphics.vectorgraphics.Brush obtainBrush(Object? brush);
-  }
-
-  public final class GroupComponent extends androidx.ui.graphics.vectorgraphics.VNode {
-    ctor public GroupComponent(String name);
-    ctor public GroupComponent();
-    method public void draw(androidx.ui.painting.Canvas canvas);
-    method public androidx.ui.graphics.vectorgraphics.PathNode![] getClipPathNodes();
-    method public String getName();
-    method public float getPivotX();
-    method public float getPivotY();
-    method public float getRotation();
-    method public float getScaleX();
-    method public float getScaleY();
-    method public int getSize();
-    method public float getTranslationX();
-    method public float getTranslationY();
-    method public void insertAt(int index, androidx.ui.graphics.vectorgraphics.VNode instance);
-    method public void move(int from, int to, int count);
-    method public void remove(int index, int count);
-    method public void setClipPathNodes(androidx.ui.graphics.vectorgraphics.PathNode![] value);
-    method public void setPivotX(float value);
-    method public void setPivotY(float value);
-    method public void setRotation(float value);
-    method public void setScaleX(float value);
-    method public void setScaleY(float value);
-    method public void setTranslationX(float value);
-    method public void setTranslationY(float value);
-    property public final androidx.ui.graphics.vectorgraphics.PathNode![] clipPathNodes;
-    property public final float pivotX;
-    property public final float pivotY;
-    property public final float rotation;
-    property public final float scaleX;
-    property public final float scaleY;
-    property public final int size;
-    property public final float translationX;
-    property public final float translationY;
-  }
-
-  public final class LinearGradient implements androidx.ui.graphics.vectorgraphics.Brush {
-    method public void applyBrush(androidx.ui.painting.Paint p);
-    method public java.util.List<androidx.ui.graphics.Color> component1();
-    method public java.util.List<java.lang.Float>? component2();
-    method public androidx.ui.core.Px component3();
-    method public androidx.ui.core.Px component4();
-    method public androidx.ui.core.Px component5();
-    method public androidx.ui.core.Px component6();
-    method public androidx.ui.painting.TileMode component7();
-    method public androidx.ui.graphics.vectorgraphics.LinearGradient copy(java.util.List<androidx.ui.graphics.Color> colors, java.util.List<java.lang.Float>? stops, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode);
-    method public java.util.List<androidx.ui.graphics.Color> getColors();
-    method public androidx.ui.core.Px getEndX();
-    method public androidx.ui.core.Px getEndY();
-    method public androidx.ui.core.Px getStartX();
-    method public androidx.ui.core.Px getStartY();
-    method public java.util.List<java.lang.Float>? getStops();
-    method public androidx.ui.painting.TileMode getTileMode();
-  }
-
   public final class PathBuilder {
     ctor public PathBuilder();
     method public androidx.ui.graphics.vectorgraphics.PathBuilder arcTo(float horizontalEllipseRadius, float verticalEllipseRadius, float theta, float largeArcFlag, float sweepFlag, float x1, float y1);
@@ -1450,44 +1384,6 @@
     method public static androidx.ui.graphics.vectorgraphics.PathCommand toPathCommand(char);
   }
 
-  public final class PathComponent extends androidx.ui.graphics.vectorgraphics.VNode {
-    ctor public PathComponent(String name);
-    method public void draw(androidx.ui.painting.Canvas canvas);
-    method public androidx.ui.graphics.vectorgraphics.Brush getFill();
-    method public float getFillAlpha();
-    method public String getName();
-    method public androidx.ui.graphics.vectorgraphics.PathNode![] getPathNodes();
-    method public androidx.ui.graphics.vectorgraphics.Brush getStroke();
-    method public float getStrokeAlpha();
-    method public androidx.ui.painting.StrokeCap getStrokeLineCap();
-    method public androidx.ui.painting.StrokeJoin getStrokeLineJoin();
-    method public float getStrokeLineMiter();
-    method public float getStrokeLineWidth();
-    method public void setFill(androidx.ui.graphics.vectorgraphics.Brush value);
-    method public void setFillAlpha(float value);
-    method public void setPathNodes(androidx.ui.graphics.vectorgraphics.PathNode![] value);
-    method public void setStroke(androidx.ui.graphics.vectorgraphics.Brush value);
-    method public void setStrokeAlpha(float value);
-    method public void setStrokeLineCap(androidx.ui.painting.StrokeCap value);
-    method public void setStrokeLineJoin(androidx.ui.painting.StrokeJoin value);
-    method public void setStrokeLineMiter(float value);
-    method public void setStrokeLineWidth(float value);
-    property public final androidx.ui.graphics.vectorgraphics.Brush fill;
-    property public final float fillAlpha;
-    property public final androidx.ui.graphics.vectorgraphics.PathNode![] pathNodes;
-    property public final androidx.ui.graphics.vectorgraphics.Brush stroke;
-    property public final float strokeAlpha;
-    property public final androidx.ui.painting.StrokeCap strokeLineCap;
-    property public final androidx.ui.painting.StrokeJoin strokeLineJoin;
-    property public final float strokeLineMiter;
-    property public final float strokeLineWidth;
-  }
-
-  public final class PathDelegate {
-    ctor public PathDelegate(kotlin.jvm.functions.Function1<? super androidx.ui.graphics.vectorgraphics.PathBuilder,kotlin.Unit> delegate);
-    method public kotlin.jvm.functions.Function1<androidx.ui.graphics.vectorgraphics.PathBuilder,kotlin.Unit> getDelegate();
-  }
-
   public final class PathNode {
     ctor public PathNode(androidx.ui.graphics.vectorgraphics.PathCommand command, float[] args);
     method public androidx.ui.graphics.vectorgraphics.PathCommand component1();
@@ -1515,60 +1411,6 @@
     ctor public PathParserKt();
   }
 
-  public final class RadialGradient implements androidx.ui.graphics.vectorgraphics.Brush {
-    method public void applyBrush(androidx.ui.painting.Paint p);
-    method public androidx.ui.graphics.vectorgraphics.RadialGradient copy(java.util.List<androidx.ui.graphics.Color> colors, java.util.List<java.lang.Float>? stops, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode);
-  }
-
-  public final class SolidColor implements androidx.ui.graphics.vectorgraphics.Brush {
-    ctor public SolidColor(androidx.ui.graphics.Color value);
-    method public void applyBrush(androidx.ui.painting.Paint p);
-    method public androidx.ui.graphics.vectorgraphics.SolidColor copy(androidx.ui.graphics.Color value);
-  }
-
-  public abstract sealed class VNode {
-    method public abstract void draw(androidx.ui.painting.Canvas canvas);
-  }
-
-  public final class VectorComponent extends androidx.ui.graphics.vectorgraphics.VNode {
-    ctor public VectorComponent(String name, float viewportWidth, float viewportHeight, androidx.ui.core.Px defaultWidth, androidx.ui.core.Px defaultHeight);
-    method public void draw(androidx.ui.painting.Canvas canvas);
-    method public androidx.ui.core.Px getDefaultHeight();
-    method public androidx.ui.core.Px getDefaultWidth();
-    method public String getName();
-    method public androidx.ui.graphics.vectorgraphics.GroupComponent getRoot();
-    method public int getSize();
-    method public float getViewportHeight();
-    method public float getViewportWidth();
-    method public void setDefaultHeight(androidx.ui.core.Px p);
-    method public void setDefaultWidth(androidx.ui.core.Px p);
-    method public void setViewportHeight(float p);
-    method public void setViewportWidth(float p);
-    property public final androidx.ui.graphics.vectorgraphics.GroupComponent root;
-    property public final int size;
-  }
-
-  public final class VectorKt {
-    ctor public VectorKt();
-    method public static androidx.ui.graphics.vectorgraphics.PathNode![] addPathNodes(String? pathStr);
-    method public static androidx.ui.graphics.vectorgraphics.PathNode![] createPath(Object? pathData);
-    method public static androidx.ui.painting.StrokeCap getDefaultStrokeLineCap();
-    method public static androidx.ui.painting.StrokeJoin getDefaultStrokeLineJoin();
-    method public static androidx.ui.graphics.vectorgraphics.PathNode![] getEmptyPath();
-    field public static final float DefaultAlpha = 1.0f;
-    field public static final String DefaultGroupName = "";
-    field public static final String DefaultPathName = "";
-    field public static final float DefaultPivotX = 0.0f;
-    field public static final float DefaultPivotY = 0.0f;
-    field public static final float DefaultRotation = 0.0f;
-    field public static final float DefaultScaleX = 1.0f;
-    field public static final float DefaultScaleY = 1.0f;
-    field public static final float DefaultStrokeLineMiter = 4.0f;
-    field public static final float DefaultStrokeLineWidth = 0.0f;
-    field public static final float DefaultTranslationX = 0.0f;
-    field public static final float DefaultTranslationY = 0.0f;
-  }
-
 }
 
 package androidx.ui.painting {
@@ -1920,6 +1762,31 @@
 
 }
 
+package androidx.ui.semantics {
+
+  public final class AccessibilityAction<T extends kotlin.Function<? extends kotlin.Unit>> {
+    ctor public AccessibilityAction(String? label, T action);
+    method public String? component1();
+    method public T component2();
+    method public androidx.ui.semantics.AccessibilityAction<T> copy(String? label, T action);
+    method public T getAction();
+    method public String? getLabel();
+  }
+
+  public class SemanticsPropertyKey<T> implements kotlin.properties.ReadWriteProperty<androidx.ui.semantics.SemanticsPropertyReceiver,T> {
+    ctor public SemanticsPropertyKey(String name);
+    method public final String getName();
+    method public final T! getValue(androidx.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property);
+    method public T! merge(T? existingValue, T? newValue);
+    method public final void setValue(androidx.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property, T? value);
+  }
+
+  public interface SemanticsPropertyReceiver {
+    method public operator <T> void set(androidx.ui.semantics.SemanticsPropertyKey<T> key, T? value);
+  }
+
+}
+
 package androidx.ui.temputils {
 
   public final class CoroutineUtilsKt {
diff --git a/ui/ui-core/api/restricted_1.0.0-alpha01.txt b/ui/ui-core/api/restricted_1.0.0-alpha01.txt
index 195ecdf..0a4e798 100644
--- a/ui/ui-core/api/restricted_1.0.0-alpha01.txt
+++ b/ui/ui-core/api/restricted_1.0.0-alpha01.txt
@@ -31,6 +31,42 @@
 
 }
 
+package androidx.ui.autofill {
+
+  public interface Autofill {
+    method public void cancelAutofillForNode(androidx.ui.autofill.AutofillNode autofillNode);
+    method public void requestAutofillForNode(androidx.ui.autofill.AutofillNode autofillNode);
+  }
+
+  public final class AutofillNode {
+    ctor public AutofillNode(java.util.List<? extends androidx.ui.autofill.AutofillType> autofillTypes, android.graphics.Rect? boundingBox, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit>? onFill);
+    method public java.util.List<androidx.ui.autofill.AutofillType> component1();
+    method public android.graphics.Rect? component2();
+    method public kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit>? component3();
+    method public androidx.ui.autofill.AutofillNode copy(java.util.List<? extends androidx.ui.autofill.AutofillType> autofillTypes, android.graphics.Rect? boundingBox, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit>? onFill);
+    method public java.util.List<androidx.ui.autofill.AutofillType> getAutofillTypes();
+    method public android.graphics.Rect? getBoundingBox();
+    method public int getId();
+    method public kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit>? getOnFill();
+    method public void setBoundingBox(android.graphics.Rect? p);
+    property public final int id;
+  }
+
+  public final class AutofillTree {
+    ctor public AutofillTree();
+    method public java.util.Map<java.lang.Integer,androidx.ui.autofill.AutofillNode> getChildren();
+    method public kotlin.Unit? performAutofill(int id, String value);
+    method public operator void plusAssign(androidx.ui.autofill.AutofillNode autofillNode);
+    property public final java.util.Map<java.lang.Integer,androidx.ui.autofill.AutofillNode> children;
+  }
+
+  public enum AutofillType {
+    enum_constant public static final androidx.ui.autofill.AutofillType EmailAddress;
+    enum_constant public static final androidx.ui.autofill.AutofillType Name;
+  }
+
+}
+
 package androidx.ui.core {
 
   public final class Bounds {
@@ -396,6 +432,11 @@
     method public androidx.ui.core.IntPx getWidth();
   }
 
+  public enum LayoutDirection {
+    enum_constant public static final androidx.ui.core.LayoutDirection Ltr;
+    enum_constant public static final androidx.ui.core.LayoutDirection Rtl;
+  }
+
   public enum PointerEventPass {
     enum_constant public static final androidx.ui.core.PointerEventPass InitialDown;
     enum_constant public static final androidx.ui.core.PointerEventPass PostDown;
@@ -710,74 +751,6 @@
 
 }
 
-package androidx.ui.core.semantics {
-
-  public final class SemanticsAction<T> {
-    ctor public SemanticsAction(androidx.ui.core.semantics.SemanticsActionType<T> type, T handler);
-    method public androidx.ui.core.semantics.SemanticsActionType<T> component1();
-    method public T component2();
-    method public androidx.ui.core.semantics.SemanticsAction<T> copy(androidx.ui.core.semantics.SemanticsActionType<T> type, T handler);
-    method public T getHandler();
-    method public androidx.ui.core.semantics.SemanticsActionType<T> getType();
-    method public void invokeHandler(Object? args);
-  }
-
-  public final class SemanticsActionType<T> {
-    method public int getBitmask();
-    field public static final androidx.ui.core.semantics.SemanticsActionType.Companion! Companion;
-  }
-
-  public static final class SemanticsActionType.Companion {
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getCopy();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getCustomAction();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getCut();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getDecrease();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getDidGainAccessibilityFocus();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getDidLoseAccessibilityFocus();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getDismiss();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getIncrease();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getLongPress();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> getMoveCursorBackwardByCharacter();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> getMoveCursorBackwardByWord();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> getMoveCursorForwardByCharacter();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> getMoveCursorForwardByWord();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getPaste();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getScrollDown();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getScrollLeft();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getScrollRight();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getScrollUp();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<androidx.ui.text.TextSelection,kotlin.Unit>> getSetSelection();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getShowOnScreen();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getTap();
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Copy;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> CustomAction;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Cut;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Decrease;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> DidGainAccessibilityFocus;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> DidLoseAccessibilityFocus;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Dismiss;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Increase;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> LongPress;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> MoveCursorBackwardByCharacter;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> MoveCursorBackwardByWord;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> MoveCursorForwardByCharacter;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> MoveCursorForwardByWord;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Paste;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ScrollDown;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ScrollLeft;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ScrollRight;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ScrollUp;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<androidx.ui.text.TextSelection,kotlin.Unit>> SetSelection;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ShowOnScreen;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Tap;
-  }
-
-  public final class SemanticsActionsKt {
-    ctor public SemanticsActionsKt();
-  }
-
-}
-
 package androidx.ui.engine.geometry {
 
   public final class Offset implements androidx.ui.engine.geometry.OffsetBase {
@@ -1078,6 +1051,24 @@
 
 package androidx.ui.graphics {
 
+  public interface Brush {
+    method public void applyBrush(androidx.ui.painting.Paint p);
+  }
+
+  public final class BrushKt {
+    ctor public BrushKt();
+    method public static androidx.ui.graphics.LinearGradient HorizontalGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startX, androidx.ui.core.Px endX, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.Brush HorizontalGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startX, androidx.ui.core.Px endX, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.LinearGradient LinearGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.LinearGradient LinearGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.RadialGradient RadialGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.RadialGradient RadialGradient(androidx.ui.graphics.Color![] colors, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.LinearGradient VerticalGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startY, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.LinearGradient VerticalGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startY, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.Brush getEmptyBrush();
+    method public static androidx.ui.graphics.Brush obtainBrush(Object? brush);
+  }
+
   @AnyThread public final class Color {
     method public operator int compareTo(androidx.ui.graphics.Color other);
     method public androidx.ui.graphics.Color convert(androidx.ui.graphics.ColorSpace colorSpace);
@@ -1320,83 +1311,26 @@
     method public double getG();
   }
 
+  public final class LinearGradient implements androidx.ui.graphics.Brush {
+    method public void applyBrush(androidx.ui.painting.Paint p);
+    method public androidx.ui.graphics.LinearGradient copy(java.util.List<androidx.ui.graphics.Color> colors, java.util.List<java.lang.Float>? stops, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode);
+  }
+
+  public final class RadialGradient implements androidx.ui.graphics.Brush {
+    method public void applyBrush(androidx.ui.painting.Paint p);
+    method public androidx.ui.graphics.RadialGradient copy(java.util.List<androidx.ui.graphics.Color> colors, java.util.List<java.lang.Float>? stops, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode);
+  }
+
+  public final class SolidColor implements androidx.ui.graphics.Brush {
+    ctor public SolidColor(androidx.ui.graphics.Color value);
+    method public void applyBrush(androidx.ui.painting.Paint p);
+    method public androidx.ui.graphics.SolidColor copy(androidx.ui.graphics.Color value);
+  }
+
 }
 
 package androidx.ui.graphics.vectorgraphics {
 
-  public interface Brush {
-    method public void applyBrush(androidx.ui.painting.Paint p);
-  }
-
-  public final class BrushKt {
-    ctor public BrushKt();
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient HorizontalGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startX, androidx.ui.core.Px endX, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.Brush HorizontalGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startX, androidx.ui.core.Px endX, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient LinearGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient LinearGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.RadialGradient RadialGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.RadialGradient RadialGradient(androidx.ui.graphics.Color![] colors, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient VerticalGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startY, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient VerticalGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startY, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.Brush getEmptyBrush();
-    method public static androidx.ui.graphics.vectorgraphics.Brush obtainBrush(Object? brush);
-  }
-
-  public final class GroupComponent extends androidx.ui.graphics.vectorgraphics.VNode {
-    ctor public GroupComponent(String name);
-    ctor public GroupComponent();
-    method public void draw(androidx.ui.painting.Canvas canvas);
-    method public androidx.ui.graphics.vectorgraphics.PathNode![] getClipPathNodes();
-    method public String getName();
-    method public float getPivotX();
-    method public float getPivotY();
-    method public float getRotation();
-    method public float getScaleX();
-    method public float getScaleY();
-    method public int getSize();
-    method public float getTranslationX();
-    method public float getTranslationY();
-    method public void insertAt(int index, androidx.ui.graphics.vectorgraphics.VNode instance);
-    method public void move(int from, int to, int count);
-    method public void remove(int index, int count);
-    method public void setClipPathNodes(androidx.ui.graphics.vectorgraphics.PathNode![] value);
-    method public void setPivotX(float value);
-    method public void setPivotY(float value);
-    method public void setRotation(float value);
-    method public void setScaleX(float value);
-    method public void setScaleY(float value);
-    method public void setTranslationX(float value);
-    method public void setTranslationY(float value);
-    property public final androidx.ui.graphics.vectorgraphics.PathNode![] clipPathNodes;
-    property public final float pivotX;
-    property public final float pivotY;
-    property public final float rotation;
-    property public final float scaleX;
-    property public final float scaleY;
-    property public final int size;
-    property public final float translationX;
-    property public final float translationY;
-  }
-
-  public final class LinearGradient implements androidx.ui.graphics.vectorgraphics.Brush {
-    method public void applyBrush(androidx.ui.painting.Paint p);
-    method public java.util.List<androidx.ui.graphics.Color> component1();
-    method public java.util.List<java.lang.Float>? component2();
-    method public androidx.ui.core.Px component3();
-    method public androidx.ui.core.Px component4();
-    method public androidx.ui.core.Px component5();
-    method public androidx.ui.core.Px component6();
-    method public androidx.ui.painting.TileMode component7();
-    method public androidx.ui.graphics.vectorgraphics.LinearGradient copy(java.util.List<androidx.ui.graphics.Color> colors, java.util.List<java.lang.Float>? stops, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode);
-    method public java.util.List<androidx.ui.graphics.Color> getColors();
-    method public androidx.ui.core.Px getEndX();
-    method public androidx.ui.core.Px getEndY();
-    method public androidx.ui.core.Px getStartX();
-    method public androidx.ui.core.Px getStartY();
-    method public java.util.List<java.lang.Float>? getStops();
-    method public androidx.ui.painting.TileMode getTileMode();
-  }
-
   public final class PathBuilder {
     ctor public PathBuilder();
     method public androidx.ui.graphics.vectorgraphics.PathBuilder arcTo(float horizontalEllipseRadius, float verticalEllipseRadius, float theta, float largeArcFlag, float sweepFlag, float x1, float y1);
@@ -1450,44 +1384,6 @@
     method public static androidx.ui.graphics.vectorgraphics.PathCommand toPathCommand(char);
   }
 
-  public final class PathComponent extends androidx.ui.graphics.vectorgraphics.VNode {
-    ctor public PathComponent(String name);
-    method public void draw(androidx.ui.painting.Canvas canvas);
-    method public androidx.ui.graphics.vectorgraphics.Brush getFill();
-    method public float getFillAlpha();
-    method public String getName();
-    method public androidx.ui.graphics.vectorgraphics.PathNode![] getPathNodes();
-    method public androidx.ui.graphics.vectorgraphics.Brush getStroke();
-    method public float getStrokeAlpha();
-    method public androidx.ui.painting.StrokeCap getStrokeLineCap();
-    method public androidx.ui.painting.StrokeJoin getStrokeLineJoin();
-    method public float getStrokeLineMiter();
-    method public float getStrokeLineWidth();
-    method public void setFill(androidx.ui.graphics.vectorgraphics.Brush value);
-    method public void setFillAlpha(float value);
-    method public void setPathNodes(androidx.ui.graphics.vectorgraphics.PathNode![] value);
-    method public void setStroke(androidx.ui.graphics.vectorgraphics.Brush value);
-    method public void setStrokeAlpha(float value);
-    method public void setStrokeLineCap(androidx.ui.painting.StrokeCap value);
-    method public void setStrokeLineJoin(androidx.ui.painting.StrokeJoin value);
-    method public void setStrokeLineMiter(float value);
-    method public void setStrokeLineWidth(float value);
-    property public final androidx.ui.graphics.vectorgraphics.Brush fill;
-    property public final float fillAlpha;
-    property public final androidx.ui.graphics.vectorgraphics.PathNode![] pathNodes;
-    property public final androidx.ui.graphics.vectorgraphics.Brush stroke;
-    property public final float strokeAlpha;
-    property public final androidx.ui.painting.StrokeCap strokeLineCap;
-    property public final androidx.ui.painting.StrokeJoin strokeLineJoin;
-    property public final float strokeLineMiter;
-    property public final float strokeLineWidth;
-  }
-
-  public final class PathDelegate {
-    ctor public PathDelegate(kotlin.jvm.functions.Function1<? super androidx.ui.graphics.vectorgraphics.PathBuilder,kotlin.Unit> delegate);
-    method public kotlin.jvm.functions.Function1<androidx.ui.graphics.vectorgraphics.PathBuilder,kotlin.Unit> getDelegate();
-  }
-
   public final class PathNode {
     ctor public PathNode(androidx.ui.graphics.vectorgraphics.PathCommand command, float[] args);
     method public androidx.ui.graphics.vectorgraphics.PathCommand component1();
@@ -1515,60 +1411,6 @@
     ctor public PathParserKt();
   }
 
-  public final class RadialGradient implements androidx.ui.graphics.vectorgraphics.Brush {
-    method public void applyBrush(androidx.ui.painting.Paint p);
-    method public androidx.ui.graphics.vectorgraphics.RadialGradient copy(java.util.List<androidx.ui.graphics.Color> colors, java.util.List<java.lang.Float>? stops, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode);
-  }
-
-  public final class SolidColor implements androidx.ui.graphics.vectorgraphics.Brush {
-    ctor public SolidColor(androidx.ui.graphics.Color value);
-    method public void applyBrush(androidx.ui.painting.Paint p);
-    method public androidx.ui.graphics.vectorgraphics.SolidColor copy(androidx.ui.graphics.Color value);
-  }
-
-  public abstract sealed class VNode {
-    method public abstract void draw(androidx.ui.painting.Canvas canvas);
-  }
-
-  public final class VectorComponent extends androidx.ui.graphics.vectorgraphics.VNode {
-    ctor public VectorComponent(String name, float viewportWidth, float viewportHeight, androidx.ui.core.Px defaultWidth, androidx.ui.core.Px defaultHeight);
-    method public void draw(androidx.ui.painting.Canvas canvas);
-    method public androidx.ui.core.Px getDefaultHeight();
-    method public androidx.ui.core.Px getDefaultWidth();
-    method public String getName();
-    method public androidx.ui.graphics.vectorgraphics.GroupComponent getRoot();
-    method public int getSize();
-    method public float getViewportHeight();
-    method public float getViewportWidth();
-    method public void setDefaultHeight(androidx.ui.core.Px p);
-    method public void setDefaultWidth(androidx.ui.core.Px p);
-    method public void setViewportHeight(float p);
-    method public void setViewportWidth(float p);
-    property public final androidx.ui.graphics.vectorgraphics.GroupComponent root;
-    property public final int size;
-  }
-
-  public final class VectorKt {
-    ctor public VectorKt();
-    method public static androidx.ui.graphics.vectorgraphics.PathNode![] addPathNodes(String? pathStr);
-    method public static androidx.ui.graphics.vectorgraphics.PathNode![] createPath(Object? pathData);
-    method public static androidx.ui.painting.StrokeCap getDefaultStrokeLineCap();
-    method public static androidx.ui.painting.StrokeJoin getDefaultStrokeLineJoin();
-    method public static androidx.ui.graphics.vectorgraphics.PathNode![] getEmptyPath();
-    field public static final float DefaultAlpha = 1.0f;
-    field public static final String DefaultGroupName = "";
-    field public static final String DefaultPathName = "";
-    field public static final float DefaultPivotX = 0.0f;
-    field public static final float DefaultPivotY = 0.0f;
-    field public static final float DefaultRotation = 0.0f;
-    field public static final float DefaultScaleX = 1.0f;
-    field public static final float DefaultScaleY = 1.0f;
-    field public static final float DefaultStrokeLineMiter = 4.0f;
-    field public static final float DefaultStrokeLineWidth = 0.0f;
-    field public static final float DefaultTranslationX = 0.0f;
-    field public static final float DefaultTranslationY = 0.0f;
-  }
-
 }
 
 package androidx.ui.painting {
@@ -1920,6 +1762,31 @@
 
 }
 
+package androidx.ui.semantics {
+
+  public final class AccessibilityAction<T extends kotlin.Function<? extends kotlin.Unit>> {
+    ctor public AccessibilityAction(String? label, T action);
+    method public String? component1();
+    method public T component2();
+    method public androidx.ui.semantics.AccessibilityAction<T> copy(String? label, T action);
+    method public T getAction();
+    method public String? getLabel();
+  }
+
+  public class SemanticsPropertyKey<T> implements kotlin.properties.ReadWriteProperty<androidx.ui.semantics.SemanticsPropertyReceiver,T> {
+    ctor public SemanticsPropertyKey(String name);
+    method public final String getName();
+    method public final T! getValue(androidx.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property);
+    method public T! merge(T? existingValue, T? newValue);
+    method public final void setValue(androidx.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property, T? value);
+  }
+
+  public interface SemanticsPropertyReceiver {
+    method public operator <T> void set(androidx.ui.semantics.SemanticsPropertyKey<T> key, T? value);
+  }
+
+}
+
 package androidx.ui.temputils {
 
   public final class CoroutineUtilsKt {
diff --git a/ui/ui-core/api/restricted_current.txt b/ui/ui-core/api/restricted_current.txt
index 195ecdf..0a4e798 100644
--- a/ui/ui-core/api/restricted_current.txt
+++ b/ui/ui-core/api/restricted_current.txt
@@ -31,6 +31,42 @@
 
 }
 
+package androidx.ui.autofill {
+
+  public interface Autofill {
+    method public void cancelAutofillForNode(androidx.ui.autofill.AutofillNode autofillNode);
+    method public void requestAutofillForNode(androidx.ui.autofill.AutofillNode autofillNode);
+  }
+
+  public final class AutofillNode {
+    ctor public AutofillNode(java.util.List<? extends androidx.ui.autofill.AutofillType> autofillTypes, android.graphics.Rect? boundingBox, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit>? onFill);
+    method public java.util.List<androidx.ui.autofill.AutofillType> component1();
+    method public android.graphics.Rect? component2();
+    method public kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit>? component3();
+    method public androidx.ui.autofill.AutofillNode copy(java.util.List<? extends androidx.ui.autofill.AutofillType> autofillTypes, android.graphics.Rect? boundingBox, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit>? onFill);
+    method public java.util.List<androidx.ui.autofill.AutofillType> getAutofillTypes();
+    method public android.graphics.Rect? getBoundingBox();
+    method public int getId();
+    method public kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit>? getOnFill();
+    method public void setBoundingBox(android.graphics.Rect? p);
+    property public final int id;
+  }
+
+  public final class AutofillTree {
+    ctor public AutofillTree();
+    method public java.util.Map<java.lang.Integer,androidx.ui.autofill.AutofillNode> getChildren();
+    method public kotlin.Unit? performAutofill(int id, String value);
+    method public operator void plusAssign(androidx.ui.autofill.AutofillNode autofillNode);
+    property public final java.util.Map<java.lang.Integer,androidx.ui.autofill.AutofillNode> children;
+  }
+
+  public enum AutofillType {
+    enum_constant public static final androidx.ui.autofill.AutofillType EmailAddress;
+    enum_constant public static final androidx.ui.autofill.AutofillType Name;
+  }
+
+}
+
 package androidx.ui.core {
 
   public final class Bounds {
@@ -396,6 +432,11 @@
     method public androidx.ui.core.IntPx getWidth();
   }
 
+  public enum LayoutDirection {
+    enum_constant public static final androidx.ui.core.LayoutDirection Ltr;
+    enum_constant public static final androidx.ui.core.LayoutDirection Rtl;
+  }
+
   public enum PointerEventPass {
     enum_constant public static final androidx.ui.core.PointerEventPass InitialDown;
     enum_constant public static final androidx.ui.core.PointerEventPass PostDown;
@@ -710,74 +751,6 @@
 
 }
 
-package androidx.ui.core.semantics {
-
-  public final class SemanticsAction<T> {
-    ctor public SemanticsAction(androidx.ui.core.semantics.SemanticsActionType<T> type, T handler);
-    method public androidx.ui.core.semantics.SemanticsActionType<T> component1();
-    method public T component2();
-    method public androidx.ui.core.semantics.SemanticsAction<T> copy(androidx.ui.core.semantics.SemanticsActionType<T> type, T handler);
-    method public T getHandler();
-    method public androidx.ui.core.semantics.SemanticsActionType<T> getType();
-    method public void invokeHandler(Object? args);
-  }
-
-  public final class SemanticsActionType<T> {
-    method public int getBitmask();
-    field public static final androidx.ui.core.semantics.SemanticsActionType.Companion! Companion;
-  }
-
-  public static final class SemanticsActionType.Companion {
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getCopy();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getCustomAction();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getCut();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getDecrease();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getDidGainAccessibilityFocus();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getDidLoseAccessibilityFocus();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getDismiss();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getIncrease();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getLongPress();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> getMoveCursorBackwardByCharacter();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> getMoveCursorBackwardByWord();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> getMoveCursorForwardByCharacter();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> getMoveCursorForwardByWord();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getPaste();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getScrollDown();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getScrollLeft();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getScrollRight();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getScrollUp();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<androidx.ui.text.TextSelection,kotlin.Unit>> getSetSelection();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getShowOnScreen();
-    method public androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> getTap();
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Copy;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> CustomAction;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Cut;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Decrease;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> DidGainAccessibilityFocus;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> DidLoseAccessibilityFocus;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Dismiss;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Increase;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> LongPress;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> MoveCursorBackwardByCharacter;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> MoveCursorBackwardByWord;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> MoveCursorForwardByCharacter;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit>> MoveCursorForwardByWord;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Paste;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ScrollDown;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ScrollLeft;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ScrollRight;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ScrollUp;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function1<androidx.ui.text.TextSelection,kotlin.Unit>> SetSelection;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> ShowOnScreen;
-    property public final androidx.ui.core.semantics.SemanticsActionType<kotlin.jvm.functions.Function0<kotlin.Unit>> Tap;
-  }
-
-  public final class SemanticsActionsKt {
-    ctor public SemanticsActionsKt();
-  }
-
-}
-
 package androidx.ui.engine.geometry {
 
   public final class Offset implements androidx.ui.engine.geometry.OffsetBase {
@@ -1078,6 +1051,24 @@
 
 package androidx.ui.graphics {
 
+  public interface Brush {
+    method public void applyBrush(androidx.ui.painting.Paint p);
+  }
+
+  public final class BrushKt {
+    ctor public BrushKt();
+    method public static androidx.ui.graphics.LinearGradient HorizontalGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startX, androidx.ui.core.Px endX, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.Brush HorizontalGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startX, androidx.ui.core.Px endX, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.LinearGradient LinearGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.LinearGradient LinearGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.RadialGradient RadialGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.RadialGradient RadialGradient(androidx.ui.graphics.Color![] colors, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.LinearGradient VerticalGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startY, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.LinearGradient VerticalGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startY, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
+    method public static androidx.ui.graphics.Brush getEmptyBrush();
+    method public static androidx.ui.graphics.Brush obtainBrush(Object? brush);
+  }
+
   @AnyThread public final class Color {
     method public operator int compareTo(androidx.ui.graphics.Color other);
     method public androidx.ui.graphics.Color convert(androidx.ui.graphics.ColorSpace colorSpace);
@@ -1320,83 +1311,26 @@
     method public double getG();
   }
 
+  public final class LinearGradient implements androidx.ui.graphics.Brush {
+    method public void applyBrush(androidx.ui.painting.Paint p);
+    method public androidx.ui.graphics.LinearGradient copy(java.util.List<androidx.ui.graphics.Color> colors, java.util.List<java.lang.Float>? stops, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode);
+  }
+
+  public final class RadialGradient implements androidx.ui.graphics.Brush {
+    method public void applyBrush(androidx.ui.painting.Paint p);
+    method public androidx.ui.graphics.RadialGradient copy(java.util.List<androidx.ui.graphics.Color> colors, java.util.List<java.lang.Float>? stops, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode);
+  }
+
+  public final class SolidColor implements androidx.ui.graphics.Brush {
+    ctor public SolidColor(androidx.ui.graphics.Color value);
+    method public void applyBrush(androidx.ui.painting.Paint p);
+    method public androidx.ui.graphics.SolidColor copy(androidx.ui.graphics.Color value);
+  }
+
 }
 
 package androidx.ui.graphics.vectorgraphics {
 
-  public interface Brush {
-    method public void applyBrush(androidx.ui.painting.Paint p);
-  }
-
-  public final class BrushKt {
-    ctor public BrushKt();
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient HorizontalGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startX, androidx.ui.core.Px endX, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.Brush HorizontalGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startX, androidx.ui.core.Px endX, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient LinearGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient LinearGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.RadialGradient RadialGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.RadialGradient RadialGradient(androidx.ui.graphics.Color![] colors, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient VerticalGradient(androidx.ui.graphics.Color![] colors, androidx.ui.core.Px startY, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.LinearGradient VerticalGradient(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>![] colorStops, androidx.ui.core.Px startY, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode = TileMode.clamp);
-    method public static androidx.ui.graphics.vectorgraphics.Brush getEmptyBrush();
-    method public static androidx.ui.graphics.vectorgraphics.Brush obtainBrush(Object? brush);
-  }
-
-  public final class GroupComponent extends androidx.ui.graphics.vectorgraphics.VNode {
-    ctor public GroupComponent(String name);
-    ctor public GroupComponent();
-    method public void draw(androidx.ui.painting.Canvas canvas);
-    method public androidx.ui.graphics.vectorgraphics.PathNode![] getClipPathNodes();
-    method public String getName();
-    method public float getPivotX();
-    method public float getPivotY();
-    method public float getRotation();
-    method public float getScaleX();
-    method public float getScaleY();
-    method public int getSize();
-    method public float getTranslationX();
-    method public float getTranslationY();
-    method public void insertAt(int index, androidx.ui.graphics.vectorgraphics.VNode instance);
-    method public void move(int from, int to, int count);
-    method public void remove(int index, int count);
-    method public void setClipPathNodes(androidx.ui.graphics.vectorgraphics.PathNode![] value);
-    method public void setPivotX(float value);
-    method public void setPivotY(float value);
-    method public void setRotation(float value);
-    method public void setScaleX(float value);
-    method public void setScaleY(float value);
-    method public void setTranslationX(float value);
-    method public void setTranslationY(float value);
-    property public final androidx.ui.graphics.vectorgraphics.PathNode![] clipPathNodes;
-    property public final float pivotX;
-    property public final float pivotY;
-    property public final float rotation;
-    property public final float scaleX;
-    property public final float scaleY;
-    property public final int size;
-    property public final float translationX;
-    property public final float translationY;
-  }
-
-  public final class LinearGradient implements androidx.ui.graphics.vectorgraphics.Brush {
-    method public void applyBrush(androidx.ui.painting.Paint p);
-    method public java.util.List<androidx.ui.graphics.Color> component1();
-    method public java.util.List<java.lang.Float>? component2();
-    method public androidx.ui.core.Px component3();
-    method public androidx.ui.core.Px component4();
-    method public androidx.ui.core.Px component5();
-    method public androidx.ui.core.Px component6();
-    method public androidx.ui.painting.TileMode component7();
-    method public androidx.ui.graphics.vectorgraphics.LinearGradient copy(java.util.List<androidx.ui.graphics.Color> colors, java.util.List<java.lang.Float>? stops, androidx.ui.core.Px startX, androidx.ui.core.Px startY, androidx.ui.core.Px endX, androidx.ui.core.Px endY, androidx.ui.painting.TileMode tileMode);
-    method public java.util.List<androidx.ui.graphics.Color> getColors();
-    method public androidx.ui.core.Px getEndX();
-    method public androidx.ui.core.Px getEndY();
-    method public androidx.ui.core.Px getStartX();
-    method public androidx.ui.core.Px getStartY();
-    method public java.util.List<java.lang.Float>? getStops();
-    method public androidx.ui.painting.TileMode getTileMode();
-  }
-
   public final class PathBuilder {
     ctor public PathBuilder();
     method public androidx.ui.graphics.vectorgraphics.PathBuilder arcTo(float horizontalEllipseRadius, float verticalEllipseRadius, float theta, float largeArcFlag, float sweepFlag, float x1, float y1);
@@ -1450,44 +1384,6 @@
     method public static androidx.ui.graphics.vectorgraphics.PathCommand toPathCommand(char);
   }
 
-  public final class PathComponent extends androidx.ui.graphics.vectorgraphics.VNode {
-    ctor public PathComponent(String name);
-    method public void draw(androidx.ui.painting.Canvas canvas);
-    method public androidx.ui.graphics.vectorgraphics.Brush getFill();
-    method public float getFillAlpha();
-    method public String getName();
-    method public androidx.ui.graphics.vectorgraphics.PathNode![] getPathNodes();
-    method public androidx.ui.graphics.vectorgraphics.Brush getStroke();
-    method public float getStrokeAlpha();
-    method public androidx.ui.painting.StrokeCap getStrokeLineCap();
-    method public androidx.ui.painting.StrokeJoin getStrokeLineJoin();
-    method public float getStrokeLineMiter();
-    method public float getStrokeLineWidth();
-    method public void setFill(androidx.ui.graphics.vectorgraphics.Brush value);
-    method public void setFillAlpha(float value);
-    method public void setPathNodes(androidx.ui.graphics.vectorgraphics.PathNode![] value);
-    method public void setStroke(androidx.ui.graphics.vectorgraphics.Brush value);
-    method public void setStrokeAlpha(float value);
-    method public void setStrokeLineCap(androidx.ui.painting.StrokeCap value);
-    method public void setStrokeLineJoin(androidx.ui.painting.StrokeJoin value);
-    method public void setStrokeLineMiter(float value);
-    method public void setStrokeLineWidth(float value);
-    property public final androidx.ui.graphics.vectorgraphics.Brush fill;
-    property public final float fillAlpha;
-    property public final androidx.ui.graphics.vectorgraphics.PathNode![] pathNodes;
-    property public final androidx.ui.graphics.vectorgraphics.Brush stroke;
-    property public final float strokeAlpha;
-    property public final androidx.ui.painting.StrokeCap strokeLineCap;
-    property public final androidx.ui.painting.StrokeJoin strokeLineJoin;
-    property public final float strokeLineMiter;
-    property public final float strokeLineWidth;
-  }
-
-  public final class PathDelegate {
-    ctor public PathDelegate(kotlin.jvm.functions.Function1<? super androidx.ui.graphics.vectorgraphics.PathBuilder,kotlin.Unit> delegate);
-    method public kotlin.jvm.functions.Function1<androidx.ui.graphics.vectorgraphics.PathBuilder,kotlin.Unit> getDelegate();
-  }
-
   public final class PathNode {
     ctor public PathNode(androidx.ui.graphics.vectorgraphics.PathCommand command, float[] args);
     method public androidx.ui.graphics.vectorgraphics.PathCommand component1();
@@ -1515,60 +1411,6 @@
     ctor public PathParserKt();
   }
 
-  public final class RadialGradient implements androidx.ui.graphics.vectorgraphics.Brush {
-    method public void applyBrush(androidx.ui.painting.Paint p);
-    method public androidx.ui.graphics.vectorgraphics.RadialGradient copy(java.util.List<androidx.ui.graphics.Color> colors, java.util.List<java.lang.Float>? stops, float centerX, float centerY, float radius, androidx.ui.painting.TileMode tileMode);
-  }
-
-  public final class SolidColor implements androidx.ui.graphics.vectorgraphics.Brush {
-    ctor public SolidColor(androidx.ui.graphics.Color value);
-    method public void applyBrush(androidx.ui.painting.Paint p);
-    method public androidx.ui.graphics.vectorgraphics.SolidColor copy(androidx.ui.graphics.Color value);
-  }
-
-  public abstract sealed class VNode {
-    method public abstract void draw(androidx.ui.painting.Canvas canvas);
-  }
-
-  public final class VectorComponent extends androidx.ui.graphics.vectorgraphics.VNode {
-    ctor public VectorComponent(String name, float viewportWidth, float viewportHeight, androidx.ui.core.Px defaultWidth, androidx.ui.core.Px defaultHeight);
-    method public void draw(androidx.ui.painting.Canvas canvas);
-    method public androidx.ui.core.Px getDefaultHeight();
-    method public androidx.ui.core.Px getDefaultWidth();
-    method public String getName();
-    method public androidx.ui.graphics.vectorgraphics.GroupComponent getRoot();
-    method public int getSize();
-    method public float getViewportHeight();
-    method public float getViewportWidth();
-    method public void setDefaultHeight(androidx.ui.core.Px p);
-    method public void setDefaultWidth(androidx.ui.core.Px p);
-    method public void setViewportHeight(float p);
-    method public void setViewportWidth(float p);
-    property public final androidx.ui.graphics.vectorgraphics.GroupComponent root;
-    property public final int size;
-  }
-
-  public final class VectorKt {
-    ctor public VectorKt();
-    method public static androidx.ui.graphics.vectorgraphics.PathNode![] addPathNodes(String? pathStr);
-    method public static androidx.ui.graphics.vectorgraphics.PathNode![] createPath(Object? pathData);
-    method public static androidx.ui.painting.StrokeCap getDefaultStrokeLineCap();
-    method public static androidx.ui.painting.StrokeJoin getDefaultStrokeLineJoin();
-    method public static androidx.ui.graphics.vectorgraphics.PathNode![] getEmptyPath();
-    field public static final float DefaultAlpha = 1.0f;
-    field public static final String DefaultGroupName = "";
-    field public static final String DefaultPathName = "";
-    field public static final float DefaultPivotX = 0.0f;
-    field public static final float DefaultPivotY = 0.0f;
-    field public static final float DefaultRotation = 0.0f;
-    field public static final float DefaultScaleX = 1.0f;
-    field public static final float DefaultScaleY = 1.0f;
-    field public static final float DefaultStrokeLineMiter = 4.0f;
-    field public static final float DefaultStrokeLineWidth = 0.0f;
-    field public static final float DefaultTranslationX = 0.0f;
-    field public static final float DefaultTranslationY = 0.0f;
-  }
-
 }
 
 package androidx.ui.painting {
@@ -1920,6 +1762,31 @@
 
 }
 
+package androidx.ui.semantics {
+
+  public final class AccessibilityAction<T extends kotlin.Function<? extends kotlin.Unit>> {
+    ctor public AccessibilityAction(String? label, T action);
+    method public String? component1();
+    method public T component2();
+    method public androidx.ui.semantics.AccessibilityAction<T> copy(String? label, T action);
+    method public T getAction();
+    method public String? getLabel();
+  }
+
+  public class SemanticsPropertyKey<T> implements kotlin.properties.ReadWriteProperty<androidx.ui.semantics.SemanticsPropertyReceiver,T> {
+    ctor public SemanticsPropertyKey(String name);
+    method public final String getName();
+    method public final T! getValue(androidx.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property);
+    method public T! merge(T? existingValue, T? newValue);
+    method public final void setValue(androidx.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property, T? value);
+  }
+
+  public interface SemanticsPropertyReceiver {
+    method public operator <T> void set(androidx.ui.semantics.SemanticsPropertyKey<T> key, T? value);
+  }
+
+}
+
 package androidx.ui.temputils {
 
   public final class CoroutineUtilsKt {
diff --git a/ui/ui-core/build.gradle b/ui/ui-core/build.gradle
index 6817c80..f33c1a5 100644
--- a/ui/ui-core/build.gradle
+++ b/ui/ui-core/build.gradle
@@ -58,6 +58,6 @@
 
 tasks.withType(KotlinCompile).configureEach {
     kotlinOptions {
-        freeCompilerArgs += ["-Werror", "-Xuse-experimental=kotlin.Experimental"]
+        freeCompilerArgs += ["-Xuse-experimental=kotlin.Experimental", "-XXLanguage:+InlineClasses"]
     }
 }
diff --git a/ui/ui-core/src/main/java/androidx/ui/autofill/Autofill.kt b/ui/ui-core/src/main/java/androidx/ui/autofill/Autofill.kt
new file mode 100644
index 0000000..6e13b2c0
--- /dev/null
+++ b/ui/ui-core/src/main/java/androidx/ui/autofill/Autofill.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2019 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.ui.autofill
+
+import android.graphics.Rect
+import androidx.annotation.GuardedBy
+
+/**
+ * Autofill API.
+ *
+ * This interface is available to all composables via an ambient. The composable can then request
+ * or cancel autofill as required. For instance, the [TextField] can call [requestAutofillForNode]
+ * when it gains focus, and [cancelAutofillForNode] when it loses focus.
+ */
+interface Autofill {
+
+    /**
+     * Request autofill for the specified node.
+     *
+     * @param autofillNode The node that needs to be autofilled.
+     *
+     * This function is usually called when an autofillable component gains focus.
+     */
+    fun requestAutofillForNode(autofillNode: AutofillNode)
+
+    /**
+     * Cancel a previously supplied autofill request.
+     *
+     * @param autofillNode The node that needs to be autofilled.
+     *
+     * This function is usually called when an autofillable component loses focus.
+     */
+    fun cancelAutofillForNode(autofillNode: AutofillNode)
+}
+
+// TODO(b/138551812): Add more autofill types.
+/** Autofill type information. */
+enum class AutofillType {
+    EmailAddress,
+    Name
+}
+
+/**
+ * Every autofillable composable will have an [AutofillNode]. (An autofill node will be created
+ * for every semantics node that adds autofill properties). This node is used to request/cancel
+ * autofill, and it holds the [onFill] lambda which is called by the autofill framework.
+ *
+ * @property autofillTypes A list of autofill types for this node. These types are conveyed to the
+ * autofill framework and it is used to call [onFill] with the appropriate value. If you don't set
+ * this property, the autofill framework will use heuristics to guess the type. This property is a
+ * list because some fields can have multiple types. For instance, userid in a login form can
+ * either be a username or an email address. TODO(b/138731416): Check with the autofill service
+ * team if the order matters, and how duplicate types are handled.
+ *
+ * @property boundingBox The screen coordinates of the composable being autofilled.
+ * This data is used by the autofill framework to decide where to show the autofill popup.
+ *
+ * @property onFill The callback that is called by the autofill framework to perform autofill.
+ *
+ * @property id A virtual id that is automatically generated for each node.
+ */
+data class AutofillNode(
+    val autofillTypes: List<AutofillType> = listOf(),
+    var boundingBox: Rect? = null,
+    val onFill: ((String) -> Unit)?
+) {
+    internal companion object {
+        @GuardedBy("this")
+        private var previousId = 0
+
+        @Synchronized
+        private fun generateId() = ++previousId
+    }
+
+    val id: Int = generateId()
+}
\ No newline at end of file
diff --git a/ui/ui-core/src/main/java/androidx/ui/autofill/AutofillTree.kt b/ui/ui-core/src/main/java/androidx/ui/autofill/AutofillTree.kt
new file mode 100644
index 0000000..c3ca40e
--- /dev/null
+++ b/ui/ui-core/src/main/java/androidx/ui/autofill/AutofillTree.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2019 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.ui.autofill
+
+/**
+ * The autofill tree.
+ *
+ * This is used temporarily until we have a semantic tree implemented (b/138604305). This
+ * implementation is a tree of height = 1, and we don't use the root node right now, so this is
+ * essentially a group of leaf nodes.
+ */
+class AutofillTree {
+    val children: MutableMap<Int, AutofillNode> = mutableMapOf()
+
+    operator fun plusAssign(autofillNode: AutofillNode) {
+        children[autofillNode.id] = autofillNode
+    }
+
+    fun performAutofill(id: Int, value: String) = children[id]?.onFill?.invoke(value)
+}
\ No newline at end of file
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/LayoutDirection.kt b/ui/ui-core/src/main/java/androidx/ui/core/LayoutDirection.kt
new file mode 100644
index 0000000..c826d32
--- /dev/null
+++ b/ui/ui-core/src/main/java/androidx/ui/core/LayoutDirection.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2019 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.ui.core
+
+/**
+ * A class for defining layout directions.
+ *
+ * A layout direction can be left-to-right (LTR) or right-to-left (RTL).
+ */
+enum class LayoutDirection {
+    /**
+     * Horizontal layout direction is from Left to Right.
+     */
+    Ltr,
+
+    /**
+     * Horizontal layout direction is from Right to Left.
+     */
+    Rtl,
+}
\ No newline at end of file
diff --git a/ui/ui-core/src/main/java/androidx/ui/graphics/Brush.kt b/ui/ui-core/src/main/java/androidx/ui/graphics/Brush.kt
new file mode 100644
index 0000000..4dd008f
--- /dev/null
+++ b/ui/ui-core/src/main/java/androidx/ui/graphics/Brush.kt
@@ -0,0 +1,360 @@
+/*
+ * Copyright 2019 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.ui.graphics
+
+import androidx.ui.core.Px
+import androidx.ui.engine.geometry.Offset
+import androidx.ui.painting.Gradient
+import androidx.ui.painting.Paint
+import androidx.ui.painting.Shader
+import androidx.ui.painting.TileMode
+import androidx.ui.vectormath64.Matrix4
+
+val EmptyBrush = object : Brush {
+    override fun applyBrush(p: Paint) {
+        // NO-OP
+    }
+}
+
+interface Brush {
+    fun applyBrush(p: Paint)
+}
+
+data class SolidColor(private val value: Color) : Brush {
+    override fun applyBrush(p: Paint) {
+        p.color = value
+    }
+}
+
+typealias ColorStop = Pair<Float, Color>
+
+/**
+ * Obtains actual Brush instance from Union type, throws an IllegalArgumentException
+ * if the type is other than Int, Color, Brush or null
+ */
+fun obtainBrush(brush: Any?): Brush {
+    return when (brush) {
+        is Int -> SolidColor(Color(brush))
+        is Color -> SolidColor(brush)
+        is Brush -> brush
+        null -> EmptyBrush
+        else -> throw IllegalArgumentException(brush.javaClass.simpleName +
+                "Brush must be either a Color long, LinearGradient or RadialGradient")
+    }
+}
+
+/**
+ * Creates a linear gradient with the provided colors along the given start and end coordinates.
+ * The colors are
+ *
+ * ```
+ *  LinearGradient(
+ *      0.0f to Color.Aqua,
+ *      0.3f to Color.Lime,
+ *      1.0f to Color.Fuchsia,
+ *      startX = Px.Zero,
+ *      startY = Px(50.0f),
+ *      endY = Px.Zero,
+ *      endY = Px(100.0f)
+ * )
+ * ```
+ */
+fun LinearGradient(
+    vararg colors: Color,
+    startX: Px,
+    startY: Px,
+    endX: Px,
+    endY: Px,
+    tileMode: TileMode = TileMode.clamp
+): LinearGradient {
+    return LinearGradient(
+        colors.asList(),
+        null,
+        startX,
+        startY,
+        endX,
+        endY,
+        tileMode
+    )
+}
+
+/**
+ * Creates a linear gradient with the provided colors along the given start and end coordinates.
+ * The colors are dispersed at the provided offset defined in the [ColorStop]
+ *
+ * ```
+ *  LinearGradient(
+ *      0.0f to Color.Aqua,
+ *      0.3f to Color.Lime,
+ *      1.0f to Color.Fuchsia,
+ *      startX = Px.Zero,
+ *      startY = Px(50.0f),
+ *      endY = Px.Zero,
+ *      endY = Px(100.0f)
+ * )
+ * ```
+ */
+fun LinearGradient(
+    vararg colorStops: ColorStop,
+    startX: Px,
+    startY: Px,
+    endX: Px,
+    endY: Px,
+    tileMode: TileMode = TileMode.clamp
+): LinearGradient {
+    return LinearGradient(
+        List<Color>(colorStops.size) { i -> colorStops[i].second },
+        List<Float>(colorStops.size) { i -> colorStops[i].first },
+        startX,
+        startY,
+        endX,
+        endY,
+        tileMode
+    )
+}
+
+/**
+ * Creates a radial gradient with the given colors at the provided offset defined in the [ColorStop]
+ * ```
+ * RadialGradient(
+ *      0.0f to Color.Navy,
+ *      0.3f to Color.Olive,
+ *      1.0f to Color.Teal,
+ *      centerX = side1 / 2.0f,
+ *      centerY = side2 / 2.0f,
+ *      radius = side1 / 2.0f,
+ *      tileMode = TileMode.repeated
+ * )
+ * ```
+ */
+fun RadialGradient(
+    vararg colorStops: ColorStop,
+    centerX: Float,
+    centerY: Float,
+    radius: Float,
+    tileMode: TileMode = TileMode.clamp
+): RadialGradient {
+    return RadialGradient(
+        List<Color>(colorStops.size) { i -> colorStops[i].second },
+        List<Float>(colorStops.size) { i -> colorStops[i].first },
+        centerX,
+        centerY,
+        radius,
+        tileMode
+    )
+}
+
+/**
+ * Creates a radial gradient with the given colors evenly dispersed within the gradient
+ * ```
+ * RadialGradient(
+ *      Color.Navy,
+ *      Color.Olive,
+ *      Color.Teal,
+ *      centerX = side1 / 2.0f,
+ *      centerY = side2 / 2.0f,
+ *      radius = side1 / 2.0f,
+ *      tileMode = TileMode.repeated
+ * )
+ * ```
+ */
+fun RadialGradient(
+    vararg colors: Color,
+    centerX: Float,
+    centerY: Float,
+    radius: Float,
+    tileMode: TileMode = TileMode.clamp
+): RadialGradient {
+    return RadialGradient(colors.asList(), null, centerX, centerY, radius, tileMode)
+}
+
+/**
+ * Creates a vertical gradient with the given colors at the provided offset defined in the [ColorStop]
+ * Ex:
+ * ```
+ *  VerticalGradient(
+ *      Color.Aqua,
+ *      Color.Lime,
+ *      Color.Fuchsia,
+ *      startY = Px.Zero,
+ *      endY = Px(100.0f)
+ * )
+ *
+ * ```
+ */
+fun VerticalGradient(
+    vararg colors: Color,
+    startY: Px,
+    endY: Px,
+    tileMode: TileMode = TileMode.clamp
+): LinearGradient {
+    return LinearGradient(
+        colors.asList(),
+        null,
+        startX = Px.Zero,
+        startY = startY,
+        endX = Px.Zero,
+        endY = endY,
+        tileMode = tileMode
+    )
+}
+
+/**
+ * Creates a vertical gradient with the given colors evenly dispersed within the gradient
+ * Ex:
+ * ```
+ *  VerticalGradient(
+ *      Color.Aqua,
+ *      Color.Lime,
+ *      Color.Fuchsia,
+ *      startY = Px.Zero,
+ *      endY = Px(100.0f)
+ * )
+ * ```
+ */
+fun VerticalGradient(
+    vararg colorStops: ColorStop,
+    startY: Px,
+    endY: Px,
+    tileMode: TileMode = TileMode.clamp
+): LinearGradient {
+    return LinearGradient(
+        List<Color>(colorStops.size) { i -> colorStops[i].second },
+        List<Float>(colorStops.size) { i -> colorStops[i].first },
+        startX = Px.Zero,
+        startY = startY,
+        endX = Px.Zero,
+        endY = endY,
+        tileMode = tileMode
+    )
+}
+
+/**
+ * Creates a horizontal gradient with the given colors evenly dispersed within the gradient
+ *
+ * Ex:
+ * ```
+ *  HorizontalGradient(
+ *      Color.Aqua,
+ *      Color.Lime,
+ *      Color.Fuchsia,
+ *      startX = Px(10.0f),
+ *      endX = Px(20.0f)
+ * )
+ * ```
+ */
+fun HorizontalGradient(
+    vararg colors: Color,
+    startX: Px,
+    endX: Px,
+    tileMode: TileMode = TileMode.clamp
+): LinearGradient {
+    return LinearGradient(
+        colors.asList(),
+        null,
+        startX = startX,
+        startY = Px.Zero,
+        endX = endX,
+        endY = Px.Zero,
+        tileMode = tileMode
+    )
+}
+
+/**
+ * Creates a horizontal gradient with the given colors dispersed at the provided offset defined in the [ColorStop]
+ *
+ * Ex:
+ * ```
+ *  HorizontalGradient(
+ *      0.0f to Color.Aqua,
+ *      0.3f to Color.Lime,
+ *      1.0f to Color.Fuchsia,
+ *      startX = Px.Zero,
+ *      endX = Px(100.0f)
+ * )
+ * ```
+ */
+fun HorizontalGradient(
+    vararg colorStops: ColorStop,
+    startX: Px,
+    endX: Px,
+    tileMode: TileMode = TileMode.clamp
+): Brush {
+    return LinearGradient(
+        List<Color>(colorStops.size) { i -> colorStops[i].second },
+        List<Float>(colorStops.size) { i -> colorStops[i].first },
+        startX = startX,
+        startY = Px.Zero,
+        endX = endX,
+        endY = Px.Zero,
+        tileMode = tileMode
+    )
+}
+
+/**
+ * Brush implementation used to apply a linear gradient on a given [Paint]
+ */
+data class LinearGradient internal constructor(
+    private val colors: List<Color>,
+    private val stops: List<Float>? = null,
+    private val startX: Px,
+    private val startY: Px,
+    private val endX: Px,
+    private val endY: Px,
+    private val tileMode: TileMode = TileMode.clamp
+) : Brush {
+
+    private val shader: Shader
+
+    init {
+        shader = Gradient.linear(
+            Offset(startX.value, startY.value),
+            Offset(endX.value, endY.value),
+            colors,
+            stops,
+            tileMode)
+    }
+
+    override fun applyBrush(p: Paint) {
+        p.shader = shader
+    }
+}
+
+/**
+ * Brush implementation used to apply a radial gradient on a given [Paint]
+ */
+data class RadialGradient internal constructor(
+    private val colors: List<Color>,
+    private val stops: List<Float>? = null,
+    private val centerX: Float,
+    private val centerY: Float,
+    private val radius: Float,
+    private val tileMode: TileMode = TileMode.clamp
+) : Brush {
+
+    private val shader: Shader
+
+    init {
+        shader = Gradient.radial(
+            Offset(centerX, centerY),
+            radius, colors, stops, tileMode, Matrix4())
+    }
+
+    override fun applyBrush(p: Paint) {
+        p.shader = shader
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-core/src/main/java/androidx/ui/graphics/vectorgraphics/Brush.kt b/ui/ui-core/src/main/java/androidx/ui/graphics/vectorgraphics/Brush.kt
deleted file mode 100644
index 3243120..0000000
--- a/ui/ui-core/src/main/java/androidx/ui/graphics/vectorgraphics/Brush.kt
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Copyright 2019 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.ui.graphics.vectorgraphics
-
-import androidx.ui.core.Px
-import androidx.ui.engine.geometry.Offset
-import androidx.ui.graphics.Color
-import androidx.ui.painting.Gradient
-import androidx.ui.painting.Paint
-import androidx.ui.painting.TileMode
-import androidx.ui.vectormath64.Matrix4
-
-val EmptyBrush = object : Brush {
-    override fun applyBrush(p: Paint) {
-        // NO-OP
-    }
-}
-
-interface Brush {
-    fun applyBrush(p: Paint)
-}
-
-data class SolidColor(private val value: Color) : Brush {
-    override fun applyBrush(p: Paint) {
-        p.color = value
-    }
-}
-
-typealias ColorStop = Pair<Float, Color>
-
-/**
- * Obtains actual Brush instance from Union type, throws an IllegalArgumentException
- * if the type is other than Int, Color, Brush or null
- */
-fun obtainBrush(brush: Any?): Brush {
-    return when (brush) {
-        is Int -> SolidColor(Color(brush))
-        is Color -> SolidColor(brush)
-        is Brush -> brush
-        null -> EmptyBrush
-        else -> throw IllegalArgumentException(brush.javaClass.simpleName +
-                "Brush must be either a Color long, LinearGradient or RadialGradient")
-    }
-}
-
-/**
- * Creates a linear gradient with the provided colors along the given start and end coordinates.
- * The colors are
- *
- * ```
- *  LinearGradient(
- *      0.0f to Color.Aqua,
- *      0.3f to Color.Lime,
- *      1.0f to Color.Fuchsia,
- *      startX = Px.Zero,
- *      startY = Px(50.0f),
- *      endY = Px.Zero,
- *      endY = Px(100.0f)
- * )
- * ```
- */
-fun LinearGradient(
-    vararg colors: Color,
-    startX: Px,
-    startY: Px,
-    endX: Px,
-    endY: Px,
-    tileMode: TileMode = TileMode.clamp
-): LinearGradient {
-    return LinearGradient(
-        colors.asList(),
-        null,
-        startX,
-        startY,
-        endX,
-        endY,
-        tileMode)
-}
-
-/**
- * Creates a linear gradient with the provided colors along the given start and end coordinates.
- * The colors are dispersed at the provided offset defined in the [ColorStop]
- *
- * ```
- *  LinearGradient(
- *      0.0f to Color.Aqua,
- *      0.3f to Color.Lime,
- *      1.0f to Color.Fuchsia,
- *      startX = Px.Zero,
- *      startY = Px(50.0f),
- *      endY = Px.Zero,
- *      endY = Px(100.0f)
- * )
- * ```
- */
-fun LinearGradient(
-    vararg colorStops: ColorStop,
-    startX: Px,
-    startY: Px,
-    endX: Px,
-    endY: Px,
-    tileMode: TileMode = TileMode.clamp
-): LinearGradient {
-    return LinearGradient(
-        List<Color>(colorStops.size) { i -> colorStops[i].second },
-        List<Float>(colorStops.size) { i -> colorStops[i].first },
-        startX,
-        startY,
-        endX,
-        endY,
-        tileMode)
-}
-
-/**
- * Creates a radial gradient with the given colors at the provided offset defined in the [ColorStop]
- * ```
- * RadialGradient(
- *      0.0f to Color.Navy,
- *      0.3f to Color.Olive,
- *      1.0f to Color.Teal,
- *      centerX = side1 / 2.0f,
- *      centerY = side2 / 2.0f,
- *      radius = side1 / 2.0f,
- *      tileMode = TileMode.repeated
- * )
- * ```
- */
-fun RadialGradient(
-    vararg colorStops: ColorStop,
-    centerX: Float,
-    centerY: Float,
-    radius: Float,
-    tileMode: TileMode = TileMode.clamp
-): RadialGradient {
-    return RadialGradient(
-        List<Color>(colorStops.size) { i -> colorStops[i].second },
-        List<Float>(colorStops.size) { i -> colorStops[i].first },
-        centerX,
-        centerY,
-        radius,
-        tileMode
-    )
-}
-
-/**
- * Creates a radial gradient with the given colors evenly dispersed within the gradient
- * ```
- * RadialGradient(
- *      Color.Navy,
- *      Color.Olive,
- *      Color.Teal,
- *      centerX = side1 / 2.0f,
- *      centerY = side2 / 2.0f,
- *      radius = side1 / 2.0f,
- *      tileMode = TileMode.repeated
- * )
- * ```
- */
-fun RadialGradient(
-    vararg colors: Color,
-    centerX: Float,
-    centerY: Float,
-    radius: Float,
-    tileMode: TileMode = TileMode.clamp
-): RadialGradient {
-    return RadialGradient(colors.asList(), null, centerX, centerY, radius, tileMode)
-}
-
-/**
- * Creates a vertical gradient with the given colors at the provided offset defined in the [ColorStop]
- * Ex:
- * ```
- *  VerticalGradient(
- *      Color.Aqua,
- *      Color.Lime,
- *      Color.Fuchsia,
- *      startY = Px.Zero,
- *      endY = Px(100.0f)
- * )
- *
- * ```
- */
-fun VerticalGradient(
-    vararg colors: Color,
-    startY: Px,
-    endY: Px,
-    tileMode: TileMode = TileMode.clamp
-): LinearGradient {
-    return LinearGradient(
-        colors.asList(),
-        null,
-        startX = Px.Zero,
-        startY = startY,
-        endX = Px.Zero,
-        endY = endY,
-        tileMode = tileMode)
-}
-
-/**
- * Creates a vertical gradient with the given colors evenly dispersed within the gradient
- * Ex:
- * ```
- *  VerticalGradient(
- *      Color.Aqua,
- *      Color.Lime,
- *      Color.Fuchsia,
- *      startY = Px.Zero,
- *      endY = Px(100.0f)
- * )
- * ```
- */
-fun VerticalGradient(
-    vararg colorStops: ColorStop,
-    startY: Px,
-    endY: Px,
-    tileMode: TileMode = TileMode.clamp
-): LinearGradient {
-    return LinearGradient(
-        List<Color>(colorStops.size) { i -> colorStops[i].second },
-        List<Float>(colorStops.size) { i -> colorStops[i].first },
-        startX = Px.Zero,
-        startY = startY,
-        endX = Px.Zero,
-        endY = endY,
-        tileMode = tileMode
-    )
-}
-
-/**
- * Creates a horizontal gradient with the given colors evenly dispersed within the gradient
- *
- * Ex:
- * ```
- *  HorizontalGradient(
- *      Color.Aqua,
- *      Color.Lime,
- *      Color.Fuchsia,
- *      startX = Px(10.0f),
- *      endX = Px(20.0f)
- * )
- * ```
- */
-fun HorizontalGradient(
-    vararg colors: Color,
-    startX: Px,
-    endX: Px,
-    tileMode: TileMode = TileMode.clamp
-): LinearGradient {
-    return LinearGradient(
-        colors.asList(),
-        null,
-        startX = startX,
-        startY = Px.Zero,
-        endX = endX,
-        endY = Px.Zero,
-        tileMode = tileMode)
-}
-
-/**
- * Creates a horizontal gradient with the given colors dispersed at the provided offset defined in the [ColorStop]
- *
- * Ex:
- * ```
- *  HorizontalGradient(
- *      0.0f to Color.Aqua,
- *      0.3f to Color.Lime,
- *      1.0f to Color.Fuchsia,
- *      startX = Px.Zero,
- *      endX = Px(100.0f)
- * )
- * ```
- */
-fun HorizontalGradient(
-    vararg colorStops: ColorStop,
-    startX: Px,
-    endX: Px,
-    tileMode: TileMode = TileMode.clamp
-): Brush {
-    return LinearGradient(
-        List<Color>(colorStops.size) { i -> colorStops[i].second },
-        List<Float>(colorStops.size) { i -> colorStops[i].first },
-        startX = startX,
-        startY = Px.Zero,
-        endX = endX,
-        endY = Px.Zero,
-        tileMode = tileMode
-    )
-}
-
-/**
- * Brush implementation used to apply a linear gradient on a given [Paint]
- */
-data class LinearGradient internal constructor(
-    val colors: List<Color>,
-    val stops: List<Float>? = null,
-    val startX: Px,
-    val startY: Px,
-    val endX: Px,
-    val endY: Px,
-    val tileMode: TileMode = TileMode.clamp
-) : Brush {
-
-    override fun applyBrush(p: Paint) {
-        p.shader = Gradient.linear(
-            Offset(startX.value, startY.value),
-            Offset(endX.value, endY.value),
-            colors,
-            stops,
-            tileMode)
-    }
-}
-
-/**
- * Brush implementation used to apply a radial gradient on a given [Paint]
- */
-data class RadialGradient internal constructor(
-    private val colors: List<Color>,
-    private val stops: List<Float>? = null,
-    private val centerX: Float,
-    private val centerY: Float,
-    private val radius: Float,
-    private val tileMode: TileMode = TileMode.clamp
-) : Brush {
-
-    override fun applyBrush(p: Paint) {
-        p.shader = Gradient.radial(
-            Offset(centerX, centerY),
-            radius, colors, stops, tileMode, Matrix4())
-    }
-}
\ No newline at end of file
diff --git a/ui/ui-core/src/main/java/androidx/ui/graphics/vectorgraphics/PathParser.kt b/ui/ui-core/src/main/java/androidx/ui/graphics/vectorgraphics/PathParser.kt
index 553eb32..fe5a4d8 100644
--- a/ui/ui-core/src/main/java/androidx/ui/graphics/vectorgraphics/PathParser.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/graphics/vectorgraphics/PathParser.kt
@@ -725,7 +725,7 @@
         val resultLength = end - start
         val copyLength = Math.min(resultLength, originalLength - start)
         val result = FloatArray(resultLength)
-        System.arraycopy(original, start, result, 0, copyLength)
+        original.copyInto(result, 0, start, start + copyLength)
         return result
     }
 
@@ -774,4 +774,4 @@
         var endPosition: Int = 0,
         var endWithNegativeOrDot: Boolean = false
     )
-}
\ No newline at end of file
+}
diff --git a/ui/ui-core/src/main/java/androidx/ui/graphics/vectorgraphics/Vector.kt b/ui/ui-core/src/main/java/androidx/ui/graphics/vectorgraphics/Vector.kt
deleted file mode 100644
index 920b59e..0000000
--- a/ui/ui-core/src/main/java/androidx/ui/graphics/vectorgraphics/Vector.kt
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Copyright 2019 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.ui.graphics.vectorgraphics
-
-import android.graphics.Matrix
-import androidx.ui.engine.geometry.Offset
-import androidx.ui.painting.Canvas
-import androidx.ui.painting.Image
-import androidx.ui.painting.Paint
-import androidx.ui.painting.PaintingStyle
-import androidx.ui.painting.Path
-import androidx.ui.painting.StrokeCap
-import androidx.ui.painting.StrokeJoin
-import androidx.compose.Children
-import androidx.compose.Composable
-import androidx.compose.Emittable
-import androidx.compose.composer
-import androidx.ui.core.Px
-import androidx.ui.painting.withSave
-import kotlin.math.ceil
-
-const val DefaultGroupName = ""
-const val DefaultRotation = 0.0f
-const val DefaultPivotX = 0.0f
-const val DefaultPivotY = 0.0f
-const val DefaultScaleX = 1.0f
-const val DefaultScaleY = 1.0f
-const val DefaultTranslationX = 0.0f
-const val DefaultTranslationY = 0.0f
-
-val EmptyPath = emptyArray<PathNode>()
-
-/**
- * paint used to draw the cached vector graphic to the provided canvas
- * TODO (njawad) Can we update the Crane Canvas API to make this paint optional?
- */
-internal val EmptyPaint = Paint()
-
-class PathDelegate(val delegate: PathBuilder.() -> Unit)
-
-// TODO figure out how to use UNIONTYPE with a Lambda receiver. Cannot cast to KClass which is what
-// UnionType is expecting
-// TODO uncomment usage of UnionType when Compose can be accessed across modules
-typealias PathData = /*@UnionType(String::class, PathDelegate::class, Array<PathNode>::class)*/ Any?
-
-// TODO (njawad) change to color int
-typealias BrushType = /*@UnionType(Int::class, Brush::class)*/ Any
-
-const val DefaultPathName = ""
-const val DefaultAlpha = 1.0f
-const val DefaultStrokeLineWidth = 0.0f
-const val DefaultStrokeLineMiter = 4.0f
-
-val DefaultStrokeLineCap = StrokeCap.butt
-val DefaultStrokeLineJoin = StrokeJoin.miter
-
-fun addPathNodes(pathStr: String?): Array<PathNode> =
-    if (pathStr == null) {
-        EmptyPath
-    } else {
-        PathParser().parsePathString(pathStr).toNodes()
-    }
-
-sealed class VNode {
-    abstract fun draw(canvas: Canvas)
-}
-
-class VectorComponent(
-    val name: String = "",
-    var viewportWidth: Float,
-    var viewportHeight: Float,
-    var defaultWidth: Px,
-    var defaultHeight: Px
-) : VNode() {
-
-    val root = GroupComponent(this@VectorComponent.name).apply {
-        pivotX = 0.0f
-        pivotY = 0.0f
-        scaleX = defaultWidth.value / viewportWidth
-        scaleY = defaultHeight.value / viewportHeight
-    }
-
-    /**
-     * Cached Image of the Vector Graphic to be re-used across draw calls
-     * if the Vector graphic is not dirty
-     */
-    // TODO (njawad) add invalidation logic to re-draw into the offscreen Image
-    private var cachedImage: Image? = null
-
-    val size: Int
-        get() = root.size
-
-    override fun draw(canvas: Canvas) {
-        var targetImage = cachedImage
-        if (targetImage == null) {
-            targetImage = Image(
-                ceil(defaultWidth.value).toInt(),
-                ceil(defaultHeight.value).toInt()
-            )
-            cachedImage = targetImage
-            root.draw(Canvas(targetImage))
-        }
-        canvas.drawImage(targetImage, Offset.zero, EmptyPaint)
-    }
-
-    override fun toString(): String {
-        return buildString {
-            append("Params: ")
-            append("\tname: ").append(name).append("\n")
-            append("\twidth: ").append(defaultWidth).append("\n")
-            append("\theight: ").append(defaultHeight).append("\n")
-            append("\tviewportWidth: ").append(viewportWidth).append("\n")
-            append("\tviewportHeight: ").append(viewportHeight).append("\n")
-        }
-    }
-}
-
-class PathComponent(val name: String) : VNode() {
-
-    var fill: Brush = EmptyBrush
-        set(value) {
-            field = value
-            updateFillPaint {
-                field.applyBrush(this)
-            }
-        }
-
-    var fillAlpha: Float = DefaultAlpha
-        set(value) {
-            field = value
-            updateFillPaint {
-                alpha = field
-            }
-        }
-
-    var pathNodes: Array<PathNode> = emptyArray()
-        set(value) {
-            field = value
-            isPathDirty = true
-        }
-
-    var strokeAlpha: Float = DefaultAlpha
-        set(value) {
-            field = value
-            updateStrokePaint {
-                alpha = field
-            }
-        }
-
-    var strokeLineWidth: Float = DefaultStrokeLineWidth
-        set(value) {
-            field = value
-            updateStrokePaint {
-                strokeWidth = field
-            }
-        }
-
-    var stroke: Brush = EmptyBrush
-        set(value) {
-            field = value
-            updateStrokePaint {
-                field.applyBrush(this)
-            }
-        }
-
-    var strokeLineCap: StrokeCap = DefaultStrokeLineCap
-        set(value) {
-            field = value
-            updateStrokePaint {
-                strokeCap = field
-            }
-        }
-
-    var strokeLineJoin: StrokeJoin = DefaultStrokeLineJoin
-        set(value) {
-            field = value
-            updateStrokePaint {
-                strokeJoin = field
-            }
-        }
-
-    var strokeLineMiter: Float = DefaultStrokeLineMiter
-        set(value) {
-            field = value
-            updateStrokePaint {
-                strokeMiterLimit = field
-            }
-        }
-
-    private var isPathDirty = true
-
-    private val path = Path()
-
-    private var fillPaint: Paint? = null
-    private var strokePaint: Paint? = null
-
-    private val parser = PathParser()
-
-    private fun updateStrokePaint(strokePaintUpdater: Paint.() -> Unit) {
-        if (strokePaint == null) {
-            strokePaint = createStrokePaint()
-        } else {
-            strokePaint?.strokePaintUpdater()
-        }
-    }
-
-    private fun createStrokePaint(): Paint = Paint().apply {
-        isAntiAlias = true
-        style = PaintingStyle.stroke
-        alpha = strokeAlpha
-        strokeWidth = strokeLineWidth
-        strokeCap = strokeLineCap
-        strokeJoin = strokeLineJoin
-        strokeMiterLimit = strokeLineMiter
-        stroke.applyBrush(this)
-    }
-
-    private fun updateFillPaint(fillPaintUpdater: Paint.() -> Unit) {
-        if (fillPaint == null) {
-            fillPaint = createFillPaint()
-        } else {
-            fillPaint?.fillPaintUpdater()
-        }
-    }
-
-    private fun createFillPaint(): Paint = Paint().apply {
-        isAntiAlias = true
-        alpha = fillAlpha
-        style = PaintingStyle.fill
-        fill.applyBrush(this)
-    }
-
-    private fun updatePath() {
-        parser.clear()
-        path.reset()
-        parser.addPathNodes(pathNodes).toPath(path)
-    }
-
-    override fun draw(canvas: Canvas) {
-        if (isPathDirty) {
-            updatePath()
-            isPathDirty = false
-        }
-
-        val fillBrush = fill
-        if (fillBrush !== EmptyBrush) {
-            var targetFillPaint = fillPaint
-            if (targetFillPaint == null) {
-                targetFillPaint = createFillPaint()
-                fillPaint = targetFillPaint
-            }
-            canvas.drawPath(path, targetFillPaint)
-        }
-
-        val strokeBrush = stroke
-        if (strokeBrush !== EmptyBrush) {
-            var targetStrokePaint = strokePaint
-            if (targetStrokePaint == null) {
-                targetStrokePaint = createStrokePaint()
-                strokePaint = targetStrokePaint
-            }
-            canvas.drawPath(path, targetStrokePaint)
-        }
-    }
-
-    override fun toString(): String {
-        return path.toString()
-    }
-}
-
-class GroupComponent(val name: String = DefaultGroupName) : VNode() {
-
-    private var groupMatrix: Matrix? = null
-
-    private val children = mutableListOf<VNode>()
-
-    var clipPathNodes: Array<PathNode> = EmptyPath
-        set(value) {
-            field = value
-            isClipPathDirty = true
-        }
-
-    private val willClipPath: Boolean
-        get() = clipPathNodes.isNotEmpty()
-
-    private var isClipPathDirty = true
-
-    private var clipPath: Path? = null
-    private var parser: PathParser? = null
-
-    private fun updateClipPath() {
-        if (willClipPath) {
-            var targetParser = parser
-            if (targetParser == null) {
-                targetParser = PathParser()
-                parser = targetParser
-            } else {
-                targetParser.clear()
-            }
-
-            var targetClip = clipPath
-            if (targetClip == null) {
-                targetClip = Path()
-                clipPath = targetClip
-            } else {
-                targetClip.reset()
-            }
-
-            targetParser.addPathNodes(clipPathNodes).toPath(targetClip)
-        }
-    }
-
-    var rotation: Float = DefaultRotation
-        set(value) {
-            field = value
-            isMatrixDirty = true
-        }
-
-    var pivotX: Float = DefaultPivotX
-        set(value) {
-            field = value
-            isMatrixDirty = true
-        }
-
-    var pivotY: Float = DefaultPivotY
-        set(value) {
-            field = value
-            isMatrixDirty = true
-        }
-
-    var scaleX: Float = DefaultScaleX
-        set(value) {
-            field = value
-            isMatrixDirty = true
-        }
-
-    var scaleY: Float = DefaultScaleY
-        set(value) {
-            field = value
-            isMatrixDirty = true
-        }
-
-    var translationX: Float = DefaultTranslationX
-        set(value) {
-            field = value
-            isMatrixDirty = true
-        }
-
-    var translationY: Float = DefaultTranslationY
-        set(value) {
-            field = value
-            isMatrixDirty = true
-        }
-
-    private var isMatrixDirty = true
-
-    private fun updateMatrix() {
-        val matrix: Matrix
-        val target = groupMatrix
-        if (target == null) {
-            matrix = Matrix()
-            groupMatrix = matrix
-        } else {
-            matrix = target
-        }
-        with(matrix) {
-            reset()
-            postTranslate(-pivotX, -pivotY)
-            postScale(scaleX, scaleY)
-            postRotate(rotation, 0f, 0f)
-            postTranslate(translationX + pivotX,
-                translationY + pivotY)
-        }
-    }
-
-    fun insertAt(index: Int, instance: VNode) {
-        if (index < size) {
-            children[index] = instance
-        } else {
-            children.add(instance)
-        }
-    }
-
-    fun move(from: Int, to: Int, count: Int) {
-        if (from > to) {
-            var current = to
-            repeat(count) {
-                val node = children[from]
-                children.removeAt(from)
-                children.add(current, node)
-                current++
-            }
-        } else {
-            repeat(count) {
-                val node = children[from]
-                children.removeAt(from)
-                children.add(to - 1, node)
-            }
-        }
-    }
-
-    fun remove(index: Int, count: Int) {
-        repeat(count) {
-            children.removeAt(index)
-        }
-    }
-
-    override fun draw(canvas: Canvas) {
-        if (isMatrixDirty) {
-            updateMatrix()
-            isMatrixDirty = false
-        }
-
-        if (isClipPathDirty) {
-            updateClipPath()
-            isClipPathDirty = false
-        }
-
-        canvas.withSave {
-            val targetClip = clipPath
-            if (willClipPath && targetClip != null) {
-                canvas.clipPath(targetClip)
-            }
-
-            val matrix = groupMatrix
-            if (matrix != null) {
-                // TODO (njawad) add concat support to matrix
-                canvas.nativeCanvas.concat(matrix)
-            }
-
-            for (node in children) {
-                node.draw(canvas)
-            }
-        }
-    }
-
-    val size: Int
-        get() = children.size
-
-    override fun toString(): String {
-        val sb = StringBuilder().append("VGroup: ").append(name)
-        for (node in children) {
-            sb.append("\t").append(node.toString()).append("\n")
-        }
-        return sb.toString()
-    }
-}
-
-fun createPath(pathData: PathData): Array<PathNode> {
-    @Suppress("UNCHECKED_CAST")
-    return when (pathData) {
-        is Array<*> -> pathData as Array<PathNode>
-        is PathDelegate -> {
-            with(PathBuilder()) {
-                pathData.delegate(this)
-                getNodes()
-            }
-        }
-        else -> throw IllegalArgumentException("Must be array of PathNodes or PathDelegate")
-    }
-}
\ No newline at end of file
diff --git a/ui/ui-core/src/main/java/androidx/ui/semantics/SemanticsActions.kt b/ui/ui-core/src/main/java/androidx/ui/semantics/SemanticsActions.kt
deleted file mode 100644
index c1511f5..0000000
--- a/ui/ui-core/src/main/java/androidx/ui/semantics/SemanticsActions.kt
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright 2019 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.ui.core.semantics
-
-import androidx.ui.text.TextSelection
-
-private const val INDEX_TAP = 1 shl 0
-private const val INDEX_LONG_PRESS = 1 shl 1
-private const val INDEX_SCROLL_LEFT = 1 shl 2
-private const val INDEX_SCROLL_RIGHT = 1 shl 3
-private const val INDEX_SCROLL_UP = 1 shl 4
-private const val INDEX_SCROLL_DOWN = 1 shl 5
-private const val INDEX_INCREASE = 1 shl 6
-private const val INDEX_DECREASE = 1 shl 7
-private const val INDEX_SHOW_ON_SCREEN = 1 shl 8
-private const val INDEX_MOVE_CURSOR_FORWARD_BY_CHARACTER = 1 shl 9
-private const val INDEX_MOVE_CURSOR_BACKWARD_BY_CHARACTER = 1 shl 10
-private const val INDEX_SET_SELECTION = 1 shl 11
-private const val INDEX_COPY = 1 shl 12
-private const val INDEX_CUT = 1 shl 13
-private const val INDEX_PASTE = 1 shl 14
-private const val INDEX_DID_GAIN_ACCESSIBILITY_FOCUS = 1 shl 15
-private const val INDEX_DID_LOSE_ACCESSIBILITY_FOCUS = 1 shl 16
-private const val INDEX_CUSTOM_ACTION = 1 shl 17
-private const val INDEX_DISMISS = 1 shl 18
-private const val INDEX_MOVE_CURSOR_FORWARD_BY_WORD = 1 shl 19
-private const val INDEX_MOVE_CURSOR_BACKWARD_BY_WORD = 1 shl 20
-
-private typealias VoidCallback = () -> Unit
-
-/**
- * Signature for [SemanticsActionType]s that move the cursor.
- *
- * If `extendSelection` is set to true the cursor movement should extend the
- * current selection or (if nothing is currently selected) start a selection.
- */
-typealias MoveCursorHandler = (extendSelection: Boolean) -> Unit
-
-/**
- * Signature for the [SemanticsActionType.SetSelection] handlers to change the
- * text selection (or re-position the cursor) to `selection`.
- */
-typealias SetSelectionHandler = (selection: TextSelection) -> Unit
-
-data class SemanticsAction<T : Any>(val type: SemanticsActionType<T>, val handler: T) {
-    fun invokeHandler(args: Any?) {
-        @Suppress("UNCHECKED_CAST")
-        when (type.numArguments) {
-            0 -> (handler as VoidCallback)()
-            1 -> (handler as (Any?) -> Unit)(args)
-            else -> throw IllegalStateException("Invalid number of arguments: ${type.numArguments}")
-        }
-    }
-}
-
-/**
- * The possible actions that can be conveyed from the operating system
- * accessibility APIs to a semantics node.
- */
-class SemanticsActionType<T> private constructor(
-    /**
-     * The name of the action.
-     */
-    private val name: String,
-    /**
-     * The numerical value for this action.
-     *
-     * Each action has one bit set in this bit field.
-     */
-    // TODO(ryanmentley): this should be internal, but can't because we need it from other packages
-    val bitmask: Int,
-    internal val numArguments: Int
-) {
-    companion object {
-        /**
-         * The equivalent of a user briefly tapping the screen with the finger
-         * without moving it.
-         */
-        val Tap = SemanticsActionType<VoidCallback>("Tap", INDEX_TAP, 0)
-
-        /**
-         * The equivalent of a user pressing and holding the screen with the finger
-         * for a few seconds without moving it.
-         */
-        val LongPress = SemanticsActionType<VoidCallback>("LongPress", INDEX_LONG_PRESS, 0)
-
-        /**
-         * The equivalent of a user moving their finger across the screen from right
-         * to left.
-         *
-         * This action should be recognized by controls that are horizontally
-         * scrollable.
-         */
-        val ScrollLeft = SemanticsActionType<VoidCallback>("ScrollLeft", INDEX_SCROLL_LEFT, 0)
-
-        /**
-         * The equivalent of a user moving their finger across the screen from left
-         * to right.
-         *
-         * This action should be recognized by controls that are horizontally
-         * scrollable.
-         */
-        val ScrollRight = SemanticsActionType<VoidCallback>("ScrollRight", INDEX_SCROLL_RIGHT, 0)
-
-        /**
-         * The equivalent of a user moving their finger across the screen from
-         * bottom to top.
-         *
-         * This action should be recognized by controls that are vertically
-         * scrollable.
-         */
-        val ScrollUp = SemanticsActionType<VoidCallback>("ScrollUp", INDEX_SCROLL_UP, 0)
-
-        /**
-         * The equivalent of a user moving their finger across the screen from top
-         * to bottom.
-         *
-         * This action should be recognized by controls that are vertically
-         * scrollable.
-         */
-        val ScrollDown = SemanticsActionType<VoidCallback>("ScrollDown", INDEX_SCROLL_DOWN, 0)
-
-        /**
-         * A request to increase the value represented by the semantics node.
-         *
-         * For example, this action might be recognized by a slider control.
-         */
-        val Increase = SemanticsActionType<VoidCallback>("Increase", INDEX_INCREASE, 0)
-
-        /**
-         * A request to decrease the value represented by the semantics node.
-         *
-         * For example, this action might be recognized by a slider control.
-         */
-        val Decrease = SemanticsActionType<VoidCallback>("Decrease", INDEX_DECREASE, 0)
-
-        /**
-         * A request to fully show the semantics node on screen.
-         *
-         * For example, this action might be send to a node in a scrollable list that
-         * is partially off screen to bring it on screen.
-         */
-        val ShowOnScreen = SemanticsActionType<VoidCallback>(
-            "ShowOnScreen", INDEX_SHOW_ON_SCREEN, 0
-        )
-
-        /**
-         * Move the cursor forward by one character.
-         *
-         * This is for example used by the cursor control in text fields.
-         *
-         * The action includes a boolean argument, which indicates whether the cursor
-         * movement should extend (or start) a selection.
-         */
-        val MoveCursorForwardByCharacter = SemanticsActionType<MoveCursorHandler>(
-            "MoveCursorForwardByCharacter", INDEX_MOVE_CURSOR_FORWARD_BY_CHARACTER, 1
-        )
-
-        /**
-         * Move the cursor backward by one character.
-         *
-         * This is for example used by the cursor control in text fields.
-         *
-         * The action includes a boolean argument, which indicates whether the cursor
-         * movement should extend (or start) a selection.
-         */
-        val MoveCursorBackwardByCharacter = SemanticsActionType<MoveCursorHandler>(
-            "MoveCursorBackwardByCharacter", INDEX_MOVE_CURSOR_BACKWARD_BY_CHARACTER, 1
-        )
-
-        /**
-         * Set the text selection to the given range.
-         *
-         * The provided argument is a Map<String, int> which includes the keys `base`
-         * and `extent` indicating where the selection within the `value` of the
-         * semantics node should start and where it should end. Values for both
-         * keys can range from 0 to length of `value` (inclusive).
-         *
-         * Setting `base` and `extent` to the same value will move the cursor to
-         * that position (without selecting anything).
-         */
-        val SetSelection = SemanticsActionType<SetSelectionHandler>(
-            "SetSelection", INDEX_SET_SELECTION, 1
-        )
-
-        /** Copy the current selection to the clipboard. */
-        val Copy = SemanticsActionType<VoidCallback>("Copy", INDEX_COPY, 0)
-
-        /** Cut the current selection and place it in the clipboard. */
-        val Cut = SemanticsActionType<VoidCallback>("Cut", INDEX_CUT, 0)
-
-        /** Paste the current content of the clipboard. */
-        val Paste = SemanticsActionType<VoidCallback>("Paste", INDEX_PASTE, 0)
-
-        /**
-         * Indicates that the nodes has gained accessibility focus.
-         *
-         * This handler is invoked when the node annotated with this handler gains
-         * the accessibility focus. The accessibility focus is the
-         * green (on Android with TalkBack) or black (on iOS with VoiceOver)
-         * rectangle shown on screen to indicate what element an accessibility
-         * user is currently interacting with.
-         *
-         * The accessibility focus is different from the input focus. The input focus
-         * is usually held by the element that currently responds to keyboard inputs.
-         * Accessibility focus and input focus can be held by two different nodes!
-         */
-        val DidGainAccessibilityFocus = SemanticsActionType<VoidCallback>(
-            "DidGainAccessibilityFocus", INDEX_DID_GAIN_ACCESSIBILITY_FOCUS, 0
-        )
-
-        /**
-         * Indicates that the nodes has lost accessibility focus.
-         *
-         * This handler is invoked when the node annotated with this handler
-         * loses the accessibility focus. The accessibility focus is
-         * the green (on Android with TalkBack) or black (on iOS with VoiceOver)
-         * rectangle shown on screen to indicate what element an accessibility
-         * user is currently interacting with.
-         *
-         * The accessibility focus is different from the input focus. The input focus
-         * is usually held by the element that currently responds to keyboard inputs.
-         * Accessibility focus and input focus can be held by two different nodes!
-         */
-        val DidLoseAccessibilityFocus = SemanticsActionType<VoidCallback>(
-            "DidLoseAccessibilityFocus", INDEX_DID_LOSE_ACCESSIBILITY_FOCUS, 0
-        )
-
-        /**
-         * Indicates that the user has invoked a custom accessibility action.
-         *
-         * This handler is added automatically whenever a custom accessibility
-         * action is added to a semantics node.
-         */
-        // TODO(ryanmentley): this needs parameters
-        val CustomAction = SemanticsActionType<VoidCallback>(
-            "CustomAction", INDEX_CUSTOM_ACTION, 0
-        )
-
-        /**
-         * A request that the node should be dismissed.
-         *
-         * A [Snackbar], for example, may have a dismiss action to indicate to the
-         * user that it can be removed after it is no longer relevant. On Android,
-         * (with TalkBack) special hint text is spoken when focusing the node and
-         * a custom action is availible in the local context menu. On iOS,
-         * (with VoiceOver) users can perform a standard gesture to dismiss it.
-         */
-        val Dismiss = SemanticsActionType<VoidCallback>("Dismiss", INDEX_DISMISS, 0)
-
-        /**
-         * Move the cursor forward by one word.
-         *
-         * This is for example used by the cursor control in text fields.
-         *
-         * The action includes a boolean argument, which indicates whether the cursor
-         * movement should extend (or start) a selection.
-         */
-        val MoveCursorForwardByWord = SemanticsActionType<MoveCursorHandler>(
-            "MoveCursorForwardByWord", INDEX_MOVE_CURSOR_FORWARD_BY_WORD, 1
-        )
-
-        /**
-         * Move the cursor backward by one word.
-         *
-         * This is for example used by the cursor control in text fields.
-         *
-         * The action includes a boolean argument, which indicates whether the cursor
-         * movement should extend (or start) a selection.
-         */
-        val MoveCursorBackwardByWord = SemanticsActionType<MoveCursorHandler>(
-            "MoveCursorBackwardByWord", INDEX_MOVE_CURSOR_BACKWARD_BY_WORD, 1
-        )
-
-        /**
-         * The possible semantics actions.
-         *
-         * The map's key is the [bitmask] of the action and the value is the action
-         * itself.
-         */
-        // TODO(ryanmentley): maybe unneeded, remove if not needed in final impl
-        private val values: Map<Int, SemanticsActionType<*>> = mapOf(
-            INDEX_TAP to Tap,
-            INDEX_LONG_PRESS to LongPress,
-            INDEX_SCROLL_LEFT to ScrollLeft,
-            INDEX_SCROLL_RIGHT to ScrollRight,
-            INDEX_SCROLL_UP to ScrollUp,
-            INDEX_SCROLL_DOWN to ScrollDown,
-            INDEX_INCREASE to Increase,
-            INDEX_DECREASE to Decrease,
-            INDEX_SHOW_ON_SCREEN to ShowOnScreen,
-            INDEX_MOVE_CURSOR_FORWARD_BY_CHARACTER to MoveCursorForwardByCharacter,
-            INDEX_MOVE_CURSOR_BACKWARD_BY_CHARACTER to MoveCursorBackwardByCharacter,
-            INDEX_SET_SELECTION to SetSelection,
-            INDEX_COPY to Copy,
-            INDEX_CUT to Cut,
-            INDEX_PASTE to Paste,
-            INDEX_DID_GAIN_ACCESSIBILITY_FOCUS to DidGainAccessibilityFocus,
-            INDEX_DID_LOSE_ACCESSIBILITY_FOCUS to DidLoseAccessibilityFocus,
-            INDEX_CUSTOM_ACTION to CustomAction,
-            INDEX_DISMISS to Dismiss,
-            INDEX_MOVE_CURSOR_FORWARD_BY_WORD to MoveCursorForwardByWord,
-            INDEX_MOVE_CURSOR_BACKWARD_BY_WORD to MoveCursorBackwardByWord
-        )
-    }
-
-    override fun toString(): String {
-        return "SemanticsActionType.$name"
-    }
-}
\ No newline at end of file
diff --git a/ui/ui-core/src/main/java/androidx/ui/semantics/SemanticsProperties.kt b/ui/ui-core/src/main/java/androidx/ui/semantics/SemanticsProperties.kt
new file mode 100644
index 0000000..a0a9251
--- /dev/null
+++ b/ui/ui-core/src/main/java/androidx/ui/semantics/SemanticsProperties.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2019 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.ui.semantics
+
+import kotlin.properties.ReadWriteProperty
+import kotlin.reflect.KProperty
+
+open class SemanticsPropertyKey<T>(
+    /**
+     * The name of the property.  Should be the same as the constant from which it is accessed.
+     */
+    val name: String
+) :
+    ReadWriteProperty<SemanticsPropertyReceiver, T> {
+    /**
+     * Subclasses that wish to implement merging should override this to output the merged value
+     *
+     * This implementation always throws IllegalStateException.  It should be overridden for
+     * properties that can be merged.
+     */
+    open fun merge(existingValue: T, newValue: T): T {
+        throw IllegalStateException(
+            "merge function called on unmergeable property $name.  " +
+                    "You may need to add a semantic boundary."
+        )
+    }
+
+    /**
+     * Throws [UnsupportedOperationException].  Should not be called.
+     */
+    // noinspection DeprecatedCallableAddReplaceWith
+    // TODO(KT-32770): Re-deprecate this
+    // @Deprecated(
+    //     message = "You cannot retrieve a semantics property directly - " +
+    //             "use one of the SemanticsConfiguration.getOr* methods instead",
+    //     level = DeprecationLevel.ERROR
+    // )
+    // TODO(KT-6519): Remove this getter entirely
+    final override fun getValue(thisRef: SemanticsPropertyReceiver, property: KProperty<*>): T {
+        throw UnsupportedOperationException(
+            "You cannot retrieve a semantics property directly - " +
+                    "use one of the SemanticsConfiguration.getOr* methods instead"
+        )
+    }
+
+    final override fun setValue(
+        thisRef: SemanticsPropertyReceiver,
+        property: KProperty<*>,
+        value: T
+    ) {
+        thisRef[this] = value
+    }
+}
+
+// This needs to be in core because it needs to be accessible from platform
+data class AccessibilityAction<T : Function<Unit>>(val label: String?, val action: T)
+
+interface SemanticsPropertyReceiver {
+    operator fun <T> set(key: SemanticsPropertyKey<T>, value: T)
+}
diff --git a/ui/ui-core/src/main/java/androidx/ui/testutils/PointerInputTestUtil.kt b/ui/ui-core/src/main/java/androidx/ui/testutils/PointerInputTestUtil.kt
index e00bfbf..0f792b2 100644
--- a/ui/ui-core/src/main/java/androidx/ui/testutils/PointerInputTestUtil.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/testutils/PointerInputTestUtil.kt
@@ -106,4 +106,4 @@
     PointerEventPass.PreDown,
     PointerEventPass.PostUp,
     PointerEventPass.PostDown
-)
\ No newline at end of file
+)
diff --git a/ui/ui-core/src/test/java/androidx/ui/autofill/AutofillNodeTest.kt b/ui/ui-core/src/test/java/androidx/ui/autofill/AutofillNodeTest.kt
new file mode 100644
index 0000000..d6afd3e
--- /dev/null
+++ b/ui/ui-core/src/test/java/androidx/ui/autofill/AutofillNodeTest.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 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.ui.autofill
+
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class AutofillNodeTest {
+    @Test
+    fun eachInstanceHasUniqueId() {
+        assertThat(listOf(AutofillNode {}.id, AutofillNode {}.id, AutofillNode {}.id))
+            .containsNoDuplicates()
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-foundation/api/1.0.0-alpha01.txt b/ui/ui-foundation/api/1.0.0-alpha01.txt
index f0ceb44..782f0c2 100644
--- a/ui/ui-foundation/api/1.0.0-alpha01.txt
+++ b/ui/ui-foundation/api/1.0.0-alpha01.txt
@@ -8,10 +8,15 @@
 
   public final class ColoredRectKt {
     ctor public ColoredRectKt();
-    method public static void ColoredRect(androidx.ui.graphics.vectorgraphics.Brush brush, androidx.ui.core.Dp? width = null, androidx.ui.core.Dp? height = null);
+    method public static void ColoredRect(androidx.ui.graphics.Brush brush, androidx.ui.core.Dp? width = null, androidx.ui.core.Dp? height = null);
     method public static void ColoredRect(androidx.ui.graphics.Color color, androidx.ui.core.Dp? width = null, androidx.ui.core.Dp? height = null);
   }
 
+  public final class DarkThemeKt {
+    ctor public DarkThemeKt();
+    method public static androidx.compose.Effect<java.lang.Boolean> isSystemInDarkTheme();
+  }
+
   public final class DeterminateProgressIndicatorKt {
     ctor public DeterminateProgressIndicatorKt();
     method public static void DeterminateProgressIndicator(@FloatRange(from=0.0, to=1.0) float progress, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -22,11 +27,45 @@
     method public static void Dialog(kotlin.jvm.functions.Function0<kotlin.Unit> onCloseRequest, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
+  public final class DrawBordersReceiver {
+    method public void all(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void allHorizontal(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void allVertical(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void bottom(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public int getColumnCount();
+    method public int getRowCount();
+    method public void horizontal(int row, kotlin.ranges.IntRange columns = 0 <other> columnCount, androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void left(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void outer(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void right(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void top(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void vertical(int column, kotlin.ranges.IntRange rows = 0 <other> rowCount, androidx.ui.foundation.shape.border.Border border = defaultBorder);
+  }
+
   public final class SimpleImageKt {
     ctor public SimpleImageKt();
     method public static void SimpleImage(androidx.ui.painting.Image image, androidx.ui.graphics.Color? tint = null);
   }
 
+  public final class Strings {
+    method public String getChecked();
+    method public String getIndeterminate();
+    method public String getNotSelected();
+    method public String getSelected();
+    method public String getUnchecked();
+    property public final String Checked;
+    property public final String Indeterminate;
+    property public final String NotSelected;
+    property public final String Selected;
+    property public final String Unchecked;
+    field public static final androidx.ui.foundation.Strings! INSTANCE;
+  }
+
+  public final class TableBordersKt {
+    ctor public TableBordersKt();
+    method public static void drawBorders(androidx.ui.layout.TableChildren, androidx.ui.foundation.shape.border.Border defaultBorder = Border(Color.Black, Dp.Hairline), kotlin.jvm.functions.Function1<? super androidx.ui.foundation.DrawBordersReceiver,kotlin.Unit> block);
+  }
+
 }
 
 package androidx.ui.foundation.animation {
@@ -127,12 +166,36 @@
 
 }
 
+package androidx.ui.foundation.semantics {
+
+  public final class FoundationSemanticsProperties {
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getInMutuallyExclusiveGroup();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getSelected();
+    method public androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.foundation.selection.ToggleableState> getToggleableState();
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> InMutuallyExclusiveGroup;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Selected;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.foundation.selection.ToggleableState> ToggleableState;
+    field public static final androidx.ui.foundation.semantics.FoundationSemanticsProperties! INSTANCE;
+  }
+
+  public final class FoundationSemanticsPropertiesKt {
+    ctor public FoundationSemanticsPropertiesKt();
+    method public static boolean getInMutuallyExclusiveGroup(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static boolean getSelected(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.ui.foundation.selection.ToggleableState getToggleableState(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static void setInMutuallyExclusiveGroup(androidx.ui.semantics.SemanticsPropertyReceiver, boolean p);
+    method public static void setSelected(androidx.ui.semantics.SemanticsPropertyReceiver, boolean p);
+    method public static void setToggleableState(androidx.ui.semantics.SemanticsPropertyReceiver, androidx.ui.foundation.selection.ToggleableState p);
+  }
+
+}
+
 package androidx.ui.foundation.shape {
 
   public final class DrawShapeKt {
     ctor public DrawShapeKt();
     method public static void DrawShape(androidx.ui.engine.geometry.Shape shape, androidx.ui.graphics.Color color);
-    method public static void DrawShape(androidx.ui.engine.geometry.Shape shape, androidx.ui.graphics.vectorgraphics.Brush brush);
+    method public static void DrawShape(androidx.ui.engine.geometry.Shape shape, androidx.ui.graphics.Brush brush);
   }
 
   public final class GenericShape implements androidx.ui.engine.geometry.Shape {
@@ -151,11 +214,11 @@
 package androidx.ui.foundation.shape.border {
 
   public final class Border {
-    ctor public Border(androidx.ui.graphics.vectorgraphics.Brush brush, androidx.ui.core.Dp width);
-    method public androidx.ui.graphics.vectorgraphics.Brush component1();
+    ctor public Border(androidx.ui.graphics.Brush brush, androidx.ui.core.Dp width);
+    method public androidx.ui.graphics.Brush component1();
     method public androidx.ui.core.Dp component2();
-    method public androidx.ui.foundation.shape.border.Border copy(androidx.ui.graphics.vectorgraphics.Brush brush, androidx.ui.core.Dp width);
-    method public androidx.ui.graphics.vectorgraphics.Brush getBrush();
+    method public androidx.ui.foundation.shape.border.Border copy(androidx.ui.graphics.Brush brush, androidx.ui.core.Dp width);
+    method public androidx.ui.graphics.Brush getBrush();
     method public androidx.ui.core.Dp getWidth();
   }
 
@@ -174,9 +237,9 @@
 package androidx.ui.foundation.shape.corner {
 
   public abstract class CornerBasedShape implements androidx.ui.engine.geometry.Shape {
-    ctor public CornerBasedShape(androidx.ui.foundation.shape.corner.CornerSizes corners);
+    ctor public CornerBasedShape(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
     method public final androidx.ui.engine.geometry.Outline createOutline(androidx.ui.core.PxSize size, androidx.ui.core.Density density);
-    method public abstract androidx.ui.engine.geometry.Outline createOutline(androidx.ui.foundation.shape.corner.PxCornerSizes corners, androidx.ui.core.PxSize size);
+    method public abstract androidx.ui.engine.geometry.Outline createOutline(androidx.ui.core.PxSize size, androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
   }
 
   public interface CornerSize {
@@ -192,60 +255,29 @@
     method public static androidx.ui.foundation.shape.corner.CornerSize getZeroCornerSize();
   }
 
-  public final class CornerSizes {
-    ctor public CornerSizes(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+  public final class RoundedCornerShape extends androidx.ui.foundation.shape.corner.CornerBasedShape {
+    ctor public RoundedCornerShape(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
     method public androidx.ui.foundation.shape.corner.CornerSize component1();
     method public androidx.ui.foundation.shape.corner.CornerSize component2();
     method public androidx.ui.foundation.shape.corner.CornerSize component3();
     method public androidx.ui.foundation.shape.corner.CornerSize component4();
-    method public androidx.ui.foundation.shape.corner.CornerSizes copy(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+    method public androidx.ui.foundation.shape.corner.RoundedCornerShape copy(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+    method public androidx.ui.engine.geometry.Outline.Rounded createOutline(androidx.ui.core.PxSize size, androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
     method public androidx.ui.foundation.shape.corner.CornerSize getBottomLeft();
     method public androidx.ui.foundation.shape.corner.CornerSize getBottomRight();
     method public androidx.ui.foundation.shape.corner.CornerSize getTopLeft();
     method public androidx.ui.foundation.shape.corner.CornerSize getTopRight();
   }
 
-  public final class CornerSizesKt {
-    ctor public CornerSizesKt();
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.foundation.shape.corner.CornerSize allCornersSize);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.core.Dp size);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.core.Px size);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(int percent);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.core.Dp topLeft = 0.dp, androidx.ui.core.Dp topRight = 0.dp, androidx.ui.core.Dp bottomRight = 0.dp, androidx.ui.core.Dp bottomLeft = 0.dp);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.core.Px topLeft = 0.px, androidx.ui.core.Px topRight = 0.px, androidx.ui.core.Px bottomRight = 0.px, androidx.ui.core.Px bottomLeft = 0.px);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(@IntRange(from=0, to=50) int topLeftPercent = 0, @IntRange(from=0, to=50) int topRightPercent = 0, @IntRange(from=0, to=50) int bottomRightPercent = 0, @IntRange(from=0, to=50) int bottomLeftPercent = 0);
-  }
-
-  public final class PxCornerSizes {
-    ctor public PxCornerSizes(androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
-    method public androidx.ui.core.Px component1();
-    method public androidx.ui.core.Px component2();
-    method public androidx.ui.core.Px component3();
-    method public androidx.ui.core.Px component4();
-    method public androidx.ui.foundation.shape.corner.PxCornerSizes copy(androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
-    method public androidx.ui.core.Px getBottomLeft();
-    method public androidx.ui.core.Px getBottomRight();
-    method public androidx.ui.core.Px getTopLeft();
-    method public androidx.ui.core.Px getTopRight();
-  }
-
-  public final class PxCornerSizesKt {
-    ctor public PxCornerSizesKt();
-    method public static androidx.ui.foundation.shape.corner.PxCornerSizes PxCornerSizes(androidx.ui.foundation.shape.corner.CornerSizes corners, androidx.ui.core.PxSize size, androidx.ui.core.Density density);
-    method public static boolean isEmpty(androidx.ui.foundation.shape.corner.PxCornerSizes);
-  }
-
-  public final class RoundedCornerShape extends androidx.ui.foundation.shape.corner.CornerBasedShape {
-    ctor public RoundedCornerShape(androidx.ui.foundation.shape.corner.CornerSizes corners);
-    method public androidx.ui.foundation.shape.corner.CornerSizes component1();
-    method public androidx.ui.foundation.shape.corner.RoundedCornerShape copy(androidx.ui.foundation.shape.corner.CornerSizes corners);
-    method public androidx.ui.engine.geometry.Outline.Rounded createOutline(androidx.ui.foundation.shape.corner.PxCornerSizes corners, androidx.ui.core.PxSize size);
-    method public androidx.ui.foundation.shape.corner.CornerSizes getCorners();
-  }
-
   public final class RoundedCornerShapeKt {
     ctor public RoundedCornerShapeKt();
     method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.foundation.shape.corner.CornerSize corner);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.core.Dp size);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.core.Px size);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(int percent);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.core.Dp topLeft = 0.dp, androidx.ui.core.Dp topRight = 0.dp, androidx.ui.core.Dp bottomRight = 0.dp, androidx.ui.core.Dp bottomLeft = 0.dp);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.core.Px topLeft = 0.px, androidx.ui.core.Px topRight = 0.px, androidx.ui.core.Px bottomRight = 0.px, androidx.ui.core.Px bottomLeft = 0.px);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(@IntRange(from=0, to=50) int topLeftPercent = 0, @IntRange(from=0, to=50) int topRightPercent = 0, @IntRange(from=0, to=50) int bottomRightPercent = 0, @IntRange(from=0, to=50) int bottomLeftPercent = 0);
     method public static androidx.ui.foundation.shape.corner.RoundedCornerShape getCircleShape();
   }
 
diff --git a/ui/ui-foundation/api/api_lint.ignore b/ui/ui-foundation/api/api_lint.ignore
new file mode 100644
index 0000000..aa6815f
--- /dev/null
+++ b/ui/ui-foundation/api/api_lint.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+MissingNullability: androidx.ui.foundation.Strings#INSTANCE:
+    Missing nullability on field `INSTANCE` in class `class androidx.ui.foundation.Strings`
+MissingNullability: androidx.ui.foundation.gestures.DragDirection.Horizontal#INSTANCE:
+    Missing nullability on field `INSTANCE` in class `class androidx.ui.foundation.gestures.DragDirection.Horizontal`
+MissingNullability: androidx.ui.foundation.gestures.DragDirection.Vertical#INSTANCE:
+    Missing nullability on field `INSTANCE` in class `class androidx.ui.foundation.gestures.DragDirection.Vertical`
+MissingNullability: androidx.ui.foundation.semantics.FoundationSemanticsProperties#INSTANCE:
+    Missing nullability on field `INSTANCE` in class `class androidx.ui.foundation.semantics.FoundationSemanticsProperties`
diff --git a/ui/ui-foundation/api/current.txt b/ui/ui-foundation/api/current.txt
index f0ceb44..782f0c2 100644
--- a/ui/ui-foundation/api/current.txt
+++ b/ui/ui-foundation/api/current.txt
@@ -8,10 +8,15 @@
 
   public final class ColoredRectKt {
     ctor public ColoredRectKt();
-    method public static void ColoredRect(androidx.ui.graphics.vectorgraphics.Brush brush, androidx.ui.core.Dp? width = null, androidx.ui.core.Dp? height = null);
+    method public static void ColoredRect(androidx.ui.graphics.Brush brush, androidx.ui.core.Dp? width = null, androidx.ui.core.Dp? height = null);
     method public static void ColoredRect(androidx.ui.graphics.Color color, androidx.ui.core.Dp? width = null, androidx.ui.core.Dp? height = null);
   }
 
+  public final class DarkThemeKt {
+    ctor public DarkThemeKt();
+    method public static androidx.compose.Effect<java.lang.Boolean> isSystemInDarkTheme();
+  }
+
   public final class DeterminateProgressIndicatorKt {
     ctor public DeterminateProgressIndicatorKt();
     method public static void DeterminateProgressIndicator(@FloatRange(from=0.0, to=1.0) float progress, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -22,11 +27,45 @@
     method public static void Dialog(kotlin.jvm.functions.Function0<kotlin.Unit> onCloseRequest, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
+  public final class DrawBordersReceiver {
+    method public void all(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void allHorizontal(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void allVertical(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void bottom(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public int getColumnCount();
+    method public int getRowCount();
+    method public void horizontal(int row, kotlin.ranges.IntRange columns = 0 <other> columnCount, androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void left(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void outer(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void right(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void top(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void vertical(int column, kotlin.ranges.IntRange rows = 0 <other> rowCount, androidx.ui.foundation.shape.border.Border border = defaultBorder);
+  }
+
   public final class SimpleImageKt {
     ctor public SimpleImageKt();
     method public static void SimpleImage(androidx.ui.painting.Image image, androidx.ui.graphics.Color? tint = null);
   }
 
+  public final class Strings {
+    method public String getChecked();
+    method public String getIndeterminate();
+    method public String getNotSelected();
+    method public String getSelected();
+    method public String getUnchecked();
+    property public final String Checked;
+    property public final String Indeterminate;
+    property public final String NotSelected;
+    property public final String Selected;
+    property public final String Unchecked;
+    field public static final androidx.ui.foundation.Strings! INSTANCE;
+  }
+
+  public final class TableBordersKt {
+    ctor public TableBordersKt();
+    method public static void drawBorders(androidx.ui.layout.TableChildren, androidx.ui.foundation.shape.border.Border defaultBorder = Border(Color.Black, Dp.Hairline), kotlin.jvm.functions.Function1<? super androidx.ui.foundation.DrawBordersReceiver,kotlin.Unit> block);
+  }
+
 }
 
 package androidx.ui.foundation.animation {
@@ -127,12 +166,36 @@
 
 }
 
+package androidx.ui.foundation.semantics {
+
+  public final class FoundationSemanticsProperties {
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getInMutuallyExclusiveGroup();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getSelected();
+    method public androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.foundation.selection.ToggleableState> getToggleableState();
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> InMutuallyExclusiveGroup;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Selected;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.foundation.selection.ToggleableState> ToggleableState;
+    field public static final androidx.ui.foundation.semantics.FoundationSemanticsProperties! INSTANCE;
+  }
+
+  public final class FoundationSemanticsPropertiesKt {
+    ctor public FoundationSemanticsPropertiesKt();
+    method public static boolean getInMutuallyExclusiveGroup(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static boolean getSelected(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.ui.foundation.selection.ToggleableState getToggleableState(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static void setInMutuallyExclusiveGroup(androidx.ui.semantics.SemanticsPropertyReceiver, boolean p);
+    method public static void setSelected(androidx.ui.semantics.SemanticsPropertyReceiver, boolean p);
+    method public static void setToggleableState(androidx.ui.semantics.SemanticsPropertyReceiver, androidx.ui.foundation.selection.ToggleableState p);
+  }
+
+}
+
 package androidx.ui.foundation.shape {
 
   public final class DrawShapeKt {
     ctor public DrawShapeKt();
     method public static void DrawShape(androidx.ui.engine.geometry.Shape shape, androidx.ui.graphics.Color color);
-    method public static void DrawShape(androidx.ui.engine.geometry.Shape shape, androidx.ui.graphics.vectorgraphics.Brush brush);
+    method public static void DrawShape(androidx.ui.engine.geometry.Shape shape, androidx.ui.graphics.Brush brush);
   }
 
   public final class GenericShape implements androidx.ui.engine.geometry.Shape {
@@ -151,11 +214,11 @@
 package androidx.ui.foundation.shape.border {
 
   public final class Border {
-    ctor public Border(androidx.ui.graphics.vectorgraphics.Brush brush, androidx.ui.core.Dp width);
-    method public androidx.ui.graphics.vectorgraphics.Brush component1();
+    ctor public Border(androidx.ui.graphics.Brush brush, androidx.ui.core.Dp width);
+    method public androidx.ui.graphics.Brush component1();
     method public androidx.ui.core.Dp component2();
-    method public androidx.ui.foundation.shape.border.Border copy(androidx.ui.graphics.vectorgraphics.Brush brush, androidx.ui.core.Dp width);
-    method public androidx.ui.graphics.vectorgraphics.Brush getBrush();
+    method public androidx.ui.foundation.shape.border.Border copy(androidx.ui.graphics.Brush brush, androidx.ui.core.Dp width);
+    method public androidx.ui.graphics.Brush getBrush();
     method public androidx.ui.core.Dp getWidth();
   }
 
@@ -174,9 +237,9 @@
 package androidx.ui.foundation.shape.corner {
 
   public abstract class CornerBasedShape implements androidx.ui.engine.geometry.Shape {
-    ctor public CornerBasedShape(androidx.ui.foundation.shape.corner.CornerSizes corners);
+    ctor public CornerBasedShape(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
     method public final androidx.ui.engine.geometry.Outline createOutline(androidx.ui.core.PxSize size, androidx.ui.core.Density density);
-    method public abstract androidx.ui.engine.geometry.Outline createOutline(androidx.ui.foundation.shape.corner.PxCornerSizes corners, androidx.ui.core.PxSize size);
+    method public abstract androidx.ui.engine.geometry.Outline createOutline(androidx.ui.core.PxSize size, androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
   }
 
   public interface CornerSize {
@@ -192,60 +255,29 @@
     method public static androidx.ui.foundation.shape.corner.CornerSize getZeroCornerSize();
   }
 
-  public final class CornerSizes {
-    ctor public CornerSizes(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+  public final class RoundedCornerShape extends androidx.ui.foundation.shape.corner.CornerBasedShape {
+    ctor public RoundedCornerShape(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
     method public androidx.ui.foundation.shape.corner.CornerSize component1();
     method public androidx.ui.foundation.shape.corner.CornerSize component2();
     method public androidx.ui.foundation.shape.corner.CornerSize component3();
     method public androidx.ui.foundation.shape.corner.CornerSize component4();
-    method public androidx.ui.foundation.shape.corner.CornerSizes copy(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+    method public androidx.ui.foundation.shape.corner.RoundedCornerShape copy(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+    method public androidx.ui.engine.geometry.Outline.Rounded createOutline(androidx.ui.core.PxSize size, androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
     method public androidx.ui.foundation.shape.corner.CornerSize getBottomLeft();
     method public androidx.ui.foundation.shape.corner.CornerSize getBottomRight();
     method public androidx.ui.foundation.shape.corner.CornerSize getTopLeft();
     method public androidx.ui.foundation.shape.corner.CornerSize getTopRight();
   }
 
-  public final class CornerSizesKt {
-    ctor public CornerSizesKt();
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.foundation.shape.corner.CornerSize allCornersSize);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.core.Dp size);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.core.Px size);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(int percent);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.core.Dp topLeft = 0.dp, androidx.ui.core.Dp topRight = 0.dp, androidx.ui.core.Dp bottomRight = 0.dp, androidx.ui.core.Dp bottomLeft = 0.dp);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.core.Px topLeft = 0.px, androidx.ui.core.Px topRight = 0.px, androidx.ui.core.Px bottomRight = 0.px, androidx.ui.core.Px bottomLeft = 0.px);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(@IntRange(from=0, to=50) int topLeftPercent = 0, @IntRange(from=0, to=50) int topRightPercent = 0, @IntRange(from=0, to=50) int bottomRightPercent = 0, @IntRange(from=0, to=50) int bottomLeftPercent = 0);
-  }
-
-  public final class PxCornerSizes {
-    ctor public PxCornerSizes(androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
-    method public androidx.ui.core.Px component1();
-    method public androidx.ui.core.Px component2();
-    method public androidx.ui.core.Px component3();
-    method public androidx.ui.core.Px component4();
-    method public androidx.ui.foundation.shape.corner.PxCornerSizes copy(androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
-    method public androidx.ui.core.Px getBottomLeft();
-    method public androidx.ui.core.Px getBottomRight();
-    method public androidx.ui.core.Px getTopLeft();
-    method public androidx.ui.core.Px getTopRight();
-  }
-
-  public final class PxCornerSizesKt {
-    ctor public PxCornerSizesKt();
-    method public static androidx.ui.foundation.shape.corner.PxCornerSizes PxCornerSizes(androidx.ui.foundation.shape.corner.CornerSizes corners, androidx.ui.core.PxSize size, androidx.ui.core.Density density);
-    method public static boolean isEmpty(androidx.ui.foundation.shape.corner.PxCornerSizes);
-  }
-
-  public final class RoundedCornerShape extends androidx.ui.foundation.shape.corner.CornerBasedShape {
-    ctor public RoundedCornerShape(androidx.ui.foundation.shape.corner.CornerSizes corners);
-    method public androidx.ui.foundation.shape.corner.CornerSizes component1();
-    method public androidx.ui.foundation.shape.corner.RoundedCornerShape copy(androidx.ui.foundation.shape.corner.CornerSizes corners);
-    method public androidx.ui.engine.geometry.Outline.Rounded createOutline(androidx.ui.foundation.shape.corner.PxCornerSizes corners, androidx.ui.core.PxSize size);
-    method public androidx.ui.foundation.shape.corner.CornerSizes getCorners();
-  }
-
   public final class RoundedCornerShapeKt {
     ctor public RoundedCornerShapeKt();
     method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.foundation.shape.corner.CornerSize corner);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.core.Dp size);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.core.Px size);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(int percent);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.core.Dp topLeft = 0.dp, androidx.ui.core.Dp topRight = 0.dp, androidx.ui.core.Dp bottomRight = 0.dp, androidx.ui.core.Dp bottomLeft = 0.dp);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.core.Px topLeft = 0.px, androidx.ui.core.Px topRight = 0.px, androidx.ui.core.Px bottomRight = 0.px, androidx.ui.core.Px bottomLeft = 0.px);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(@IntRange(from=0, to=50) int topLeftPercent = 0, @IntRange(from=0, to=50) int topRightPercent = 0, @IntRange(from=0, to=50) int bottomRightPercent = 0, @IntRange(from=0, to=50) int bottomLeftPercent = 0);
     method public static androidx.ui.foundation.shape.corner.RoundedCornerShape getCircleShape();
   }
 
diff --git a/ui/ui-foundation/api/restricted_1.0.0-alpha01.txt b/ui/ui-foundation/api/restricted_1.0.0-alpha01.txt
index f0ceb44..782f0c2 100644
--- a/ui/ui-foundation/api/restricted_1.0.0-alpha01.txt
+++ b/ui/ui-foundation/api/restricted_1.0.0-alpha01.txt
@@ -8,10 +8,15 @@
 
   public final class ColoredRectKt {
     ctor public ColoredRectKt();
-    method public static void ColoredRect(androidx.ui.graphics.vectorgraphics.Brush brush, androidx.ui.core.Dp? width = null, androidx.ui.core.Dp? height = null);
+    method public static void ColoredRect(androidx.ui.graphics.Brush brush, androidx.ui.core.Dp? width = null, androidx.ui.core.Dp? height = null);
     method public static void ColoredRect(androidx.ui.graphics.Color color, androidx.ui.core.Dp? width = null, androidx.ui.core.Dp? height = null);
   }
 
+  public final class DarkThemeKt {
+    ctor public DarkThemeKt();
+    method public static androidx.compose.Effect<java.lang.Boolean> isSystemInDarkTheme();
+  }
+
   public final class DeterminateProgressIndicatorKt {
     ctor public DeterminateProgressIndicatorKt();
     method public static void DeterminateProgressIndicator(@FloatRange(from=0.0, to=1.0) float progress, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -22,11 +27,45 @@
     method public static void Dialog(kotlin.jvm.functions.Function0<kotlin.Unit> onCloseRequest, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
+  public final class DrawBordersReceiver {
+    method public void all(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void allHorizontal(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void allVertical(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void bottom(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public int getColumnCount();
+    method public int getRowCount();
+    method public void horizontal(int row, kotlin.ranges.IntRange columns = 0 <other> columnCount, androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void left(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void outer(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void right(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void top(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void vertical(int column, kotlin.ranges.IntRange rows = 0 <other> rowCount, androidx.ui.foundation.shape.border.Border border = defaultBorder);
+  }
+
   public final class SimpleImageKt {
     ctor public SimpleImageKt();
     method public static void SimpleImage(androidx.ui.painting.Image image, androidx.ui.graphics.Color? tint = null);
   }
 
+  public final class Strings {
+    method public String getChecked();
+    method public String getIndeterminate();
+    method public String getNotSelected();
+    method public String getSelected();
+    method public String getUnchecked();
+    property public final String Checked;
+    property public final String Indeterminate;
+    property public final String NotSelected;
+    property public final String Selected;
+    property public final String Unchecked;
+    field public static final androidx.ui.foundation.Strings! INSTANCE;
+  }
+
+  public final class TableBordersKt {
+    ctor public TableBordersKt();
+    method public static void drawBorders(androidx.ui.layout.TableChildren, androidx.ui.foundation.shape.border.Border defaultBorder = Border(Color.Black, Dp.Hairline), kotlin.jvm.functions.Function1<? super androidx.ui.foundation.DrawBordersReceiver,kotlin.Unit> block);
+  }
+
 }
 
 package androidx.ui.foundation.animation {
@@ -127,12 +166,36 @@
 
 }
 
+package androidx.ui.foundation.semantics {
+
+  public final class FoundationSemanticsProperties {
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getInMutuallyExclusiveGroup();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getSelected();
+    method public androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.foundation.selection.ToggleableState> getToggleableState();
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> InMutuallyExclusiveGroup;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Selected;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.foundation.selection.ToggleableState> ToggleableState;
+    field public static final androidx.ui.foundation.semantics.FoundationSemanticsProperties! INSTANCE;
+  }
+
+  public final class FoundationSemanticsPropertiesKt {
+    ctor public FoundationSemanticsPropertiesKt();
+    method public static boolean getInMutuallyExclusiveGroup(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static boolean getSelected(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.ui.foundation.selection.ToggleableState getToggleableState(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static void setInMutuallyExclusiveGroup(androidx.ui.semantics.SemanticsPropertyReceiver, boolean p);
+    method public static void setSelected(androidx.ui.semantics.SemanticsPropertyReceiver, boolean p);
+    method public static void setToggleableState(androidx.ui.semantics.SemanticsPropertyReceiver, androidx.ui.foundation.selection.ToggleableState p);
+  }
+
+}
+
 package androidx.ui.foundation.shape {
 
   public final class DrawShapeKt {
     ctor public DrawShapeKt();
     method public static void DrawShape(androidx.ui.engine.geometry.Shape shape, androidx.ui.graphics.Color color);
-    method public static void DrawShape(androidx.ui.engine.geometry.Shape shape, androidx.ui.graphics.vectorgraphics.Brush brush);
+    method public static void DrawShape(androidx.ui.engine.geometry.Shape shape, androidx.ui.graphics.Brush brush);
   }
 
   public final class GenericShape implements androidx.ui.engine.geometry.Shape {
@@ -151,11 +214,11 @@
 package androidx.ui.foundation.shape.border {
 
   public final class Border {
-    ctor public Border(androidx.ui.graphics.vectorgraphics.Brush brush, androidx.ui.core.Dp width);
-    method public androidx.ui.graphics.vectorgraphics.Brush component1();
+    ctor public Border(androidx.ui.graphics.Brush brush, androidx.ui.core.Dp width);
+    method public androidx.ui.graphics.Brush component1();
     method public androidx.ui.core.Dp component2();
-    method public androidx.ui.foundation.shape.border.Border copy(androidx.ui.graphics.vectorgraphics.Brush brush, androidx.ui.core.Dp width);
-    method public androidx.ui.graphics.vectorgraphics.Brush getBrush();
+    method public androidx.ui.foundation.shape.border.Border copy(androidx.ui.graphics.Brush brush, androidx.ui.core.Dp width);
+    method public androidx.ui.graphics.Brush getBrush();
     method public androidx.ui.core.Dp getWidth();
   }
 
@@ -174,9 +237,9 @@
 package androidx.ui.foundation.shape.corner {
 
   public abstract class CornerBasedShape implements androidx.ui.engine.geometry.Shape {
-    ctor public CornerBasedShape(androidx.ui.foundation.shape.corner.CornerSizes corners);
+    ctor public CornerBasedShape(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
     method public final androidx.ui.engine.geometry.Outline createOutline(androidx.ui.core.PxSize size, androidx.ui.core.Density density);
-    method public abstract androidx.ui.engine.geometry.Outline createOutline(androidx.ui.foundation.shape.corner.PxCornerSizes corners, androidx.ui.core.PxSize size);
+    method public abstract androidx.ui.engine.geometry.Outline createOutline(androidx.ui.core.PxSize size, androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
   }
 
   public interface CornerSize {
@@ -192,60 +255,29 @@
     method public static androidx.ui.foundation.shape.corner.CornerSize getZeroCornerSize();
   }
 
-  public final class CornerSizes {
-    ctor public CornerSizes(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+  public final class RoundedCornerShape extends androidx.ui.foundation.shape.corner.CornerBasedShape {
+    ctor public RoundedCornerShape(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
     method public androidx.ui.foundation.shape.corner.CornerSize component1();
     method public androidx.ui.foundation.shape.corner.CornerSize component2();
     method public androidx.ui.foundation.shape.corner.CornerSize component3();
     method public androidx.ui.foundation.shape.corner.CornerSize component4();
-    method public androidx.ui.foundation.shape.corner.CornerSizes copy(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+    method public androidx.ui.foundation.shape.corner.RoundedCornerShape copy(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+    method public androidx.ui.engine.geometry.Outline.Rounded createOutline(androidx.ui.core.PxSize size, androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
     method public androidx.ui.foundation.shape.corner.CornerSize getBottomLeft();
     method public androidx.ui.foundation.shape.corner.CornerSize getBottomRight();
     method public androidx.ui.foundation.shape.corner.CornerSize getTopLeft();
     method public androidx.ui.foundation.shape.corner.CornerSize getTopRight();
   }
 
-  public final class CornerSizesKt {
-    ctor public CornerSizesKt();
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.foundation.shape.corner.CornerSize allCornersSize);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.core.Dp size);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.core.Px size);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(int percent);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.core.Dp topLeft = 0.dp, androidx.ui.core.Dp topRight = 0.dp, androidx.ui.core.Dp bottomRight = 0.dp, androidx.ui.core.Dp bottomLeft = 0.dp);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.core.Px topLeft = 0.px, androidx.ui.core.Px topRight = 0.px, androidx.ui.core.Px bottomRight = 0.px, androidx.ui.core.Px bottomLeft = 0.px);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(@IntRange(from=0, to=50) int topLeftPercent = 0, @IntRange(from=0, to=50) int topRightPercent = 0, @IntRange(from=0, to=50) int bottomRightPercent = 0, @IntRange(from=0, to=50) int bottomLeftPercent = 0);
-  }
-
-  public final class PxCornerSizes {
-    ctor public PxCornerSizes(androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
-    method public androidx.ui.core.Px component1();
-    method public androidx.ui.core.Px component2();
-    method public androidx.ui.core.Px component3();
-    method public androidx.ui.core.Px component4();
-    method public androidx.ui.foundation.shape.corner.PxCornerSizes copy(androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
-    method public androidx.ui.core.Px getBottomLeft();
-    method public androidx.ui.core.Px getBottomRight();
-    method public androidx.ui.core.Px getTopLeft();
-    method public androidx.ui.core.Px getTopRight();
-  }
-
-  public final class PxCornerSizesKt {
-    ctor public PxCornerSizesKt();
-    method public static androidx.ui.foundation.shape.corner.PxCornerSizes PxCornerSizes(androidx.ui.foundation.shape.corner.CornerSizes corners, androidx.ui.core.PxSize size, androidx.ui.core.Density density);
-    method public static boolean isEmpty(androidx.ui.foundation.shape.corner.PxCornerSizes);
-  }
-
-  public final class RoundedCornerShape extends androidx.ui.foundation.shape.corner.CornerBasedShape {
-    ctor public RoundedCornerShape(androidx.ui.foundation.shape.corner.CornerSizes corners);
-    method public androidx.ui.foundation.shape.corner.CornerSizes component1();
-    method public androidx.ui.foundation.shape.corner.RoundedCornerShape copy(androidx.ui.foundation.shape.corner.CornerSizes corners);
-    method public androidx.ui.engine.geometry.Outline.Rounded createOutline(androidx.ui.foundation.shape.corner.PxCornerSizes corners, androidx.ui.core.PxSize size);
-    method public androidx.ui.foundation.shape.corner.CornerSizes getCorners();
-  }
-
   public final class RoundedCornerShapeKt {
     ctor public RoundedCornerShapeKt();
     method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.foundation.shape.corner.CornerSize corner);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.core.Dp size);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.core.Px size);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(int percent);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.core.Dp topLeft = 0.dp, androidx.ui.core.Dp topRight = 0.dp, androidx.ui.core.Dp bottomRight = 0.dp, androidx.ui.core.Dp bottomLeft = 0.dp);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.core.Px topLeft = 0.px, androidx.ui.core.Px topRight = 0.px, androidx.ui.core.Px bottomRight = 0.px, androidx.ui.core.Px bottomLeft = 0.px);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(@IntRange(from=0, to=50) int topLeftPercent = 0, @IntRange(from=0, to=50) int topRightPercent = 0, @IntRange(from=0, to=50) int bottomRightPercent = 0, @IntRange(from=0, to=50) int bottomLeftPercent = 0);
     method public static androidx.ui.foundation.shape.corner.RoundedCornerShape getCircleShape();
   }
 
diff --git a/ui/ui-foundation/api/restricted_current.txt b/ui/ui-foundation/api/restricted_current.txt
index f0ceb44..782f0c2 100644
--- a/ui/ui-foundation/api/restricted_current.txt
+++ b/ui/ui-foundation/api/restricted_current.txt
@@ -8,10 +8,15 @@
 
   public final class ColoredRectKt {
     ctor public ColoredRectKt();
-    method public static void ColoredRect(androidx.ui.graphics.vectorgraphics.Brush brush, androidx.ui.core.Dp? width = null, androidx.ui.core.Dp? height = null);
+    method public static void ColoredRect(androidx.ui.graphics.Brush brush, androidx.ui.core.Dp? width = null, androidx.ui.core.Dp? height = null);
     method public static void ColoredRect(androidx.ui.graphics.Color color, androidx.ui.core.Dp? width = null, androidx.ui.core.Dp? height = null);
   }
 
+  public final class DarkThemeKt {
+    ctor public DarkThemeKt();
+    method public static androidx.compose.Effect<java.lang.Boolean> isSystemInDarkTheme();
+  }
+
   public final class DeterminateProgressIndicatorKt {
     ctor public DeterminateProgressIndicatorKt();
     method public static void DeterminateProgressIndicator(@FloatRange(from=0.0, to=1.0) float progress, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -22,11 +27,45 @@
     method public static void Dialog(kotlin.jvm.functions.Function0<kotlin.Unit> onCloseRequest, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
+  public final class DrawBordersReceiver {
+    method public void all(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void allHorizontal(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void allVertical(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void bottom(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public int getColumnCount();
+    method public int getRowCount();
+    method public void horizontal(int row, kotlin.ranges.IntRange columns = 0 <other> columnCount, androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void left(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void outer(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void right(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void top(androidx.ui.foundation.shape.border.Border border = defaultBorder);
+    method public void vertical(int column, kotlin.ranges.IntRange rows = 0 <other> rowCount, androidx.ui.foundation.shape.border.Border border = defaultBorder);
+  }
+
   public final class SimpleImageKt {
     ctor public SimpleImageKt();
     method public static void SimpleImage(androidx.ui.painting.Image image, androidx.ui.graphics.Color? tint = null);
   }
 
+  public final class Strings {
+    method public String getChecked();
+    method public String getIndeterminate();
+    method public String getNotSelected();
+    method public String getSelected();
+    method public String getUnchecked();
+    property public final String Checked;
+    property public final String Indeterminate;
+    property public final String NotSelected;
+    property public final String Selected;
+    property public final String Unchecked;
+    field public static final androidx.ui.foundation.Strings! INSTANCE;
+  }
+
+  public final class TableBordersKt {
+    ctor public TableBordersKt();
+    method public static void drawBorders(androidx.ui.layout.TableChildren, androidx.ui.foundation.shape.border.Border defaultBorder = Border(Color.Black, Dp.Hairline), kotlin.jvm.functions.Function1<? super androidx.ui.foundation.DrawBordersReceiver,kotlin.Unit> block);
+  }
+
 }
 
 package androidx.ui.foundation.animation {
@@ -127,12 +166,36 @@
 
 }
 
+package androidx.ui.foundation.semantics {
+
+  public final class FoundationSemanticsProperties {
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getInMutuallyExclusiveGroup();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getSelected();
+    method public androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.foundation.selection.ToggleableState> getToggleableState();
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> InMutuallyExclusiveGroup;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Selected;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.foundation.selection.ToggleableState> ToggleableState;
+    field public static final androidx.ui.foundation.semantics.FoundationSemanticsProperties! INSTANCE;
+  }
+
+  public final class FoundationSemanticsPropertiesKt {
+    ctor public FoundationSemanticsPropertiesKt();
+    method public static boolean getInMutuallyExclusiveGroup(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static boolean getSelected(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.ui.foundation.selection.ToggleableState getToggleableState(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static void setInMutuallyExclusiveGroup(androidx.ui.semantics.SemanticsPropertyReceiver, boolean p);
+    method public static void setSelected(androidx.ui.semantics.SemanticsPropertyReceiver, boolean p);
+    method public static void setToggleableState(androidx.ui.semantics.SemanticsPropertyReceiver, androidx.ui.foundation.selection.ToggleableState p);
+  }
+
+}
+
 package androidx.ui.foundation.shape {
 
   public final class DrawShapeKt {
     ctor public DrawShapeKt();
     method public static void DrawShape(androidx.ui.engine.geometry.Shape shape, androidx.ui.graphics.Color color);
-    method public static void DrawShape(androidx.ui.engine.geometry.Shape shape, androidx.ui.graphics.vectorgraphics.Brush brush);
+    method public static void DrawShape(androidx.ui.engine.geometry.Shape shape, androidx.ui.graphics.Brush brush);
   }
 
   public final class GenericShape implements androidx.ui.engine.geometry.Shape {
@@ -151,11 +214,11 @@
 package androidx.ui.foundation.shape.border {
 
   public final class Border {
-    ctor public Border(androidx.ui.graphics.vectorgraphics.Brush brush, androidx.ui.core.Dp width);
-    method public androidx.ui.graphics.vectorgraphics.Brush component1();
+    ctor public Border(androidx.ui.graphics.Brush brush, androidx.ui.core.Dp width);
+    method public androidx.ui.graphics.Brush component1();
     method public androidx.ui.core.Dp component2();
-    method public androidx.ui.foundation.shape.border.Border copy(androidx.ui.graphics.vectorgraphics.Brush brush, androidx.ui.core.Dp width);
-    method public androidx.ui.graphics.vectorgraphics.Brush getBrush();
+    method public androidx.ui.foundation.shape.border.Border copy(androidx.ui.graphics.Brush brush, androidx.ui.core.Dp width);
+    method public androidx.ui.graphics.Brush getBrush();
     method public androidx.ui.core.Dp getWidth();
   }
 
@@ -174,9 +237,9 @@
 package androidx.ui.foundation.shape.corner {
 
   public abstract class CornerBasedShape implements androidx.ui.engine.geometry.Shape {
-    ctor public CornerBasedShape(androidx.ui.foundation.shape.corner.CornerSizes corners);
+    ctor public CornerBasedShape(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
     method public final androidx.ui.engine.geometry.Outline createOutline(androidx.ui.core.PxSize size, androidx.ui.core.Density density);
-    method public abstract androidx.ui.engine.geometry.Outline createOutline(androidx.ui.foundation.shape.corner.PxCornerSizes corners, androidx.ui.core.PxSize size);
+    method public abstract androidx.ui.engine.geometry.Outline createOutline(androidx.ui.core.PxSize size, androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
   }
 
   public interface CornerSize {
@@ -192,60 +255,29 @@
     method public static androidx.ui.foundation.shape.corner.CornerSize getZeroCornerSize();
   }
 
-  public final class CornerSizes {
-    ctor public CornerSizes(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+  public final class RoundedCornerShape extends androidx.ui.foundation.shape.corner.CornerBasedShape {
+    ctor public RoundedCornerShape(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
     method public androidx.ui.foundation.shape.corner.CornerSize component1();
     method public androidx.ui.foundation.shape.corner.CornerSize component2();
     method public androidx.ui.foundation.shape.corner.CornerSize component3();
     method public androidx.ui.foundation.shape.corner.CornerSize component4();
-    method public androidx.ui.foundation.shape.corner.CornerSizes copy(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+    method public androidx.ui.foundation.shape.corner.RoundedCornerShape copy(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+    method public androidx.ui.engine.geometry.Outline.Rounded createOutline(androidx.ui.core.PxSize size, androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
     method public androidx.ui.foundation.shape.corner.CornerSize getBottomLeft();
     method public androidx.ui.foundation.shape.corner.CornerSize getBottomRight();
     method public androidx.ui.foundation.shape.corner.CornerSize getTopLeft();
     method public androidx.ui.foundation.shape.corner.CornerSize getTopRight();
   }
 
-  public final class CornerSizesKt {
-    ctor public CornerSizesKt();
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.foundation.shape.corner.CornerSize allCornersSize);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.core.Dp size);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.core.Px size);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(int percent);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.core.Dp topLeft = 0.dp, androidx.ui.core.Dp topRight = 0.dp, androidx.ui.core.Dp bottomRight = 0.dp, androidx.ui.core.Dp bottomLeft = 0.dp);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(androidx.ui.core.Px topLeft = 0.px, androidx.ui.core.Px topRight = 0.px, androidx.ui.core.Px bottomRight = 0.px, androidx.ui.core.Px bottomLeft = 0.px);
-    method public static androidx.ui.foundation.shape.corner.CornerSizes CornerSizes(@IntRange(from=0, to=50) int topLeftPercent = 0, @IntRange(from=0, to=50) int topRightPercent = 0, @IntRange(from=0, to=50) int bottomRightPercent = 0, @IntRange(from=0, to=50) int bottomLeftPercent = 0);
-  }
-
-  public final class PxCornerSizes {
-    ctor public PxCornerSizes(androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
-    method public androidx.ui.core.Px component1();
-    method public androidx.ui.core.Px component2();
-    method public androidx.ui.core.Px component3();
-    method public androidx.ui.core.Px component4();
-    method public androidx.ui.foundation.shape.corner.PxCornerSizes copy(androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
-    method public androidx.ui.core.Px getBottomLeft();
-    method public androidx.ui.core.Px getBottomRight();
-    method public androidx.ui.core.Px getTopLeft();
-    method public androidx.ui.core.Px getTopRight();
-  }
-
-  public final class PxCornerSizesKt {
-    ctor public PxCornerSizesKt();
-    method public static androidx.ui.foundation.shape.corner.PxCornerSizes PxCornerSizes(androidx.ui.foundation.shape.corner.CornerSizes corners, androidx.ui.core.PxSize size, androidx.ui.core.Density density);
-    method public static boolean isEmpty(androidx.ui.foundation.shape.corner.PxCornerSizes);
-  }
-
-  public final class RoundedCornerShape extends androidx.ui.foundation.shape.corner.CornerBasedShape {
-    ctor public RoundedCornerShape(androidx.ui.foundation.shape.corner.CornerSizes corners);
-    method public androidx.ui.foundation.shape.corner.CornerSizes component1();
-    method public androidx.ui.foundation.shape.corner.RoundedCornerShape copy(androidx.ui.foundation.shape.corner.CornerSizes corners);
-    method public androidx.ui.engine.geometry.Outline.Rounded createOutline(androidx.ui.foundation.shape.corner.PxCornerSizes corners, androidx.ui.core.PxSize size);
-    method public androidx.ui.foundation.shape.corner.CornerSizes getCorners();
-  }
-
   public final class RoundedCornerShapeKt {
     ctor public RoundedCornerShapeKt();
     method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.foundation.shape.corner.CornerSize corner);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.core.Dp size);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.core.Px size);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(int percent);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.core.Dp topLeft = 0.dp, androidx.ui.core.Dp topRight = 0.dp, androidx.ui.core.Dp bottomRight = 0.dp, androidx.ui.core.Dp bottomLeft = 0.dp);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(androidx.ui.core.Px topLeft = 0.px, androidx.ui.core.Px topRight = 0.px, androidx.ui.core.Px bottomRight = 0.px, androidx.ui.core.Px bottomLeft = 0.px);
+    method public static androidx.ui.foundation.shape.corner.RoundedCornerShape RoundedCornerShape(@IntRange(from=0, to=50) int topLeftPercent = 0, @IntRange(from=0, to=50) int topRightPercent = 0, @IntRange(from=0, to=50) int bottomRightPercent = 0, @IntRange(from=0, to=50) int bottomLeftPercent = 0);
     method public static androidx.ui.foundation.shape.corner.RoundedCornerShape getCircleShape();
   }
 
diff --git a/ui/ui-foundation/integration-tests/foundation-demos/src/main/AndroidManifest.xml b/ui/ui-foundation/integration-tests/foundation-demos/src/main/AndroidManifest.xml
index 5cb729b..4609982 100644
--- a/ui/ui-foundation/integration-tests/foundation-demos/src/main/AndroidManifest.xml
+++ b/ui/ui-foundation/integration-tests/foundation-demos/src/main/AndroidManifest.xml
@@ -28,5 +28,23 @@
                 <category android:name="androidx.ui.demos.SAMPLE_CODE" />
             </intent-filter>
         </activity>
+
+        <activity android:name=".TableBordersActivity"
+              android:configChanges="orientation|screenSize"
+              android:label="Foundation/TableBorders">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="androidx.ui.demos.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".DialogActivity"
+            android:configChanges="orientation|screenSize"
+            android:label="Foundation/Dialog">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="androidx.ui.demos.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
     </application>
 </manifest>
diff --git a/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/DialogActivity.kt b/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/DialogActivity.kt
new file mode 100644
index 0000000..fe5be4d
--- /dev/null
+++ b/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/DialogActivity.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 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.ui.foundation.demos
+
+import android.app.Activity
+import android.os.Bundle
+import androidx.compose.composer
+import androidx.ui.core.setContent
+import androidx.ui.foundation.samples.DialogSample
+
+class DialogActivity : Activity() {
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContent {
+            DialogSample()
+        }
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/TableBordersActivity.kt b/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/TableBordersActivity.kt
new file mode 100644
index 0000000..122ae13
--- /dev/null
+++ b/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/TableBordersActivity.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 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.ui.foundation.demos
+
+import android.app.Activity
+import android.os.Bundle
+import androidx.compose.composer
+import androidx.ui.core.setContent
+import androidx.ui.foundation.samples.SimpleTableWithBorders
+
+class TableBordersActivity : Activity() {
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContent {
+            SimpleTableWithBorders()
+        }
+    }
+}
diff --git a/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/ColoredRectSamples.kt b/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/ColoredRectSamples.kt
index 5a688a7..7221a0d 100644
--- a/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/ColoredRectSamples.kt
+++ b/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/ColoredRectSamples.kt
@@ -22,7 +22,7 @@
 import androidx.ui.core.dp
 import androidx.ui.foundation.ColoredRect
 import androidx.ui.graphics.Color
-import androidx.ui.graphics.vectorgraphics.SolidColor
+import androidx.ui.graphics.SolidColor
 
 @Sampled
 @Composable
diff --git a/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/DarkThemeSample.kt b/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/DarkThemeSample.kt
new file mode 100644
index 0000000..357083e
--- /dev/null
+++ b/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/DarkThemeSample.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019 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.ui.foundation.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.Composable
+import androidx.compose.composer
+import androidx.compose.unaryPlus
+import androidx.ui.core.dp
+import androidx.ui.foundation.ColoredRect
+import androidx.ui.foundation.isSystemInDarkTheme
+import androidx.ui.graphics.Color
+import androidx.ui.layout.Wrap
+
+@Sampled
+@Composable
+fun DarkThemeSample() {
+    val dark = +isSystemInDarkTheme()
+    val color = if (dark) Color.White else Color.Black
+    Wrap {
+        ColoredRect(color = color, width = 50.dp, height = 50.dp)
+    }
+}
diff --git a/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/DialogSample.kt b/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/DialogSample.kt
index 2c01062c..f717f9c 100644
--- a/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/DialogSample.kt
+++ b/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/DialogSample.kt
@@ -21,17 +21,26 @@
 import androidx.compose.composer
 import androidx.compose.state
 import androidx.compose.unaryPlus
-import androidx.ui.core.Text
+import androidx.ui.core.dp
 import androidx.ui.foundation.Dialog
+import androidx.ui.foundation.shape.DrawShape
+import androidx.ui.foundation.shape.corner.CircleShape
+import androidx.ui.graphics.Color
+import androidx.ui.layout.Container
 
 @Sampled
 @Composable
 fun DialogSample() {
     val openDialog = +state { true }
+    val dialogWidth = 200.dp
+    val dialogHeight = 50.dp
 
     if (openDialog.value) {
         Dialog(onCloseRequest = { openDialog.value = false }) {
-            Text("This is a Dialog. Click outside to dismiss.")
+            // Draw a rectangle shape with rounded corners inside the dialog
+            Container(width = dialogWidth, height = dialogHeight) {
+                DrawShape(CircleShape, Color.White)
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/TableBordersSamples.kt b/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/TableBordersSamples.kt
new file mode 100644
index 0000000..d929642
--- /dev/null
+++ b/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/TableBordersSamples.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2019 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.ui.foundation.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.Composable
+import androidx.compose.composer
+import androidx.ui.core.dp
+import androidx.ui.foundation.ColoredRect
+import androidx.ui.foundation.drawBorders
+import androidx.ui.foundation.shape.border.Border
+import androidx.ui.graphics.Color
+import androidx.ui.layout.Padding
+import androidx.ui.layout.Table
+
+@Sampled
+@Composable
+fun SimpleTableWithBorders() {
+    Padding(10.dp) {
+        Table(columnCount = 8) {
+            drawBorders(
+                defaultBorder = Border(color = Color.Red, width = 2.dp)
+            ) {
+                outer()
+                horizontal(row = 1)
+                vertical(column = 1, rows = 1 until rowCount)
+                vertical(column = columnCount - 1, rows = 1 until rowCount)
+            }
+            repeat(8) {
+                tableRow {
+                    Padding(2.dp) {
+                        ColoredRect(color = Color.Fuchsia, height = 50.dp)
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/ClickableTest.kt b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/ClickableTest.kt
index 920868f..2f7e1c3 100644
--- a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/ClickableTest.kt
+++ b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/ClickableTest.kt
@@ -54,8 +54,7 @@
         findByTag("myClickable")
             .assertSemanticsIsEqualTo(
                 createFullSemantics(
-                    isEnabled = true,
-                    isButton = true
+                    isEnabled = true
                 )
             )
     }
@@ -75,8 +74,7 @@
         findByTag("myClickable")
             .assertSemanticsIsEqualTo(
                 createFullSemantics(
-                    isEnabled = false,
-                    isButton = true
+                    isEnabled = false
                 )
             )
     }
diff --git a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/DialogUiTest.kt b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/DialogUiTest.kt
index 0bfd0af..763e71c 100644
--- a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/DialogUiTest.kt
+++ b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/DialogUiTest.kt
@@ -23,6 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
 import androidx.test.uiautomator.UiDevice
 import androidx.ui.core.Text
+import androidx.ui.semantics.accessibilityLabel
 import androidx.ui.test.assertDoesNotExist
 import androidx.ui.test.assertIsVisible
 import androidx.ui.test.doClick
@@ -103,7 +104,7 @@
         val outsideY = composeTestRule.displayMetrics.heightPixels / 2
         UiDevice.getInstance(getInstrumentation()).click(outsideX, outsideY)
 
-        assertDoesNotExist { label.equals(defaultText) }
+        assertDoesNotExist { accessibilityLabel == defaultText }
     }
 
     @Test
@@ -146,7 +147,7 @@
         // Click the back button to dismiss the Dialog
         UiDevice.getInstance(getInstrumentation()).pressBack()
 
-        assertDoesNotExist { label.equals(defaultText) }
+        assertDoesNotExist { accessibilityLabel == defaultText }
     }
 
     @Test
diff --git a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/MutuallyExclusiveSetItemTest.kt b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/MutuallyExclusiveSetItemTest.kt
index 7351089..b91dc58 100644
--- a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/MutuallyExclusiveSetItemTest.kt
+++ b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/MutuallyExclusiveSetItemTest.kt
@@ -22,14 +22,15 @@
 import androidx.test.filters.MediumTest
 import androidx.ui.core.Text
 import androidx.ui.foundation.selection.MutuallyExclusiveSetItem
-import androidx.ui.test.assertIsNotSelected
 import androidx.ui.test.assertIsSelected
+import androidx.ui.test.assertIsUnselected
 import androidx.ui.test.assertSemanticsIsEqualTo
 import androidx.ui.test.createComposeRule
 import androidx.ui.test.createFullSemantics
 import androidx.ui.test.doClick
 import androidx.ui.test.find
 import androidx.ui.test.findAll
+import androidx.ui.test.isInMutuallyExclusiveGroup
 import com.google.common.truth.Truth
 import org.junit.Rule
 import org.junit.Test
@@ -71,11 +72,11 @@
         }
 
         find { isInMutuallyExclusiveGroup }
-            .assertIsNotSelected()
+            .assertIsUnselected()
             .doClick()
             .assertIsSelected()
             .doClick()
-            .assertIsNotSelected()
+            .assertIsUnselected()
     }
 
     @Test
@@ -88,8 +89,8 @@
         }
 
         find { isInMutuallyExclusiveGroup }
-            .assertIsNotSelected()
+            .assertIsUnselected()
             .doClick()
-            .assertIsNotSelected()
+            .assertIsUnselected()
     }
 }
\ No newline at end of file
diff --git a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/shape/corner/RoundedCornerShapeTest.kt b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/shape/corner/RoundedCornerShapeTest.kt
index afba564..b9eb9d1 100644
--- a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/shape/corner/RoundedCornerShapeTest.kt
+++ b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/shape/corner/RoundedCornerShapeTest.kt
@@ -40,7 +40,7 @@
 
     @Test
     fun roundedUniformCorners() {
-        val rounded = RoundedCornerShape(CornerSizes(25))
+        val rounded = RoundedCornerShape(25)
 
         val expectedRadius = Radius.circular(25f)
         val outline = rounded.toOutline() as Outline.Rounded
@@ -57,14 +57,7 @@
         val radius2 = 22f
         val radius3 = 32f
         val radius4 = 42f
-        val rounded = RoundedCornerShape(
-            CornerSizes(
-                CornerSize(radius1.px),
-                CornerSize(radius2.px),
-                CornerSize(radius3.px),
-                CornerSize(radius4.px)
-            )
-        )
+        val rounded = RoundedCornerShape(radius1.px, radius2.px, radius3.px, radius4.px)
 
         val outline = rounded.toOutline() as Outline.Rounded
         assertThat(outline.rrect).isEqualTo(
@@ -80,8 +73,8 @@
 
     @Test
     fun roundedCornerShapesAreEquals() {
-        assertThat(RoundedCornerShape(CornerSizes(12.dp)))
-            .isEqualTo(RoundedCornerShape(CornerSizes(12.dp)))
+        assertThat(RoundedCornerShape(12.dp))
+            .isEqualTo(RoundedCornerShape(12.dp))
     }
 
     private fun Shape.toOutline() = createOutline(size, density)
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Clickable.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Clickable.kt
index bee68c7..66473034 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Clickable.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Clickable.kt
@@ -16,13 +16,12 @@
 
 package androidx.ui.foundation
 
-import androidx.ui.core.Semantics
+import androidx.ui.semantics.Semantics
 import androidx.ui.core.gesture.PressReleasedGestureDetector
-import androidx.ui.core.semantics.SemanticsAction
-import androidx.ui.core.semantics.SemanticsActionType
-import androidx.compose.Children
-import androidx.compose.Composable
 import androidx.compose.composer
+import androidx.compose.Composable
+import androidx.ui.semantics.enabled
+import androidx.ui.semantics.onClick
 
 /**
  * Combines [PressReleasedGestureDetector] and [Semantics] for the clickable
@@ -43,13 +42,11 @@
     children: @Composable() () -> Unit
 ) {
     Semantics(
-        button = true,
-        enabled = (onClick != null),
-        actions = if (onClick != null) {
-            // TODO(ryanmentley): The unnecessary generic type specification works around an IR bug
-            listOf<SemanticsAction<*>>(SemanticsAction(SemanticsActionType.Tap, onClick))
-        } else {
-            emptyList<SemanticsAction<*>>()
+        properties = {
+            enabled = (onClick != null)
+            if (onClick != null) {
+                onClick(action = onClick)
+            }
         }
     ) {
         PressReleasedGestureDetector(
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/ColoredRect.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/ColoredRect.kt
index ab71fd2..b9b81f6 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/ColoredRect.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/ColoredRect.kt
@@ -23,8 +23,8 @@
 import androidx.ui.foundation.shape.DrawShape
 import androidx.ui.foundation.shape.RectangleShape
 import androidx.ui.graphics.Color
-import androidx.ui.graphics.vectorgraphics.Brush
-import androidx.ui.graphics.vectorgraphics.SolidColor
+import androidx.ui.graphics.Brush
+import androidx.ui.graphics.SolidColor
 import androidx.ui.layout.Container
 
 /**
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/DarkTheme.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/DarkTheme.kt
new file mode 100644
index 0000000..6dede3b
--- /dev/null
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/DarkTheme.kt
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2019 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.ui.foundation
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.content.res.Configuration
+import android.os.Build
+import android.os.PowerManager
+import androidx.annotation.RequiresApi
+import androidx.compose.ambient
+import androidx.compose.composer
+import androidx.compose.effectOf
+import androidx.compose.memo
+import androidx.compose.onActive
+import androidx.compose.state
+import androidx.ui.core.ConfigurationAmbient
+import androidx.ui.core.ContextAmbient
+
+/**
+ * This effect should be used to help build responsive UIs that follow the system setting, to avoid
+ * harsh contrast changes when switching between applications. The behaviour differs depending on
+ * API:
+ *
+ * On [Build.VERSION_CODES.Q] and above: returns the system-wide dark theme setting.
+ *
+ * On [Build.VERSION_CODES.P] and below: returns whether the device is in power saving mode or not,
+ * which can be considered analogous to dark theme for these devices.
+ *
+ * It is also recommended to provide user accessible overrides in your application, so users can
+ * choose to force an always-light or always-dark theme. To do this, you should provide the current
+ * theme value in an ambient or similar to components further down your hierarchy, only calling
+ * this effect once at the top level if no user override has been set. This also helps avoid
+ * multiple calls to this effect, which can be expensive as it queries system configuration.
+ *
+ * For example, to draw a white rectangle when in dark theme, and a black rectangle when in light
+ * theme:
+ *
+ * @sample androidx.ui.foundation.samples.DarkThemeSample
+ *
+ * @return `true` if the system is considered to be in 'dark theme'.
+ */
+fun isSystemInDarkTheme() = effectOf<Boolean> {
+    if (Build.VERSION.SDK_INT >= 29) {
+        +isSystemSetToDarkTheme()
+    } else {
+        +isInPowerSaveMode()
+    }
+}
+
+/**
+ * On [Build.VERSION_CODES.P] and below there is no system-wide dark theme toggle, so we use
+ * whether the device is in power save mode or not as an indicator here.
+ *
+ * @return `true` if the device is in power save mode
+ */
+private fun isInPowerSaveMode() = effectOf<Boolean> {
+    val context = +ambient(ContextAmbient)
+    val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
+
+    val isPowerSaveMode = +state { powerManager.isPowerSaveMode }
+
+    val broadcastReceiver = +memo {
+        object : BroadcastReceiver() {
+            override fun onReceive(context: Context?, intent: Intent?) {
+                isPowerSaveMode.value = powerManager.isPowerSaveMode
+            }
+        }
+    }
+
+    val intentFilter = +memo {
+        IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)
+    }
+
+    +onActive {
+        try {
+            context.registerReceiver(broadcastReceiver, intentFilter)
+        } catch (e: Exception) {
+            // already registered
+        }
+        onDispose {
+            try {
+                context.unregisterReceiver(broadcastReceiver)
+            } catch (e: Exception) {
+                // already unregistered
+            }
+        }
+    }
+
+    isPowerSaveMode.value
+}
+
+/**
+ * Check to see if [Configuration.UI_MODE_NIGHT_YES] bit is set. It is also possible for this bit to
+ * be [Configuration.UI_MODE_NIGHT_UNDEFINED], in which case we treat light theme as the default,
+ * so we return false.
+ *
+ * @return `true` if the system-wide dark theme toggle is enabled
+ */
+@RequiresApi(29)
+private fun isSystemSetToDarkTheme() = effectOf<Boolean> {
+    val configuration = +ambient(ConfigurationAmbient)
+    (configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
+}
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/DeterminateProgressIndicator.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/DeterminateProgressIndicator.kt
index a40b834..49a0b33 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/DeterminateProgressIndicator.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/DeterminateProgressIndicator.kt
@@ -17,10 +17,10 @@
 package androidx.ui.foundation
 
 import androidx.annotation.FloatRange
-import androidx.ui.core.Semantics
-import androidx.compose.Children
+import androidx.ui.semantics.Semantics
 import androidx.compose.Composable
 import androidx.compose.composer
+import androidx.ui.semantics.accessibilityValue
 
 /**
  * Contains the [Semantics] required for a determinate progress indicator, that represents progress
@@ -41,7 +41,7 @@
     if (progress !in 0f..1f) {
         throw IllegalArgumentException("Progress must be between 0.0 and 1.0")
     }
-    Semantics(value = ("$progress")) {
+    Semantics(properties = { accessibilityValue = "$progress" }) {
         children()
     }
 }
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Dialog.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Dialog.kt
index b6ad191..52fe83e 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Dialog.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Dialog.kt
@@ -19,8 +19,8 @@
 import android.app.Dialog
 import android.content.Context
 import android.view.MotionEvent
+import android.view.Window
 import android.widget.FrameLayout
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.ambient
 import androidx.compose.disposeComposition
@@ -69,6 +69,8 @@
 private class DialogWrapper(context: Context, val onCloseRequest: () -> Unit) : Dialog(context) {
     val frameLayout = FrameLayout(context)
     init {
+        window?.requestFeature(Window.FEATURE_NO_TITLE)
+        window?.setBackgroundDrawableResource(android.R.color.transparent)
         setContentView(frameLayout)
     }
 
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Strings.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Strings.kt
new file mode 100644
index 0000000..b9d0281
--- /dev/null
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Strings.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2019 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.ui.foundation
+
+// TODO(b/138327849): (STOPSHIP) Move all of these to resources once we have a real resources system,
+//  then delete this class
+@Suppress("MayBeConstant") // The compiler gets unhappy if these are const (b/138328700)
+object Strings {
+    val Checked = "Checked"
+    val Unchecked = "Unchecked"
+    val Indeterminate = "Indeterminate"
+    val Selected = "Selected"
+    val NotSelected = "Not selected"
+}
\ No newline at end of file
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/TableBorders.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/TableBorders.kt
new file mode 100644
index 0000000..ceeeed5
--- /dev/null
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/TableBorders.kt
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2019 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.ui.foundation
+
+import androidx.compose.composer
+import androidx.compose.memo
+import androidx.compose.unaryPlus
+import androidx.ui.core.Dp
+import androidx.ui.core.Draw
+import androidx.ui.engine.geometry.Offset
+import androidx.ui.foundation.shape.border.Border
+import androidx.ui.graphics.Color
+import androidx.ui.layout.Table
+import androidx.ui.layout.TableChildren
+import androidx.ui.painting.Paint
+
+/**
+ * Adds border drawing for a [Table] layout, when placed inside the [TableChildren] block.
+ *
+ * Example usage:
+ *
+ * @sample androidx.ui.foundation.samples.SimpleTableWithBorders
+ *
+ * @param defaultBorder The default style used for borders that do not specify a style.
+ */
+fun TableChildren.drawBorders(
+    defaultBorder: Border = Border(color = Color.Black, width = Dp.Hairline),
+    block: DrawBordersReceiver.() -> Unit
+) {
+    addDecoration { verticalOffsets, horizontalOffsets ->
+        val paint = +memo { Paint() }
+        Draw { canvas, _ ->
+            val borders = DrawBordersReceiver(
+                rowCount = verticalOffsets.size - 1,
+                columnCount = horizontalOffsets.size - 1,
+                defaultBorder = defaultBorder
+            ).also(block).borders
+            for ((border, row, column, orientation) in borders) {
+                val p1 = Offset(
+                    dx = horizontalOffsets[column].value.toFloat(),
+                    dy = verticalOffsets[row].value.toFloat()
+                )
+                val p2 = when (orientation) {
+                    BorderOrientation.Vertical -> p1.copy(
+                        dy = verticalOffsets[row + 1].value.toFloat()
+                    )
+                    BorderOrientation.Horizontal -> p1.copy(
+                        dx = horizontalOffsets[column + 1].value.toFloat()
+                    )
+                }
+                // TODO(calintat): Reset paint when that operation is available.
+                border.brush.applyBrush(paint)
+                paint.strokeWidth = border.width.toPx().value
+                canvas.drawLine(p1, p2, paint)
+            }
+        }
+    }
+}
+
+/**
+ * Collects information about the borders specified by [drawBorders]
+ * when its body is executed with a [DrawBordersReceiver] instance as argument.
+ */
+class DrawBordersReceiver internal constructor(
+    val rowCount: Int,
+    val columnCount: Int,
+    private val defaultBorder: Border
+) {
+    internal val borders = mutableListOf<BorderInfo>()
+
+    /**
+     * Add all borders.
+     */
+    fun all(border: Border = defaultBorder) {
+        allVertical(border)
+        allHorizontal(border)
+    }
+
+    /**
+     * Add all outer borders.
+     */
+    fun outer(border: Border = defaultBorder) {
+        left(border)
+        top(border)
+        right(border)
+        bottom(border)
+    }
+
+    /**
+     * Add a vertical border before the first column.
+     */
+    fun left(border: Border = defaultBorder) = vertical(column = 0, border = border)
+
+    /**
+     * Add a horizontal border before the first row.
+     */
+    fun top(border: Border = defaultBorder) = horizontal(row = 0, border = border)
+
+    /**
+     * Add a vertical border after the last column.
+     */
+    fun right(border: Border = defaultBorder) = vertical(column = columnCount, border = border)
+
+    /**
+     * Add a horizontal border after the last row.
+     */
+    fun bottom(border: Border = defaultBorder) = horizontal(row = rowCount, border = border)
+
+    /**
+     * Add all vertical borders.
+     */
+    fun allVertical(border: Border = defaultBorder) {
+        for (column in 0..columnCount) {
+            vertical(column, border = border)
+        }
+    }
+
+    /**
+     * Add all horizontal borders.
+     */
+    fun allHorizontal(border: Border = defaultBorder) {
+        for (row in 0..rowCount) {
+            horizontal(row, border = border)
+        }
+    }
+
+    /**
+     * Add a vertical border before [column] at the rows specified by [rows].
+     */
+    fun vertical(
+        column: Int,
+        rows: IntRange = 0 until rowCount,
+        border: Border = defaultBorder
+    ) {
+        if (column in 0..columnCount && 0 <= rows.start && rows.endInclusive < rowCount) {
+            for (row in rows) {
+                borders += BorderInfo(
+                    border = border,
+                    row = row,
+                    column = column,
+                    orientation = BorderOrientation.Vertical
+                )
+            }
+        }
+    }
+
+    /**
+     * Add a horizontal border before [row] at the columns specified by [columns].
+     */
+    fun horizontal(
+        row: Int,
+        columns: IntRange = 0 until columnCount,
+        border: Border = defaultBorder
+    ) {
+        if (row in 0..rowCount && 0 <= columns.start && columns.endInclusive < columnCount) {
+            for (column in columns) {
+                borders += BorderInfo(
+                    border = border,
+                    row = row,
+                    column = column,
+                    orientation = BorderOrientation.Horizontal
+                )
+            }
+        }
+    }
+}
+
+internal data class BorderInfo(
+    val border: Border,
+    val row: Int,
+    val column: Int,
+    val orientation: BorderOrientation
+)
+
+internal enum class BorderOrientation { Vertical, Horizontal }
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/gestures/Draggable.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/gestures/Draggable.kt
index 5fbcfc9..b59b95b 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/gestures/Draggable.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/gestures/Draggable.kt
@@ -23,7 +23,7 @@
 import androidx.ui.core.PxPosition
 import androidx.ui.foundation.animation.AnimatedFloatDragController
 import androidx.ui.foundation.animation.AnchorsFlingConfig
-import androidx.ui.core.gesture.DragGestureDetector
+import androidx.ui.core.gesture.TouchSlopDragGestureDetector
 import androidx.ui.core.gesture.DragObserver
 import androidx.ui.core.px
 
@@ -33,7 +33,7 @@
  * The common usecase for this component is when you need to be able to drag/scroll something
  * on the screen and represent it as one value via [DragValueController].
  *
- * If you need to control the whole dragging flow, consider using [DragGestureDetector] instead.
+ * If you need to control the whole dragging flow, consider using [TouchSlopDragGestureDetector] instead.
  *
  * @sample androidx.ui.foundation.samples.DraggableSample
  *
@@ -64,10 +64,7 @@
     +memo(valueController, minValue, maxValue) {
         valueController.setBounds(minValue, maxValue)
     }
-    DragGestureDetector(
-        canDrag = { direction ->
-            dragDirection.isDraggableInDirection(direction, minValue, current(), maxValue)
-        },
+    TouchSlopDragGestureDetector(
         dragObserver = object : DragObserver {
 
             override fun onDrag(dragDistance: PxPosition): PxPosition {
@@ -89,13 +86,15 @@
                     callback?.notifyFinished(it)
                 }
             }
+        },
+        canDrag = { direction ->
+            dragDirection.isDraggableInDirection(direction, minValue, current(), maxValue)
         }
     ) {
         children(current())
     }
 }
 
-
 class DraggableCallback(
     private val onDragStarted: () -> Unit = {},
     private val onDragSettled: (Float) -> Unit = {}
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/selection/MutuallyExclusiveSetItem.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/selection/MutuallyExclusiveSetItem.kt
index a199158..6646965 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/selection/MutuallyExclusiveSetItem.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/selection/MutuallyExclusiveSetItem.kt
@@ -16,23 +16,25 @@
 
 package androidx.ui.foundation.selection
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.ui.core.gesture.PressReleasedGestureDetector
-import androidx.ui.core.Semantics
-import androidx.ui.core.semantics.SemanticsAction
-import androidx.ui.core.semantics.SemanticsActionType
+import androidx.ui.foundation.Strings
+import androidx.ui.semantics.Semantics
+import androidx.ui.foundation.semantics.inMutuallyExclusiveGroup
+import androidx.ui.foundation.semantics.selected
+import androidx.ui.semantics.onClick
+import androidx.ui.semantics.accessibilityValue
 
 /**
- * Component for representing one option out of many
- * in mutually exclusion set, e.g [androidx.ui.material.RadioGroup]
- *
- * Provides click handling as well as [Semantics] for accessibility
- *
- * @param selected whether or not this item is selected in mutually exclusion set
- * @param onClick callback to invoke when this item is clicked
- */
+* Component for representing one option out of many
+* in mutually exclusion set, e.g [androidx.ui.material.RadioGroup]
+*
+* Provides click handling as well as [Semantics] for accessibility
+*
+* @param selected whether or not this item is selected in mutually exclusion set
+* @param onClick callback to invoke when this item is clicked
+*/
 @Composable
 fun MutuallyExclusiveSetItem(
     selected: Boolean,
@@ -40,11 +42,14 @@
     children: @Composable() () -> Unit
 ) {
     // TODO: when semantics can be merged, we should make this use Clickable internally rather
-    // than duplicating logic
+    //  than duplicating logic
     Semantics(
-        inMutuallyExclusiveGroup = true,
-        selected = selected,
-        actions = listOf<SemanticsAction<*>>(SemanticsAction(SemanticsActionType.Tap, onClick))) {
+        properties = {
+            inMutuallyExclusiveGroup = true
+            this.selected = selected
+            this.accessibilityValue = if (selected) Strings.Selected else Strings.NotSelected
+            onClick(action = onClick)
+        }) {
         PressReleasedGestureDetector(
             onRelease = onClick,
             consumeDownOnStart = false
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/selection/Toggleable.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/selection/Toggleable.kt
index a9f6f7b..ae08bf0 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/selection/Toggleable.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/selection/Toggleable.kt
@@ -16,13 +16,15 @@
 
 package androidx.ui.foundation.selection
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.ui.core.gesture.PressReleasedGestureDetector
-import androidx.ui.core.semantics.SemanticsAction
-import androidx.ui.core.semantics.SemanticsActionType
-import androidx.ui.core.Semantics
+import androidx.ui.foundation.Strings
+import androidx.ui.foundation.semantics.toggleableState
+import androidx.ui.semantics.Semantics
+import androidx.ui.semantics.enabled
+import androidx.ui.semantics.onClick
+import androidx.ui.semantics.accessibilityValue
 
 @Composable
 fun Toggleable(
@@ -30,26 +32,32 @@
     onToggle: (() -> Unit)? = null,
     children: @Composable() () -> Unit
 ) {
-    val actions = if (onToggle != null) {
-        listOf(SemanticsAction(SemanticsActionType.Tap, onToggle))
-    } else {
-        emptyList()
-    }
     PressReleasedGestureDetector(
         onRelease = onToggle,
-        consumeDownOnStart = false) {
+        consumeDownOnStart = false
+    ) {
         // TODO: enabled should not be hardcoded
-        // TODO(pavlis): Semantics currently doesn't support 4 states (only checked / unchecked / not checkable).
-        Semantics(
-            checked = (value == ToggleableState.Checked),
-            enabled = true,
-            actions = actions
-        ) {
+        // TODO(pavlis): Handle multiple states for Semantics
+        Semantics(properties = {
+            this.accessibilityValue = when (value) {
+                // TODO(ryanmentley): These should be set by Checkbox, Switch, etc.
+                ToggleableState.Checked -> Strings.Checked
+                ToggleableState.Unchecked -> Strings.Unchecked
+                ToggleableState.Indeterminate -> Strings.Indeterminate
+            }
+            this.toggleableState = value
+            this.enabled = true
+
+            if (onToggle != null) {
+                onClick(action = onToggle, label = "Toggle")
+            }
+        }) {
             children()
         }
     }
 }
 
+// TODO: These shouldn't use checkbox-specific language
 enum class ToggleableState {
     Checked,
     Unchecked,
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/semantics/FoundationSemanticsProperties.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/semantics/FoundationSemanticsProperties.kt
new file mode 100644
index 0000000..7525b72
--- /dev/null
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/semantics/FoundationSemanticsProperties.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019 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.ui.foundation.semantics
+
+import androidx.ui.foundation.selection.ToggleableState
+import androidx.ui.semantics.SemanticsPropertyKey
+import androidx.ui.semantics.SemanticsPropertyReceiver
+
+/**
+ * Semantics properties that apply to the Compose Foundation UI elements.  Used for making
+ * assertions in testing.
+ */
+object FoundationSemanticsProperties {
+    // TODO(ryanmentley): Is this useful?
+    val InMutuallyExclusiveGroup = SemanticsPropertyKey<Boolean>("InMutuallyExclusiveGroup")
+
+    val Selected = SemanticsPropertyKey<Boolean>("Selected")
+
+    // TODO(ryanmentley): Can we think of a better name?
+    val ToggleableState = SemanticsPropertyKey<ToggleableState>("ToggleableState")
+}
+
+// TODO(ryanmentley): should these be public?  is that confusing?
+
+// TODO(ryanmentley): This one is kind of weird...it's sort of nonsense if this one is ever false
+var SemanticsPropertyReceiver.inMutuallyExclusiveGroup
+        by FoundationSemanticsProperties.InMutuallyExclusiveGroup
+
+var SemanticsPropertyReceiver.selected by FoundationSemanticsProperties.Selected
+
+var SemanticsPropertyReceiver.toggleableState
+        by FoundationSemanticsProperties.ToggleableState
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/DrawShape.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/DrawShape.kt
index 1cd22be..f404358 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/DrawShape.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/DrawShape.kt
@@ -26,8 +26,8 @@
 import androidx.ui.engine.geometry.Shape
 import androidx.ui.engine.geometry.drawOutline
 import androidx.ui.graphics.Color
-import androidx.ui.graphics.vectorgraphics.Brush
-import androidx.ui.graphics.vectorgraphics.SolidColor
+import androidx.ui.graphics.Brush
+import androidx.ui.graphics.SolidColor
 import androidx.ui.painting.Paint
 
 /**
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/border/Border.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/border/Border.kt
index 62f871a..7eaa1f4 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/border/Border.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/border/Border.kt
@@ -18,12 +18,12 @@
 
 import androidx.ui.core.Dp
 import androidx.ui.graphics.Color
-import androidx.ui.graphics.vectorgraphics.Brush
-import androidx.ui.graphics.vectorgraphics.SolidColor
+import androidx.ui.graphics.Brush
+import androidx.ui.graphics.SolidColor
 
 /**
- * A border of a shape.
- * It will be drawn on top of the shape as an inner stroke.
+ * A border of a shape which will be drawn on top of the shape as an inner stroke.
+ * This can also be used for the border of a table layout.
  *
  * @param brush the brush to paint the border with.
  * @param width the width of the border. Use [Dp.Hairline] for a hairline border.
@@ -31,8 +31,8 @@
 data class Border(val brush: Brush, val width: Dp)
 
 /**
- * A border of a shape.
- * It will be drawn on top of the shape as an inner stroke.
+ * A border of a shape which will be drawn on top of the shape as an inner stroke.
+ * This can also be used for the border of a table layout.
  *
  * @param color the color to fill the border with.
  * @param width the width of the border. Use [Dp.Hairline] for a hairline border.
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/corner/CornerBasedShape.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/corner/CornerBasedShape.kt
index 7145a6d..89ec2be 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/corner/CornerBasedShape.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/corner/CornerBasedShape.kt
@@ -17,36 +17,59 @@
 package androidx.ui.foundation.shape.corner
 
 import androidx.ui.core.Density
+import androidx.ui.core.Px
 import androidx.ui.core.PxSize
+import androidx.ui.core.px
 import androidx.ui.core.toRect
 import androidx.ui.engine.geometry.Outline
 import androidx.ui.engine.geometry.Shape
 
 /**
- * Base class for [Shape]s defined by [CornerSizes].
+ * Base class for [Shape]s defined by four [CornerSize]s.
  *
- * @see RoundedCornerShape for an example of the usage
+ * @see RoundedCornerShape for an example of the usage.
  *
- * @param corners define all four corner sizes
+ * @param topLeft a size of the top left corner
+ * @param topRight a size of the top right corner
+ * @param bottomRight a size of the bottom left corner
+ * @param bottomLeft a size of the bottom right corner
  */
 abstract class CornerBasedShape(
-    private val corners: CornerSizes
+    private val topLeft: CornerSize,
+    private val topRight: CornerSize,
+    private val bottomRight: CornerSize,
+    private val bottomLeft: CornerSize
 ) : Shape {
 
     final override fun createOutline(size: PxSize, density: Density): Outline {
-        val corners = PxCornerSizes(corners, size, density)
-        return if (corners.isEmpty()) {
+        val topLeft = topLeft.toPx(size, density)
+        val topRight = topRight.toPx(size, density)
+        val bottomRight = bottomRight.toPx(size, density)
+        val bottomLeft = bottomLeft.toPx(size, density)
+        require(topLeft >= 0.px && topRight >= 0.px && bottomRight >= 0.px && bottomLeft >= 0.px) {
+            "Corner size in Px can't be negative!"
+        }
+        return if (topLeft + topRight + bottomLeft + bottomRight == 0.px) {
             Outline.Rectangle(size.toRect())
         } else {
-            createOutline(corners, size)
+            createOutline(size, topLeft, topRight, bottomRight, bottomLeft)
         }
     }
 
     /**
-     * @param corners the resolved sizes of all the four corners in pixels.
      * @param size the size of the shape boundary.
+     * @param topLeft the resolved size of the top left corner
+     * @param topRight the resolved size for the top right corner
+     * @param bottomRight the resolved size for the bottom left corner
+     * @param bottomLeft the resolved size for the bottom right corner
      *
      * @return [Outline] of this shape for the given [size].
      */
-    abstract fun createOutline(corners: PxCornerSizes, size: PxSize): Outline
+    abstract fun createOutline(
+        size: PxSize,
+        topLeft: Px,
+        topRight: Px,
+        bottomRight: Px,
+        bottomLeft: Px
+    ): Outline
 }
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/corner/CornerSizes.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/corner/CornerSizes.kt
deleted file mode 100644
index b689b08..0000000
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/corner/CornerSizes.kt
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2019 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.ui.foundation.shape.corner
-
-import androidx.annotation.IntRange
-import androidx.ui.core.Dp
-import androidx.ui.core.Px
-import androidx.ui.core.dp
-import androidx.ui.core.px
-
-/**
- * Contains sizes of all four corner sizes for a shape.
- *
- * @param topLeft a size for the top left corner
- * @param topRight a size for the top right corner
- * @param bottomRight a size for the bottom left corner
- * @param bottomLeft a size for the bottom right corner
- */
-data class CornerSizes(
-    val topLeft: CornerSize,
-    val topRight: CornerSize,
-    val bottomRight: CornerSize,
-    val bottomLeft: CornerSize
-)
-
-/**
- * Creates [CornerSizes] with the same size applied for all four corners.
- */
-/*inline*/ fun CornerSizes(allCornersSize: CornerSize) = CornerSizes(
-    allCornersSize,
-    allCornersSize,
-    allCornersSize,
-    allCornersSize
-)
-
-/**
- * Creates [CornerSizes] with the same size applied for all four corners.
- */
-/*inline*/ fun CornerSizes(size: Dp) = CornerSizes(CornerSize(size))
-
-/**
- * Creates [CornerSizes] with the same size applied for all four corners.
- */
-/*inline*/ fun CornerSizes(size: Px) = CornerSizes(CornerSize(size))
-
-/**
- * Creates [CornerSizes] with the same size applied for all four corners.
- */
-/*inline*/ fun CornerSizes(percent: Int) = CornerSizes(CornerSize(percent))
-
-/**
- * Creates [CornerSizes] with sizes defined by [Dp].
- */
-/*inline*/ fun CornerSizes(
-    topLeft: Dp = 0.dp,
-    topRight: Dp = 0.dp,
-    bottomRight: Dp = 0.dp,
-    bottomLeft: Dp = 0.dp
-) = CornerSizes(
-    CornerSize(topLeft),
-    CornerSize(topRight),
-    CornerSize(bottomRight),
-    CornerSize(bottomLeft)
-)
-
-/**
- * Creates [CornerSizes] with sizes defined by [Px].
- */
-/*inline*/ fun CornerSizes(
-    topLeft: Px = 0.px,
-    topRight: Px = 0.px,
-    bottomRight: Px = 0.px,
-    bottomLeft: Px = 0.px
-) = CornerSizes(
-    CornerSize(topLeft),
-    CornerSize(topRight),
-    CornerSize(bottomRight),
-    CornerSize(bottomLeft)
-)
-
-/**
- * Creates [CornerSizes] with sizes defined by percents of the shape's smaller side.
- */
-/*inline*/ fun CornerSizes(
-    @IntRange(from = 0, to = 50) topLeftPercent: Int = 0,
-    @IntRange(from = 0, to = 50) topRightPercent: Int = 0,
-    @IntRange(from = 0, to = 50) bottomRightPercent: Int = 0,
-    @IntRange(from = 0, to = 50) bottomLeftPercent: Int = 0
-) = CornerSizes(
-    CornerSize(topLeftPercent),
-    CornerSize(topRightPercent),
-    CornerSize(bottomRightPercent),
-    CornerSize(bottomLeftPercent)
-)
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/corner/PxCornerSizes.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/corner/PxCornerSizes.kt
deleted file mode 100644
index f6d1b58..0000000
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/corner/PxCornerSizes.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2019 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.ui.foundation.shape.corner
-
-import androidx.ui.core.Density
-import androidx.ui.core.Px
-import androidx.ui.core.PxSize
-import androidx.ui.core.px
-
-/**
- * Contains sizes of all four corner sizes for a shape resolved in Pixels
- *
- * @param topLeft a size for the top left corner
- * @param topRight a size for the top right corner
- * @param bottomRight a size for the bottom left corner
- * @param bottomLeft a size for the bottom right corner
- */
-data class PxCornerSizes(
-    val topLeft: Px,
-    val topRight: Px,
-    val bottomRight: Px,
-    val bottomLeft: Px
-) {
-    init {
-        if (topLeft < 0.px || topRight < 0.px || bottomRight < 0.px || bottomLeft < 0.px) {
-            throw IllegalArgumentException("Corner size in Px can't be negative!")
-        }
-    }
-}
-
-/**
- * @return true if all the sizes are equals to 0 pixels.
- */
-/*inline*/ fun PxCornerSizes.isEmpty() =
-    topLeft + topRight + bottomLeft + bottomRight == 0.px
-
-/**
- * @param corners define all four corner sizes
- * @param size the size of the shape
- * @param density the current density of the screen.
- *
- * @return resolved [PxCornerSizes].
- */
-/*inline*/ fun PxCornerSizes(
-    corners: CornerSizes,
-    size: PxSize,
-    density: Density
-): PxCornerSizes = with(corners) {
-    PxCornerSizes(
-        topLeft = topLeft.toPx(size, density),
-        topRight = topRight.toPx(size, density),
-        bottomRight = bottomRight.toPx(size, density),
-        bottomLeft = bottomLeft.toPx(size, density)
-    )
-}
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/corner/RoundedCornerShape.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/corner/RoundedCornerShape.kt
index acbfd2d8..4c9c81f 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/corner/RoundedCornerShape.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/shape/corner/RoundedCornerShape.kt
@@ -16,8 +16,12 @@
 
 package androidx.ui.foundation.shape.corner
 
+import androidx.annotation.IntRange
+import androidx.ui.core.Dp
 import androidx.ui.core.Px
 import androidx.ui.core.PxSize
+import androidx.ui.core.dp
+import androidx.ui.core.px
 import androidx.ui.core.toRect
 import androidx.ui.engine.geometry.Outline
 import androidx.ui.engine.geometry.RRect
@@ -27,20 +31,31 @@
 /**
  * A shape describing the rectangle with rounded corners.
  *
- * @param corners define all four corner sizes
+ * @param topLeft a size of the top left corner
+ * @param topRight a size of the top right corner
+ * @param bottomRight a size of the bottom left corner
+ * @param bottomLeft a size of the bottom right corner
  */
 data class RoundedCornerShape(
-    val corners: CornerSizes
-) : CornerBasedShape(corners) {
+    val topLeft: CornerSize,
+    val topRight: CornerSize,
+    val bottomRight: CornerSize,
+    val bottomLeft: CornerSize
+) : CornerBasedShape(topLeft, topRight, bottomRight, bottomLeft) {
 
-    override fun createOutline(corners: PxCornerSizes, size: PxSize) =
-        Outline.Rounded(
+    override fun createOutline(
+        size: PxSize,
+        topLeft: Px,
+        topRight: Px,
+        bottomRight: Px,
+        bottomLeft: Px
+    ) = Outline.Rounded(
             RRect(
                 rect = size.toRect(),
-                topLeft = corners.topLeft.toRadius(),
-                topRight = corners.topRight.toRadius(),
-                bottomRight = corners.bottomRight.toRadius(),
-                bottomLeft = corners.bottomLeft.toRadius()
+                topLeft = topLeft.toRadius(),
+                topRight = topRight.toRadius(),
+                bottomRight = bottomRight.toRadius(),
+                bottomLeft = bottomLeft.toRadius()
             )
         )
 
@@ -48,14 +63,72 @@
 }
 
 /**
- * A shape describing the rectangle with rounded corners.
- *
- * @param corner size to apply for all four corners
- */
-/*inline*/ fun RoundedCornerShape(corner: CornerSize) =
-    RoundedCornerShape(CornerSizes(corner))
-
-/**
  * Circular [Shape] with all the corners sized as the 50 percent of the shape size.
  */
-val CircleShape = RoundedCornerShape(CornerSizes(CornerSize(50)))
+val CircleShape = RoundedCornerShape(50)
+
+/**
+ * Creates [RoundedCornerShape] with the same size applied for all four corners.
+ */
+/*inline*/ fun RoundedCornerShape(corner: CornerSize) =
+    RoundedCornerShape(corner, corner, corner, corner)
+
+/**
+ * Creates [RoundedCornerShape] with the same size applied for all four corners.
+ */
+/*inline*/ fun RoundedCornerShape(size: Dp) = RoundedCornerShape(CornerSize(size))
+
+/**
+ * Creates [RoundedCornerShape] with the same size applied for all four corners.
+ */
+/*inline*/ fun RoundedCornerShape(size: Px) = RoundedCornerShape(CornerSize(size))
+
+/**
+ * Creates [RoundedCornerShape] with the same size applied for all four corners.
+ */
+/*inline*/ fun RoundedCornerShape(percent: Int) = RoundedCornerShape(CornerSize(percent))
+
+/**
+ * Creates [RoundedCornerShape] with sizes defined by [Dp].
+ */
+/*inline*/ fun RoundedCornerShape(
+    topLeft: Dp = 0.dp,
+    topRight: Dp = 0.dp,
+    bottomRight: Dp = 0.dp,
+    bottomLeft: Dp = 0.dp
+) = RoundedCornerShape(
+    CornerSize(topLeft),
+    CornerSize(topRight),
+    CornerSize(bottomRight),
+    CornerSize(bottomLeft)
+)
+
+/**
+ * Creates [RoundedCornerShape] with sizes defined by [Px].
+ */
+/*inline*/ fun RoundedCornerShape(
+    topLeft: Px = 0.px,
+    topRight: Px = 0.px,
+    bottomRight: Px = 0.px,
+    bottomLeft: Px = 0.px
+) = RoundedCornerShape(
+    CornerSize(topLeft),
+    CornerSize(topRight),
+    CornerSize(bottomRight),
+    CornerSize(bottomLeft)
+)
+
+/**
+ * Creates [RoundedCornerShape] with sizes defined by percents of the shape's smaller side.
+ */
+/*inline*/ fun RoundedCornerShape(
+    @IntRange(from = 0, to = 50) topLeftPercent: Int = 0,
+    @IntRange(from = 0, to = 50) topRightPercent: Int = 0,
+    @IntRange(from = 0, to = 50) bottomRightPercent: Int = 0,
+    @IntRange(from = 0, to = 50) bottomLeftPercent: Int = 0
+) = RoundedCornerShape(
+    CornerSize(topLeftPercent),
+    CornerSize(topRightPercent),
+    CornerSize(bottomRightPercent),
+    CornerSize(bottomLeftPercent)
+)
diff --git a/ui/ui-framework/api/1.0.0-alpha01.txt b/ui/ui-framework/api/1.0.0-alpha01.txt
index 56e2390..2f60003 100644
--- a/ui/ui-framework/api/1.0.0-alpha01.txt
+++ b/ui/ui-framework/api/1.0.0-alpha01.txt
@@ -6,12 +6,23 @@
     method public static void Clip(androidx.ui.engine.geometry.Shape shape, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
+  public final class ComplexLayoutBlockReceiver implements androidx.ui.core.DensityReceiver {
+    method public androidx.ui.core.Density getDensity();
+    method public androidx.ui.core.LayoutResult layout(androidx.ui.core.IntPx width, androidx.ui.core.IntPx height, kotlin.jvm.functions.Function1<? super androidx.ui.core.PositioningBlockReceiver,kotlin.Unit> positioningBlock);
+    method public androidx.ui.core.IntPx maxIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
+    method public androidx.ui.core.IntPx maxIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
+    method public androidx.ui.core.Placeable measure(androidx.ui.core.Measurable, androidx.ui.core.Constraints constraints);
+    method public androidx.ui.core.IntPx minIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
+    method public androidx.ui.core.IntPx minIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
+    property public androidx.ui.core.Density density;
+  }
+
   public final class ComplexLayoutReceiver {
-    method public void layout(kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutBlockReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,kotlin.Unit> layoutBlock);
-    method public void maxIntrinsicHeight(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementsReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> maxIntrinsicHeightBlock);
-    method public void maxIntrinsicWidth(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementsReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> maxIntrinsicWidthBlock);
-    method public void minIntrinsicHeight(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementsReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> minIntrinsicHeightBlock);
-    method public void minIntrinsicWidth(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementsReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> minIntrinsicWidthBlock);
+    method public void maxIntrinsicHeight(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> maxIntrinsicHeightBlock);
+    method public void maxIntrinsicWidth(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> maxIntrinsicWidthBlock);
+    method public void measure(kotlin.jvm.functions.Function3<? super androidx.ui.core.ComplexLayoutBlockReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,androidx.ui.core.LayoutResult> layoutBlock);
+    method public void minIntrinsicHeight(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> minIntrinsicHeightBlock);
+    method public void minIntrinsicWidth(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> minIntrinsicWidthBlock);
   }
 
   public final class DrawKt {
@@ -20,19 +31,12 @@
     method public static void Draw(kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function3<? super androidx.ui.core.DrawReceiver,? super androidx.ui.painting.Canvas,? super androidx.ui.core.PxSize,kotlin.Unit> onPaint);
   }
 
-  public final class EditorStyle {
-    ctor public EditorStyle(androidx.ui.text.TextStyle? textStyle, androidx.ui.graphics.Color compositionColor, androidx.ui.graphics.Color selectionColor);
-    ctor public EditorStyle();
-    method public androidx.ui.text.TextStyle? component1();
-    method public androidx.ui.graphics.Color component2();
-    method public androidx.ui.graphics.Color component3();
-    method public androidx.ui.core.EditorStyle copy(androidx.ui.text.TextStyle? textStyle, androidx.ui.graphics.Color compositionColor, androidx.ui.graphics.Color selectionColor);
-    method public androidx.ui.graphics.Color getCompositionColor();
-    method public androidx.ui.graphics.Color getSelectionColor();
-    method public androidx.ui.text.TextStyle? getTextStyle();
+  public final class DrawShadowKt {
+    ctor public DrawShadowKt();
+    method public static void DrawShadow(androidx.ui.engine.geometry.Shape shape, androidx.ui.core.Dp elevation);
   }
 
-  public final class IntrinsicMeasurementsReceiver implements androidx.ui.core.DensityReceiver {
+  public final class IntrinsicMeasurementReceiver implements androidx.ui.core.DensityReceiver {
     method public androidx.ui.core.Density getDensity();
     method public androidx.ui.core.IntPx maxIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
     method public androidx.ui.core.IntPx maxIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
@@ -42,13 +46,10 @@
   }
 
   public final class LayoutBlockReceiver implements androidx.ui.core.DensityReceiver {
+    method public operator java.util.List<androidx.ui.core.Measurable> get(java.util.List<? extends androidx.ui.core.Measurable>, kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public androidx.ui.core.Density getDensity();
-    method public void layoutResult(androidx.ui.core.IntPx width, androidx.ui.core.IntPx height, kotlin.jvm.functions.Function1<? super androidx.ui.core.PositioningBlockReceiver,kotlin.Unit> block);
-    method public androidx.ui.core.IntPx maxIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
-    method public androidx.ui.core.IntPx maxIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
+    method public androidx.ui.core.LayoutResult layout(androidx.ui.core.IntPx width, androidx.ui.core.IntPx height, kotlin.jvm.functions.Function1<? super androidx.ui.core.PositioningBlockReceiver,kotlin.Unit> positioningBlock);
     method public androidx.ui.core.Placeable measure(androidx.ui.core.Measurable, androidx.ui.core.Constraints constraints);
-    method public androidx.ui.core.IntPx minIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
-    method public androidx.ui.core.IntPx minIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
     property public androidx.ui.core.Density density;
   }
 
@@ -67,19 +68,18 @@
   public final class LayoutKt {
     ctor public LayoutKt();
     method public static void ComplexLayout(kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function1<? super androidx.ui.core.ComplexLayoutReceiver,kotlin.Unit> block);
-    method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,kotlin.Unit> layoutBlock);
-    method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit>![] childrenArray, kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,kotlin.Unit> layoutBlock);
+    method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutBlockReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,androidx.ui.core.LayoutResult> measureBlock);
+    method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit>![] childrenArray, kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutBlockReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,androidx.ui.core.LayoutResult> measureBlock);
     method public static void OnChildPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned, kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static void OnPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned);
     method public static void WithConstraints(kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
   }
 
-  public final class LayoutReceiver implements androidx.ui.core.DensityReceiver {
-    method public operator java.util.List<androidx.ui.core.Measurable> get(java.util.List<? extends androidx.ui.core.Measurable>, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public androidx.ui.core.Density getDensity();
-    method public void layout(androidx.ui.core.IntPx width, androidx.ui.core.IntPx height, kotlin.jvm.functions.Function1<? super androidx.ui.core.PositioningBlockReceiver,kotlin.Unit> block);
-    method public androidx.ui.core.Placeable measure(androidx.ui.core.Measurable, androidx.ui.core.Constraints constraints);
-    property public androidx.ui.core.Density density;
+  public final class LayoutResult {
+    field public static final androidx.ui.core.LayoutResult.Companion! Companion;
+  }
+
+  public static final class LayoutResult.Companion {
   }
 
   public interface Measurable {
@@ -87,11 +87,6 @@
     property public abstract Object? parentData;
   }
 
-  public interface OffsetMap {
-    method public int originalToTransformed(int offset);
-    method public int transformedToOriginal(int offset);
-  }
-
   public final class OpacityKt {
     ctor public OpacityKt();
     method public static void Opacity(@FloatRange(from=0.0, to=1.0) float opacity, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -102,13 +97,6 @@
     method public static void ParentData(Object data, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class PasswordVisualTransformation implements androidx.ui.core.VisualTransformation {
-    ctor public PasswordVisualTransformation(char mask);
-    ctor public PasswordVisualTransformation();
-    method public androidx.ui.core.TransformedText filter(androidx.ui.text.AnnotatedString text);
-    method public char getMask();
-  }
-
   public abstract class Placeable {
     ctor public Placeable();
     method public abstract androidx.ui.core.IntPx getHeight();
@@ -134,11 +122,6 @@
     method public static void RepaintBoundary(String? name = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class SemanticsKt {
-    ctor public SemanticsKt();
-    method public static void Semantics(boolean container = false, boolean explicitChildNodes = false, Boolean? enabled = null, Boolean? checked = null, Boolean? selected = null, Boolean? button = null, Boolean? inMutuallyExclusiveGroup = null, Boolean? hidden = null, String? label = null, String? value = null, androidx.ui.text.style.TextDirection? textDirection = null, String? testTag = null, java.util.List<? extends androidx.ui.core.semantics.SemanticsAction<?>> actions = emptyList(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
   public final class TestTagProviderKt {
     ctor public TestTagProviderKt();
     method public static void TestTag(String tag, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -146,9 +129,13 @@
     method public static androidx.compose.Ambient<java.lang.String> getTestTagAmbient();
   }
 
+  public final class TextFieldDelegateKt {
+    ctor public TextFieldDelegateKt();
+  }
+
   public final class TextFieldKt {
     ctor public TextFieldKt();
-    method public static void TextField(androidx.ui.input.EditorModel value, androidx.ui.core.EditorStyle editorStyle, androidx.ui.input.KeyboardType keyboardType = KeyboardType.Text, androidx.ui.input.ImeAction imeAction = ImeAction.Unspecified, kotlin.jvm.functions.Function1<? super androidx.ui.input.EditorModel,kotlin.Unit> onValueChange = {}, kotlin.jvm.functions.Function0<kotlin.Unit> onFocus = {}, kotlin.jvm.functions.Function0<kotlin.Unit> onBlur = {}, kotlin.jvm.functions.Function1<? super androidx.ui.input.ImeAction,kotlin.Unit> onImeActionPerformed = {}, androidx.ui.core.VisualTransformation? visualTransformation = null);
+    method public static void TextField(androidx.ui.input.EditorModel value, androidx.ui.input.EditorStyle editorStyle, androidx.ui.input.KeyboardType keyboardType = KeyboardType.Text, androidx.ui.input.ImeAction imeAction = ImeAction.Unspecified, kotlin.jvm.functions.Function1<? super androidx.ui.input.EditorModel,kotlin.Unit> onValueChange = {}, kotlin.jvm.functions.Function0<kotlin.Unit> onFocus = {}, kotlin.jvm.functions.Function0<kotlin.Unit> onBlur = {}, kotlin.jvm.functions.Function1<? super androidx.ui.input.ImeAction,kotlin.Unit> onImeActionPerformed = {}, androidx.ui.input.VisualTransformation? visualTransformation = null);
   }
 
   public final class TextKt {
@@ -186,31 +173,18 @@
     method public androidx.ui.core.TextSpanComposition getComposer();
   }
 
-  public final class TransformedText {
-    ctor public TransformedText(androidx.ui.text.AnnotatedString transformedText, androidx.ui.core.OffsetMap offsetMap);
-    method public androidx.ui.text.AnnotatedString component1();
-    method public androidx.ui.core.OffsetMap component2();
-    method public androidx.ui.core.TransformedText copy(androidx.ui.text.AnnotatedString transformedText, androidx.ui.core.OffsetMap offsetMap);
-    method public androidx.ui.core.OffsetMap getOffsetMap();
-    method public androidx.ui.text.AnnotatedString getTransformedText();
-  }
-
-  public interface VisualTransformation {
-    method public androidx.ui.core.TransformedText filter(androidx.ui.text.AnnotatedString text);
-  }
-
-  public final class VisualTransformationKt {
-    ctor public VisualTransformationKt();
-  }
-
   public final class WrapperKt {
     ctor public WrapperKt();
     method public static void ComposeView(kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static void WithDensity(kotlin.jvm.functions.Function1<? super androidx.ui.core.DensityReceiver,kotlin.Unit> block);
     method @CheckResult(suggest="+") public static androidx.compose.Effect<androidx.ui.core.Density> ambientDensity();
+    method public static androidx.compose.Ambient<androidx.ui.autofill.Autofill> getAutofillAmbient();
+    method public static androidx.compose.Ambient<androidx.ui.autofill.AutofillTree> getAutofillTreeAmbient();
+    method public static androidx.compose.Ambient<android.content.res.Configuration> getConfigurationAmbient();
     method public static androidx.compose.Ambient<android.content.Context> getContextAmbient();
     method public static androidx.compose.Ambient<kotlin.coroutines.CoroutineContext> getCoroutineContextAmbient();
     method public static androidx.compose.Ambient<androidx.ui.core.Density> getDensityAmbient();
+    method public static androidx.compose.Ambient<androidx.ui.core.LayoutDirection> getLayoutDirectionAmbient();
     method public static androidx.compose.CompositionContext? setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.CompositionContext? setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @CheckResult(suggest="+") public static <R> androidx.compose.Effect<R> withDensity(kotlin.jvm.functions.Function1<? super androidx.ui.core.DensityReceiver,? extends R> block);
@@ -246,11 +220,6 @@
     method public static void DoubleTapGestureDetector(kotlin.jvm.functions.Function1<? super androidx.ui.core.PxPosition,kotlin.Unit> onDoubleTap, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class DragGestureDetectorKt {
-    ctor public DragGestureDetectorKt();
-    method public static void DragGestureDetector(kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean>? canDrag = null, androidx.ui.core.gesture.DragObserver? dragObserver = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
   public interface DragObserver {
     method public default androidx.ui.core.PxPosition onDrag(androidx.ui.core.PxPosition dragDistance);
     method public default void onStart();
@@ -277,6 +246,21 @@
     method public static void PressReleasedGestureDetector(kotlin.jvm.functions.Function0<kotlin.Unit>? onRelease = null, boolean consumeDownOnStart = true, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
+  public final class RawDragGestureDetectorKt {
+    ctor public RawDragGestureDetectorKt();
+    method public static void RawDragGestureDetector(androidx.ui.core.gesture.DragObserver dragObserver, kotlin.jvm.functions.Function0<java.lang.Boolean>? canStartDragging = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+  }
+
+  public final class TouchSlopDragGestureDetectorKt {
+    ctor public TouchSlopDragGestureDetectorKt();
+    method public static void TouchSlopDragGestureDetector(androidx.ui.core.gesture.DragObserver dragObserver, kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean>? canDrag = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+  }
+
+  public final class TouchSlopExceededGestureDetectorKt {
+    ctor public TouchSlopExceededGestureDetectorKt();
+    method public static void TouchSlopExceededGestureDetector(kotlin.jvm.functions.Function0<kotlin.Unit> onTouchSlopExceeded, kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean>? canDrag = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+  }
+
 }
 
 package androidx.ui.core.gesture.util {
@@ -369,7 +353,8 @@
 
   public final class VectorComposeKt {
     ctor public VectorComposeKt();
-    method public static void DrawVector(float viewportWidth, float viewportHeight, androidx.ui.core.Px defaultWidth = Px(viewportWidth), androidx.ui.core.Px defaultHeight = Px(viewportHeight), String name = "", kotlin.jvm.functions.Function1<? super androidx.ui.vector.VectorScope,kotlin.Unit> children);
+    method public static void DrawVector(androidx.ui.core.Dp defaultWidth, androidx.ui.core.Dp defaultHeight, float viewportWidth = -1.0f, float viewportHeight = -1.0f, String name = "", kotlin.jvm.functions.Function3<? super androidx.ui.vector.VectorScope,? super java.lang.Float,? super java.lang.Float,kotlin.Unit> children);
+    method public static void DrawVector(androidx.ui.core.Px defaultWidth, androidx.ui.core.Px defaultHeight, float viewportWidth = defaultWidth.value, float viewportHeight = defaultHeight.value, String name = "", kotlin.jvm.functions.Function3<? super androidx.ui.vector.VectorScope,? super java.lang.Float,? super java.lang.Float,kotlin.Unit> children);
     method public static void Group(androidx.ui.vector.VectorScope, String name = "", float rotation = 0.0f, float pivotX = 0.0f, float pivotY = 0.0f, float scaleX = 1.0f, float scaleY = 1.0f, float translationX = 0.0f, float translationY = 0.0f, Object? clipPathData = EmptyPath, kotlin.jvm.functions.Function1<? super androidx.ui.vector.VectorScope,kotlin.Unit> children);
     method public static void Path(androidx.ui.vector.VectorScope, Object? pathData, String name = "", Object fill = EmptyBrush, float fillAlpha = 1.0f, Object stroke = EmptyBrush, float strokeAlpha = 1.0f, float strokeLineWidth = 0.0f, androidx.ui.painting.StrokeCap strokeLineCap = DefaultStrokeLineCap, androidx.ui.painting.StrokeJoin strokeLineJoin = DefaultStrokeLineJoin, float strokeLineMiter = 4.0f);
   }
@@ -415,8 +400,9 @@
 
   public final class VectorResourceKt {
     ctor public VectorResourceKt();
-    method public static void VectorResource(int resId);
+    method public static void DrawVectorResource(int resId);
     method public static androidx.ui.core.vectorgraphics.VectorAsset loadVectorResource(android.content.res.Resources.Theme? theme = null, android.content.res.Resources res, int resId) throws org.xmlpull.v1.XmlPullParserException;
+    method @CheckResult(suggest="+") public static androidx.compose.Effect<androidx.ui.core.vectorgraphics.VectorAsset> vectorResource(int resId);
   }
 
   public final class XmlVectorParserKt {
@@ -425,3 +411,61 @@
 
 }
 
+package androidx.ui.semantics {
+
+  public final class SemanticsActions {
+    ctor public SemanticsActions();
+    field public static final androidx.ui.semantics.SemanticsActions.Companion! Companion;
+  }
+
+  public static final class SemanticsActions.Companion {
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.util.List<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>>> getCustomActions();
+    method public androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>> getOnClick();
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.util.List<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>>> CustomActions;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>> OnClick;
+  }
+
+  public final class SemanticsKt {
+    ctor public SemanticsKt();
+    method public static void Semantics(boolean container = false, boolean explicitChildNodes = false, kotlin.jvm.functions.Function1<? super androidx.ui.semantics.SemanticsPropertyReceiver,kotlin.Unit>? properties = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+  }
+
+  public final class SemanticsProperties {
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> getAccessibilityLabel();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> getAccessibilityValue();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getEnabled();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getHidden();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> getTestTag();
+    method public androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.text.style.TextDirection> getTextDirection();
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> AccessibilityLabel;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> AccessibilityValue;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Enabled;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Hidden;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> TestTag;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.text.style.TextDirection> TextDirection;
+    field public static final androidx.ui.semantics.SemanticsProperties! INSTANCE;
+  }
+
+  public final class SemanticsPropertiesKt {
+    ctor public SemanticsPropertiesKt();
+    method public static String getAccessibilityLabel(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static String getAccessibilityValue(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static java.util.List<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>> getCustomActions(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static boolean getEnabled(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static boolean getHidden(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>> getOnClick(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static String getTestTag(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.ui.text.style.TextDirection getTextDirection(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static void onClick(androidx.ui.semantics.SemanticsPropertyReceiver, String? label = null, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+    method public static void setAccessibilityLabel(androidx.ui.semantics.SemanticsPropertyReceiver, String p);
+    method public static void setAccessibilityValue(androidx.ui.semantics.SemanticsPropertyReceiver, String p);
+    method public static void setCustomActions(androidx.ui.semantics.SemanticsPropertyReceiver, java.util.List<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>> p);
+    method public static void setEnabled(androidx.ui.semantics.SemanticsPropertyReceiver, boolean p);
+    method public static void setHidden(androidx.ui.semantics.SemanticsPropertyReceiver, boolean p);
+    method public static void setOnClick(androidx.ui.semantics.SemanticsPropertyReceiver, androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>> p);
+    method public static void setTestTag(androidx.ui.semantics.SemanticsPropertyReceiver, String p);
+    method public static void setTextDirection(androidx.ui.semantics.SemanticsPropertyReceiver, androidx.ui.text.style.TextDirection p);
+  }
+
+}
+
diff --git a/ui/ui-framework/api/api_lint.ignore b/ui/ui-framework/api/api_lint.ignore
index a728327..a8db659 100644
--- a/ui/ui-framework/api/api_lint.ignore
+++ b/ui/ui-framework/api/api_lint.ignore
@@ -1,13 +1,11 @@
 // Baseline format: 1.0
-BannedThrow: androidx.ui.core.vectorgraphics.PathCommandKt#toPathCommand(char):
-    Methods must not mention RuntimeException subclasses in throws clauses (was `java.lang.IllegalArgumentException`)
-BannedThrow: androidx.ui.core.vectorgraphics.PathParser#parsePathString(String):
-    Methods must not mention RuntimeException subclasses in throws clauses (was `java.lang.IllegalArgumentException`)
-
-
 CallbackName: androidx.ui.core.gesture.DragObserver:
     Class should be named DragCallback
 
 
-DocumentExceptions: androidx.ui.core.vectorgraphics.BrushKt#obtainBrush(Object):
-    Method BrushKt.obtainBrush appears to be throwing java.lang.IllegalArgumentException; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
+MissingNullability: androidx.ui.core.LayoutResult#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.core.LayoutResult`
+MissingNullability: androidx.ui.semantics.SemanticsActions#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.semantics.SemanticsActions`
+MissingNullability: androidx.ui.semantics.SemanticsProperties#INSTANCE:
+    Missing nullability on field `INSTANCE` in class `class androidx.ui.semantics.SemanticsProperties`
diff --git a/ui/ui-framework/api/current.txt b/ui/ui-framework/api/current.txt
index 56e2390..2f60003 100644
--- a/ui/ui-framework/api/current.txt
+++ b/ui/ui-framework/api/current.txt
@@ -6,12 +6,23 @@
     method public static void Clip(androidx.ui.engine.geometry.Shape shape, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
+  public final class ComplexLayoutBlockReceiver implements androidx.ui.core.DensityReceiver {
+    method public androidx.ui.core.Density getDensity();
+    method public androidx.ui.core.LayoutResult layout(androidx.ui.core.IntPx width, androidx.ui.core.IntPx height, kotlin.jvm.functions.Function1<? super androidx.ui.core.PositioningBlockReceiver,kotlin.Unit> positioningBlock);
+    method public androidx.ui.core.IntPx maxIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
+    method public androidx.ui.core.IntPx maxIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
+    method public androidx.ui.core.Placeable measure(androidx.ui.core.Measurable, androidx.ui.core.Constraints constraints);
+    method public androidx.ui.core.IntPx minIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
+    method public androidx.ui.core.IntPx minIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
+    property public androidx.ui.core.Density density;
+  }
+
   public final class ComplexLayoutReceiver {
-    method public void layout(kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutBlockReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,kotlin.Unit> layoutBlock);
-    method public void maxIntrinsicHeight(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementsReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> maxIntrinsicHeightBlock);
-    method public void maxIntrinsicWidth(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementsReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> maxIntrinsicWidthBlock);
-    method public void minIntrinsicHeight(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementsReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> minIntrinsicHeightBlock);
-    method public void minIntrinsicWidth(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementsReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> minIntrinsicWidthBlock);
+    method public void maxIntrinsicHeight(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> maxIntrinsicHeightBlock);
+    method public void maxIntrinsicWidth(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> maxIntrinsicWidthBlock);
+    method public void measure(kotlin.jvm.functions.Function3<? super androidx.ui.core.ComplexLayoutBlockReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,androidx.ui.core.LayoutResult> layoutBlock);
+    method public void minIntrinsicHeight(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> minIntrinsicHeightBlock);
+    method public void minIntrinsicWidth(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> minIntrinsicWidthBlock);
   }
 
   public final class DrawKt {
@@ -20,19 +31,12 @@
     method public static void Draw(kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function3<? super androidx.ui.core.DrawReceiver,? super androidx.ui.painting.Canvas,? super androidx.ui.core.PxSize,kotlin.Unit> onPaint);
   }
 
-  public final class EditorStyle {
-    ctor public EditorStyle(androidx.ui.text.TextStyle? textStyle, androidx.ui.graphics.Color compositionColor, androidx.ui.graphics.Color selectionColor);
-    ctor public EditorStyle();
-    method public androidx.ui.text.TextStyle? component1();
-    method public androidx.ui.graphics.Color component2();
-    method public androidx.ui.graphics.Color component3();
-    method public androidx.ui.core.EditorStyle copy(androidx.ui.text.TextStyle? textStyle, androidx.ui.graphics.Color compositionColor, androidx.ui.graphics.Color selectionColor);
-    method public androidx.ui.graphics.Color getCompositionColor();
-    method public androidx.ui.graphics.Color getSelectionColor();
-    method public androidx.ui.text.TextStyle? getTextStyle();
+  public final class DrawShadowKt {
+    ctor public DrawShadowKt();
+    method public static void DrawShadow(androidx.ui.engine.geometry.Shape shape, androidx.ui.core.Dp elevation);
   }
 
-  public final class IntrinsicMeasurementsReceiver implements androidx.ui.core.DensityReceiver {
+  public final class IntrinsicMeasurementReceiver implements androidx.ui.core.DensityReceiver {
     method public androidx.ui.core.Density getDensity();
     method public androidx.ui.core.IntPx maxIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
     method public androidx.ui.core.IntPx maxIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
@@ -42,13 +46,10 @@
   }
 
   public final class LayoutBlockReceiver implements androidx.ui.core.DensityReceiver {
+    method public operator java.util.List<androidx.ui.core.Measurable> get(java.util.List<? extends androidx.ui.core.Measurable>, kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public androidx.ui.core.Density getDensity();
-    method public void layoutResult(androidx.ui.core.IntPx width, androidx.ui.core.IntPx height, kotlin.jvm.functions.Function1<? super androidx.ui.core.PositioningBlockReceiver,kotlin.Unit> block);
-    method public androidx.ui.core.IntPx maxIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
-    method public androidx.ui.core.IntPx maxIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
+    method public androidx.ui.core.LayoutResult layout(androidx.ui.core.IntPx width, androidx.ui.core.IntPx height, kotlin.jvm.functions.Function1<? super androidx.ui.core.PositioningBlockReceiver,kotlin.Unit> positioningBlock);
     method public androidx.ui.core.Placeable measure(androidx.ui.core.Measurable, androidx.ui.core.Constraints constraints);
-    method public androidx.ui.core.IntPx minIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
-    method public androidx.ui.core.IntPx minIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
     property public androidx.ui.core.Density density;
   }
 
@@ -67,19 +68,18 @@
   public final class LayoutKt {
     ctor public LayoutKt();
     method public static void ComplexLayout(kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function1<? super androidx.ui.core.ComplexLayoutReceiver,kotlin.Unit> block);
-    method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,kotlin.Unit> layoutBlock);
-    method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit>![] childrenArray, kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,kotlin.Unit> layoutBlock);
+    method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutBlockReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,androidx.ui.core.LayoutResult> measureBlock);
+    method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit>![] childrenArray, kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutBlockReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,androidx.ui.core.LayoutResult> measureBlock);
     method public static void OnChildPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned, kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static void OnPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned);
     method public static void WithConstraints(kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
   }
 
-  public final class LayoutReceiver implements androidx.ui.core.DensityReceiver {
-    method public operator java.util.List<androidx.ui.core.Measurable> get(java.util.List<? extends androidx.ui.core.Measurable>, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public androidx.ui.core.Density getDensity();
-    method public void layout(androidx.ui.core.IntPx width, androidx.ui.core.IntPx height, kotlin.jvm.functions.Function1<? super androidx.ui.core.PositioningBlockReceiver,kotlin.Unit> block);
-    method public androidx.ui.core.Placeable measure(androidx.ui.core.Measurable, androidx.ui.core.Constraints constraints);
-    property public androidx.ui.core.Density density;
+  public final class LayoutResult {
+    field public static final androidx.ui.core.LayoutResult.Companion! Companion;
+  }
+
+  public static final class LayoutResult.Companion {
   }
 
   public interface Measurable {
@@ -87,11 +87,6 @@
     property public abstract Object? parentData;
   }
 
-  public interface OffsetMap {
-    method public int originalToTransformed(int offset);
-    method public int transformedToOriginal(int offset);
-  }
-
   public final class OpacityKt {
     ctor public OpacityKt();
     method public static void Opacity(@FloatRange(from=0.0, to=1.0) float opacity, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -102,13 +97,6 @@
     method public static void ParentData(Object data, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class PasswordVisualTransformation implements androidx.ui.core.VisualTransformation {
-    ctor public PasswordVisualTransformation(char mask);
-    ctor public PasswordVisualTransformation();
-    method public androidx.ui.core.TransformedText filter(androidx.ui.text.AnnotatedString text);
-    method public char getMask();
-  }
-
   public abstract class Placeable {
     ctor public Placeable();
     method public abstract androidx.ui.core.IntPx getHeight();
@@ -134,11 +122,6 @@
     method public static void RepaintBoundary(String? name = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class SemanticsKt {
-    ctor public SemanticsKt();
-    method public static void Semantics(boolean container = false, boolean explicitChildNodes = false, Boolean? enabled = null, Boolean? checked = null, Boolean? selected = null, Boolean? button = null, Boolean? inMutuallyExclusiveGroup = null, Boolean? hidden = null, String? label = null, String? value = null, androidx.ui.text.style.TextDirection? textDirection = null, String? testTag = null, java.util.List<? extends androidx.ui.core.semantics.SemanticsAction<?>> actions = emptyList(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
   public final class TestTagProviderKt {
     ctor public TestTagProviderKt();
     method public static void TestTag(String tag, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -146,9 +129,13 @@
     method public static androidx.compose.Ambient<java.lang.String> getTestTagAmbient();
   }
 
+  public final class TextFieldDelegateKt {
+    ctor public TextFieldDelegateKt();
+  }
+
   public final class TextFieldKt {
     ctor public TextFieldKt();
-    method public static void TextField(androidx.ui.input.EditorModel value, androidx.ui.core.EditorStyle editorStyle, androidx.ui.input.KeyboardType keyboardType = KeyboardType.Text, androidx.ui.input.ImeAction imeAction = ImeAction.Unspecified, kotlin.jvm.functions.Function1<? super androidx.ui.input.EditorModel,kotlin.Unit> onValueChange = {}, kotlin.jvm.functions.Function0<kotlin.Unit> onFocus = {}, kotlin.jvm.functions.Function0<kotlin.Unit> onBlur = {}, kotlin.jvm.functions.Function1<? super androidx.ui.input.ImeAction,kotlin.Unit> onImeActionPerformed = {}, androidx.ui.core.VisualTransformation? visualTransformation = null);
+    method public static void TextField(androidx.ui.input.EditorModel value, androidx.ui.input.EditorStyle editorStyle, androidx.ui.input.KeyboardType keyboardType = KeyboardType.Text, androidx.ui.input.ImeAction imeAction = ImeAction.Unspecified, kotlin.jvm.functions.Function1<? super androidx.ui.input.EditorModel,kotlin.Unit> onValueChange = {}, kotlin.jvm.functions.Function0<kotlin.Unit> onFocus = {}, kotlin.jvm.functions.Function0<kotlin.Unit> onBlur = {}, kotlin.jvm.functions.Function1<? super androidx.ui.input.ImeAction,kotlin.Unit> onImeActionPerformed = {}, androidx.ui.input.VisualTransformation? visualTransformation = null);
   }
 
   public final class TextKt {
@@ -186,31 +173,18 @@
     method public androidx.ui.core.TextSpanComposition getComposer();
   }
 
-  public final class TransformedText {
-    ctor public TransformedText(androidx.ui.text.AnnotatedString transformedText, androidx.ui.core.OffsetMap offsetMap);
-    method public androidx.ui.text.AnnotatedString component1();
-    method public androidx.ui.core.OffsetMap component2();
-    method public androidx.ui.core.TransformedText copy(androidx.ui.text.AnnotatedString transformedText, androidx.ui.core.OffsetMap offsetMap);
-    method public androidx.ui.core.OffsetMap getOffsetMap();
-    method public androidx.ui.text.AnnotatedString getTransformedText();
-  }
-
-  public interface VisualTransformation {
-    method public androidx.ui.core.TransformedText filter(androidx.ui.text.AnnotatedString text);
-  }
-
-  public final class VisualTransformationKt {
-    ctor public VisualTransformationKt();
-  }
-
   public final class WrapperKt {
     ctor public WrapperKt();
     method public static void ComposeView(kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static void WithDensity(kotlin.jvm.functions.Function1<? super androidx.ui.core.DensityReceiver,kotlin.Unit> block);
     method @CheckResult(suggest="+") public static androidx.compose.Effect<androidx.ui.core.Density> ambientDensity();
+    method public static androidx.compose.Ambient<androidx.ui.autofill.Autofill> getAutofillAmbient();
+    method public static androidx.compose.Ambient<androidx.ui.autofill.AutofillTree> getAutofillTreeAmbient();
+    method public static androidx.compose.Ambient<android.content.res.Configuration> getConfigurationAmbient();
     method public static androidx.compose.Ambient<android.content.Context> getContextAmbient();
     method public static androidx.compose.Ambient<kotlin.coroutines.CoroutineContext> getCoroutineContextAmbient();
     method public static androidx.compose.Ambient<androidx.ui.core.Density> getDensityAmbient();
+    method public static androidx.compose.Ambient<androidx.ui.core.LayoutDirection> getLayoutDirectionAmbient();
     method public static androidx.compose.CompositionContext? setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.CompositionContext? setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @CheckResult(suggest="+") public static <R> androidx.compose.Effect<R> withDensity(kotlin.jvm.functions.Function1<? super androidx.ui.core.DensityReceiver,? extends R> block);
@@ -246,11 +220,6 @@
     method public static void DoubleTapGestureDetector(kotlin.jvm.functions.Function1<? super androidx.ui.core.PxPosition,kotlin.Unit> onDoubleTap, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class DragGestureDetectorKt {
-    ctor public DragGestureDetectorKt();
-    method public static void DragGestureDetector(kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean>? canDrag = null, androidx.ui.core.gesture.DragObserver? dragObserver = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
   public interface DragObserver {
     method public default androidx.ui.core.PxPosition onDrag(androidx.ui.core.PxPosition dragDistance);
     method public default void onStart();
@@ -277,6 +246,21 @@
     method public static void PressReleasedGestureDetector(kotlin.jvm.functions.Function0<kotlin.Unit>? onRelease = null, boolean consumeDownOnStart = true, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
+  public final class RawDragGestureDetectorKt {
+    ctor public RawDragGestureDetectorKt();
+    method public static void RawDragGestureDetector(androidx.ui.core.gesture.DragObserver dragObserver, kotlin.jvm.functions.Function0<java.lang.Boolean>? canStartDragging = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+  }
+
+  public final class TouchSlopDragGestureDetectorKt {
+    ctor public TouchSlopDragGestureDetectorKt();
+    method public static void TouchSlopDragGestureDetector(androidx.ui.core.gesture.DragObserver dragObserver, kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean>? canDrag = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+  }
+
+  public final class TouchSlopExceededGestureDetectorKt {
+    ctor public TouchSlopExceededGestureDetectorKt();
+    method public static void TouchSlopExceededGestureDetector(kotlin.jvm.functions.Function0<kotlin.Unit> onTouchSlopExceeded, kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean>? canDrag = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+  }
+
 }
 
 package androidx.ui.core.gesture.util {
@@ -369,7 +353,8 @@
 
   public final class VectorComposeKt {
     ctor public VectorComposeKt();
-    method public static void DrawVector(float viewportWidth, float viewportHeight, androidx.ui.core.Px defaultWidth = Px(viewportWidth), androidx.ui.core.Px defaultHeight = Px(viewportHeight), String name = "", kotlin.jvm.functions.Function1<? super androidx.ui.vector.VectorScope,kotlin.Unit> children);
+    method public static void DrawVector(androidx.ui.core.Dp defaultWidth, androidx.ui.core.Dp defaultHeight, float viewportWidth = -1.0f, float viewportHeight = -1.0f, String name = "", kotlin.jvm.functions.Function3<? super androidx.ui.vector.VectorScope,? super java.lang.Float,? super java.lang.Float,kotlin.Unit> children);
+    method public static void DrawVector(androidx.ui.core.Px defaultWidth, androidx.ui.core.Px defaultHeight, float viewportWidth = defaultWidth.value, float viewportHeight = defaultHeight.value, String name = "", kotlin.jvm.functions.Function3<? super androidx.ui.vector.VectorScope,? super java.lang.Float,? super java.lang.Float,kotlin.Unit> children);
     method public static void Group(androidx.ui.vector.VectorScope, String name = "", float rotation = 0.0f, float pivotX = 0.0f, float pivotY = 0.0f, float scaleX = 1.0f, float scaleY = 1.0f, float translationX = 0.0f, float translationY = 0.0f, Object? clipPathData = EmptyPath, kotlin.jvm.functions.Function1<? super androidx.ui.vector.VectorScope,kotlin.Unit> children);
     method public static void Path(androidx.ui.vector.VectorScope, Object? pathData, String name = "", Object fill = EmptyBrush, float fillAlpha = 1.0f, Object stroke = EmptyBrush, float strokeAlpha = 1.0f, float strokeLineWidth = 0.0f, androidx.ui.painting.StrokeCap strokeLineCap = DefaultStrokeLineCap, androidx.ui.painting.StrokeJoin strokeLineJoin = DefaultStrokeLineJoin, float strokeLineMiter = 4.0f);
   }
@@ -415,8 +400,9 @@
 
   public final class VectorResourceKt {
     ctor public VectorResourceKt();
-    method public static void VectorResource(int resId);
+    method public static void DrawVectorResource(int resId);
     method public static androidx.ui.core.vectorgraphics.VectorAsset loadVectorResource(android.content.res.Resources.Theme? theme = null, android.content.res.Resources res, int resId) throws org.xmlpull.v1.XmlPullParserException;
+    method @CheckResult(suggest="+") public static androidx.compose.Effect<androidx.ui.core.vectorgraphics.VectorAsset> vectorResource(int resId);
   }
 
   public final class XmlVectorParserKt {
@@ -425,3 +411,61 @@
 
 }
 
+package androidx.ui.semantics {
+
+  public final class SemanticsActions {
+    ctor public SemanticsActions();
+    field public static final androidx.ui.semantics.SemanticsActions.Companion! Companion;
+  }
+
+  public static final class SemanticsActions.Companion {
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.util.List<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>>> getCustomActions();
+    method public androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>> getOnClick();
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.util.List<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>>> CustomActions;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>> OnClick;
+  }
+
+  public final class SemanticsKt {
+    ctor public SemanticsKt();
+    method public static void Semantics(boolean container = false, boolean explicitChildNodes = false, kotlin.jvm.functions.Function1<? super androidx.ui.semantics.SemanticsPropertyReceiver,kotlin.Unit>? properties = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+  }
+
+  public final class SemanticsProperties {
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> getAccessibilityLabel();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> getAccessibilityValue();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getEnabled();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getHidden();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> getTestTag();
+    method public androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.text.style.TextDirection> getTextDirection();
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> AccessibilityLabel;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> AccessibilityValue;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Enabled;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Hidden;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> TestTag;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.text.style.TextDirection> TextDirection;
+    field public static final androidx.ui.semantics.SemanticsProperties! INSTANCE;
+  }
+
+  public final class SemanticsPropertiesKt {
+    ctor public SemanticsPropertiesKt();
+    method public static String getAccessibilityLabel(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static String getAccessibilityValue(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static java.util.List<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>> getCustomActions(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static boolean getEnabled(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static boolean getHidden(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>> getOnClick(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static String getTestTag(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.ui.text.style.TextDirection getTextDirection(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static void onClick(androidx.ui.semantics.SemanticsPropertyReceiver, String? label = null, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+    method public static void setAccessibilityLabel(androidx.ui.semantics.SemanticsPropertyReceiver, String p);
+    method public static void setAccessibilityValue(androidx.ui.semantics.SemanticsPropertyReceiver, String p);
+    method public static void setCustomActions(androidx.ui.semantics.SemanticsPropertyReceiver, java.util.List<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>> p);
+    method public static void setEnabled(androidx.ui.semantics.SemanticsPropertyReceiver, boolean p);
+    method public static void setHidden(androidx.ui.semantics.SemanticsPropertyReceiver, boolean p);
+    method public static void setOnClick(androidx.ui.semantics.SemanticsPropertyReceiver, androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>> p);
+    method public static void setTestTag(androidx.ui.semantics.SemanticsPropertyReceiver, String p);
+    method public static void setTextDirection(androidx.ui.semantics.SemanticsPropertyReceiver, androidx.ui.text.style.TextDirection p);
+  }
+
+}
+
diff --git a/ui/ui-framework/api/restricted_1.0.0-alpha01.txt b/ui/ui-framework/api/restricted_1.0.0-alpha01.txt
index 56e2390..2f60003 100644
--- a/ui/ui-framework/api/restricted_1.0.0-alpha01.txt
+++ b/ui/ui-framework/api/restricted_1.0.0-alpha01.txt
@@ -6,12 +6,23 @@
     method public static void Clip(androidx.ui.engine.geometry.Shape shape, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
+  public final class ComplexLayoutBlockReceiver implements androidx.ui.core.DensityReceiver {
+    method public androidx.ui.core.Density getDensity();
+    method public androidx.ui.core.LayoutResult layout(androidx.ui.core.IntPx width, androidx.ui.core.IntPx height, kotlin.jvm.functions.Function1<? super androidx.ui.core.PositioningBlockReceiver,kotlin.Unit> positioningBlock);
+    method public androidx.ui.core.IntPx maxIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
+    method public androidx.ui.core.IntPx maxIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
+    method public androidx.ui.core.Placeable measure(androidx.ui.core.Measurable, androidx.ui.core.Constraints constraints);
+    method public androidx.ui.core.IntPx minIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
+    method public androidx.ui.core.IntPx minIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
+    property public androidx.ui.core.Density density;
+  }
+
   public final class ComplexLayoutReceiver {
-    method public void layout(kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutBlockReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,kotlin.Unit> layoutBlock);
-    method public void maxIntrinsicHeight(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementsReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> maxIntrinsicHeightBlock);
-    method public void maxIntrinsicWidth(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementsReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> maxIntrinsicWidthBlock);
-    method public void minIntrinsicHeight(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementsReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> minIntrinsicHeightBlock);
-    method public void minIntrinsicWidth(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementsReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> minIntrinsicWidthBlock);
+    method public void maxIntrinsicHeight(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> maxIntrinsicHeightBlock);
+    method public void maxIntrinsicWidth(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> maxIntrinsicWidthBlock);
+    method public void measure(kotlin.jvm.functions.Function3<? super androidx.ui.core.ComplexLayoutBlockReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,androidx.ui.core.LayoutResult> layoutBlock);
+    method public void minIntrinsicHeight(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> minIntrinsicHeightBlock);
+    method public void minIntrinsicWidth(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> minIntrinsicWidthBlock);
   }
 
   public final class DrawKt {
@@ -20,19 +31,12 @@
     method public static void Draw(kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function3<? super androidx.ui.core.DrawReceiver,? super androidx.ui.painting.Canvas,? super androidx.ui.core.PxSize,kotlin.Unit> onPaint);
   }
 
-  public final class EditorStyle {
-    ctor public EditorStyle(androidx.ui.text.TextStyle? textStyle, androidx.ui.graphics.Color compositionColor, androidx.ui.graphics.Color selectionColor);
-    ctor public EditorStyle();
-    method public androidx.ui.text.TextStyle? component1();
-    method public androidx.ui.graphics.Color component2();
-    method public androidx.ui.graphics.Color component3();
-    method public androidx.ui.core.EditorStyle copy(androidx.ui.text.TextStyle? textStyle, androidx.ui.graphics.Color compositionColor, androidx.ui.graphics.Color selectionColor);
-    method public androidx.ui.graphics.Color getCompositionColor();
-    method public androidx.ui.graphics.Color getSelectionColor();
-    method public androidx.ui.text.TextStyle? getTextStyle();
+  public final class DrawShadowKt {
+    ctor public DrawShadowKt();
+    method public static void DrawShadow(androidx.ui.engine.geometry.Shape shape, androidx.ui.core.Dp elevation);
   }
 
-  public final class IntrinsicMeasurementsReceiver implements androidx.ui.core.DensityReceiver {
+  public final class IntrinsicMeasurementReceiver implements androidx.ui.core.DensityReceiver {
     method public androidx.ui.core.Density getDensity();
     method public androidx.ui.core.IntPx maxIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
     method public androidx.ui.core.IntPx maxIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
@@ -42,13 +46,10 @@
   }
 
   public final class LayoutBlockReceiver implements androidx.ui.core.DensityReceiver {
+    method public operator java.util.List<androidx.ui.core.Measurable> get(java.util.List<? extends androidx.ui.core.Measurable>, kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public androidx.ui.core.Density getDensity();
-    method public void layoutResult(androidx.ui.core.IntPx width, androidx.ui.core.IntPx height, kotlin.jvm.functions.Function1<? super androidx.ui.core.PositioningBlockReceiver,kotlin.Unit> block);
-    method public androidx.ui.core.IntPx maxIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
-    method public androidx.ui.core.IntPx maxIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
+    method public androidx.ui.core.LayoutResult layout(androidx.ui.core.IntPx width, androidx.ui.core.IntPx height, kotlin.jvm.functions.Function1<? super androidx.ui.core.PositioningBlockReceiver,kotlin.Unit> positioningBlock);
     method public androidx.ui.core.Placeable measure(androidx.ui.core.Measurable, androidx.ui.core.Constraints constraints);
-    method public androidx.ui.core.IntPx minIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
-    method public androidx.ui.core.IntPx minIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
     property public androidx.ui.core.Density density;
   }
 
@@ -67,19 +68,18 @@
   public final class LayoutKt {
     ctor public LayoutKt();
     method public static void ComplexLayout(kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function1<? super androidx.ui.core.ComplexLayoutReceiver,kotlin.Unit> block);
-    method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,kotlin.Unit> layoutBlock);
-    method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit>![] childrenArray, kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,kotlin.Unit> layoutBlock);
+    method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutBlockReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,androidx.ui.core.LayoutResult> measureBlock);
+    method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit>![] childrenArray, kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutBlockReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,androidx.ui.core.LayoutResult> measureBlock);
     method public static void OnChildPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned, kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static void OnPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned);
     method public static void WithConstraints(kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
   }
 
-  public final class LayoutReceiver implements androidx.ui.core.DensityReceiver {
-    method public operator java.util.List<androidx.ui.core.Measurable> get(java.util.List<? extends androidx.ui.core.Measurable>, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public androidx.ui.core.Density getDensity();
-    method public void layout(androidx.ui.core.IntPx width, androidx.ui.core.IntPx height, kotlin.jvm.functions.Function1<? super androidx.ui.core.PositioningBlockReceiver,kotlin.Unit> block);
-    method public androidx.ui.core.Placeable measure(androidx.ui.core.Measurable, androidx.ui.core.Constraints constraints);
-    property public androidx.ui.core.Density density;
+  public final class LayoutResult {
+    field public static final androidx.ui.core.LayoutResult.Companion! Companion;
+  }
+
+  public static final class LayoutResult.Companion {
   }
 
   public interface Measurable {
@@ -87,11 +87,6 @@
     property public abstract Object? parentData;
   }
 
-  public interface OffsetMap {
-    method public int originalToTransformed(int offset);
-    method public int transformedToOriginal(int offset);
-  }
-
   public final class OpacityKt {
     ctor public OpacityKt();
     method public static void Opacity(@FloatRange(from=0.0, to=1.0) float opacity, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -102,13 +97,6 @@
     method public static void ParentData(Object data, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class PasswordVisualTransformation implements androidx.ui.core.VisualTransformation {
-    ctor public PasswordVisualTransformation(char mask);
-    ctor public PasswordVisualTransformation();
-    method public androidx.ui.core.TransformedText filter(androidx.ui.text.AnnotatedString text);
-    method public char getMask();
-  }
-
   public abstract class Placeable {
     ctor public Placeable();
     method public abstract androidx.ui.core.IntPx getHeight();
@@ -134,11 +122,6 @@
     method public static void RepaintBoundary(String? name = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class SemanticsKt {
-    ctor public SemanticsKt();
-    method public static void Semantics(boolean container = false, boolean explicitChildNodes = false, Boolean? enabled = null, Boolean? checked = null, Boolean? selected = null, Boolean? button = null, Boolean? inMutuallyExclusiveGroup = null, Boolean? hidden = null, String? label = null, String? value = null, androidx.ui.text.style.TextDirection? textDirection = null, String? testTag = null, java.util.List<? extends androidx.ui.core.semantics.SemanticsAction<?>> actions = emptyList(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
   public final class TestTagProviderKt {
     ctor public TestTagProviderKt();
     method public static void TestTag(String tag, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -146,9 +129,13 @@
     method public static androidx.compose.Ambient<java.lang.String> getTestTagAmbient();
   }
 
+  public final class TextFieldDelegateKt {
+    ctor public TextFieldDelegateKt();
+  }
+
   public final class TextFieldKt {
     ctor public TextFieldKt();
-    method public static void TextField(androidx.ui.input.EditorModel value, androidx.ui.core.EditorStyle editorStyle, androidx.ui.input.KeyboardType keyboardType = KeyboardType.Text, androidx.ui.input.ImeAction imeAction = ImeAction.Unspecified, kotlin.jvm.functions.Function1<? super androidx.ui.input.EditorModel,kotlin.Unit> onValueChange = {}, kotlin.jvm.functions.Function0<kotlin.Unit> onFocus = {}, kotlin.jvm.functions.Function0<kotlin.Unit> onBlur = {}, kotlin.jvm.functions.Function1<? super androidx.ui.input.ImeAction,kotlin.Unit> onImeActionPerformed = {}, androidx.ui.core.VisualTransformation? visualTransformation = null);
+    method public static void TextField(androidx.ui.input.EditorModel value, androidx.ui.input.EditorStyle editorStyle, androidx.ui.input.KeyboardType keyboardType = KeyboardType.Text, androidx.ui.input.ImeAction imeAction = ImeAction.Unspecified, kotlin.jvm.functions.Function1<? super androidx.ui.input.EditorModel,kotlin.Unit> onValueChange = {}, kotlin.jvm.functions.Function0<kotlin.Unit> onFocus = {}, kotlin.jvm.functions.Function0<kotlin.Unit> onBlur = {}, kotlin.jvm.functions.Function1<? super androidx.ui.input.ImeAction,kotlin.Unit> onImeActionPerformed = {}, androidx.ui.input.VisualTransformation? visualTransformation = null);
   }
 
   public final class TextKt {
@@ -186,31 +173,18 @@
     method public androidx.ui.core.TextSpanComposition getComposer();
   }
 
-  public final class TransformedText {
-    ctor public TransformedText(androidx.ui.text.AnnotatedString transformedText, androidx.ui.core.OffsetMap offsetMap);
-    method public androidx.ui.text.AnnotatedString component1();
-    method public androidx.ui.core.OffsetMap component2();
-    method public androidx.ui.core.TransformedText copy(androidx.ui.text.AnnotatedString transformedText, androidx.ui.core.OffsetMap offsetMap);
-    method public androidx.ui.core.OffsetMap getOffsetMap();
-    method public androidx.ui.text.AnnotatedString getTransformedText();
-  }
-
-  public interface VisualTransformation {
-    method public androidx.ui.core.TransformedText filter(androidx.ui.text.AnnotatedString text);
-  }
-
-  public final class VisualTransformationKt {
-    ctor public VisualTransformationKt();
-  }
-
   public final class WrapperKt {
     ctor public WrapperKt();
     method public static void ComposeView(kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static void WithDensity(kotlin.jvm.functions.Function1<? super androidx.ui.core.DensityReceiver,kotlin.Unit> block);
     method @CheckResult(suggest="+") public static androidx.compose.Effect<androidx.ui.core.Density> ambientDensity();
+    method public static androidx.compose.Ambient<androidx.ui.autofill.Autofill> getAutofillAmbient();
+    method public static androidx.compose.Ambient<androidx.ui.autofill.AutofillTree> getAutofillTreeAmbient();
+    method public static androidx.compose.Ambient<android.content.res.Configuration> getConfigurationAmbient();
     method public static androidx.compose.Ambient<android.content.Context> getContextAmbient();
     method public static androidx.compose.Ambient<kotlin.coroutines.CoroutineContext> getCoroutineContextAmbient();
     method public static androidx.compose.Ambient<androidx.ui.core.Density> getDensityAmbient();
+    method public static androidx.compose.Ambient<androidx.ui.core.LayoutDirection> getLayoutDirectionAmbient();
     method public static androidx.compose.CompositionContext? setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.CompositionContext? setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @CheckResult(suggest="+") public static <R> androidx.compose.Effect<R> withDensity(kotlin.jvm.functions.Function1<? super androidx.ui.core.DensityReceiver,? extends R> block);
@@ -246,11 +220,6 @@
     method public static void DoubleTapGestureDetector(kotlin.jvm.functions.Function1<? super androidx.ui.core.PxPosition,kotlin.Unit> onDoubleTap, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class DragGestureDetectorKt {
-    ctor public DragGestureDetectorKt();
-    method public static void DragGestureDetector(kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean>? canDrag = null, androidx.ui.core.gesture.DragObserver? dragObserver = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
   public interface DragObserver {
     method public default androidx.ui.core.PxPosition onDrag(androidx.ui.core.PxPosition dragDistance);
     method public default void onStart();
@@ -277,6 +246,21 @@
     method public static void PressReleasedGestureDetector(kotlin.jvm.functions.Function0<kotlin.Unit>? onRelease = null, boolean consumeDownOnStart = true, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
+  public final class RawDragGestureDetectorKt {
+    ctor public RawDragGestureDetectorKt();
+    method public static void RawDragGestureDetector(androidx.ui.core.gesture.DragObserver dragObserver, kotlin.jvm.functions.Function0<java.lang.Boolean>? canStartDragging = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+  }
+
+  public final class TouchSlopDragGestureDetectorKt {
+    ctor public TouchSlopDragGestureDetectorKt();
+    method public static void TouchSlopDragGestureDetector(androidx.ui.core.gesture.DragObserver dragObserver, kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean>? canDrag = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+  }
+
+  public final class TouchSlopExceededGestureDetectorKt {
+    ctor public TouchSlopExceededGestureDetectorKt();
+    method public static void TouchSlopExceededGestureDetector(kotlin.jvm.functions.Function0<kotlin.Unit> onTouchSlopExceeded, kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean>? canDrag = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+  }
+
 }
 
 package androidx.ui.core.gesture.util {
@@ -369,7 +353,8 @@
 
   public final class VectorComposeKt {
     ctor public VectorComposeKt();
-    method public static void DrawVector(float viewportWidth, float viewportHeight, androidx.ui.core.Px defaultWidth = Px(viewportWidth), androidx.ui.core.Px defaultHeight = Px(viewportHeight), String name = "", kotlin.jvm.functions.Function1<? super androidx.ui.vector.VectorScope,kotlin.Unit> children);
+    method public static void DrawVector(androidx.ui.core.Dp defaultWidth, androidx.ui.core.Dp defaultHeight, float viewportWidth = -1.0f, float viewportHeight = -1.0f, String name = "", kotlin.jvm.functions.Function3<? super androidx.ui.vector.VectorScope,? super java.lang.Float,? super java.lang.Float,kotlin.Unit> children);
+    method public static void DrawVector(androidx.ui.core.Px defaultWidth, androidx.ui.core.Px defaultHeight, float viewportWidth = defaultWidth.value, float viewportHeight = defaultHeight.value, String name = "", kotlin.jvm.functions.Function3<? super androidx.ui.vector.VectorScope,? super java.lang.Float,? super java.lang.Float,kotlin.Unit> children);
     method public static void Group(androidx.ui.vector.VectorScope, String name = "", float rotation = 0.0f, float pivotX = 0.0f, float pivotY = 0.0f, float scaleX = 1.0f, float scaleY = 1.0f, float translationX = 0.0f, float translationY = 0.0f, Object? clipPathData = EmptyPath, kotlin.jvm.functions.Function1<? super androidx.ui.vector.VectorScope,kotlin.Unit> children);
     method public static void Path(androidx.ui.vector.VectorScope, Object? pathData, String name = "", Object fill = EmptyBrush, float fillAlpha = 1.0f, Object stroke = EmptyBrush, float strokeAlpha = 1.0f, float strokeLineWidth = 0.0f, androidx.ui.painting.StrokeCap strokeLineCap = DefaultStrokeLineCap, androidx.ui.painting.StrokeJoin strokeLineJoin = DefaultStrokeLineJoin, float strokeLineMiter = 4.0f);
   }
@@ -415,8 +400,9 @@
 
   public final class VectorResourceKt {
     ctor public VectorResourceKt();
-    method public static void VectorResource(int resId);
+    method public static void DrawVectorResource(int resId);
     method public static androidx.ui.core.vectorgraphics.VectorAsset loadVectorResource(android.content.res.Resources.Theme? theme = null, android.content.res.Resources res, int resId) throws org.xmlpull.v1.XmlPullParserException;
+    method @CheckResult(suggest="+") public static androidx.compose.Effect<androidx.ui.core.vectorgraphics.VectorAsset> vectorResource(int resId);
   }
 
   public final class XmlVectorParserKt {
@@ -425,3 +411,61 @@
 
 }
 
+package androidx.ui.semantics {
+
+  public final class SemanticsActions {
+    ctor public SemanticsActions();
+    field public static final androidx.ui.semantics.SemanticsActions.Companion! Companion;
+  }
+
+  public static final class SemanticsActions.Companion {
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.util.List<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>>> getCustomActions();
+    method public androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>> getOnClick();
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.util.List<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>>> CustomActions;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>> OnClick;
+  }
+
+  public final class SemanticsKt {
+    ctor public SemanticsKt();
+    method public static void Semantics(boolean container = false, boolean explicitChildNodes = false, kotlin.jvm.functions.Function1<? super androidx.ui.semantics.SemanticsPropertyReceiver,kotlin.Unit>? properties = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+  }
+
+  public final class SemanticsProperties {
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> getAccessibilityLabel();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> getAccessibilityValue();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getEnabled();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getHidden();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> getTestTag();
+    method public androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.text.style.TextDirection> getTextDirection();
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> AccessibilityLabel;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> AccessibilityValue;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Enabled;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Hidden;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> TestTag;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.text.style.TextDirection> TextDirection;
+    field public static final androidx.ui.semantics.SemanticsProperties! INSTANCE;
+  }
+
+  public final class SemanticsPropertiesKt {
+    ctor public SemanticsPropertiesKt();
+    method public static String getAccessibilityLabel(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static String getAccessibilityValue(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static java.util.List<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>> getCustomActions(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static boolean getEnabled(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static boolean getHidden(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>> getOnClick(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static String getTestTag(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.ui.text.style.TextDirection getTextDirection(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static void onClick(androidx.ui.semantics.SemanticsPropertyReceiver, String? label = null, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+    method public static void setAccessibilityLabel(androidx.ui.semantics.SemanticsPropertyReceiver, String p);
+    method public static void setAccessibilityValue(androidx.ui.semantics.SemanticsPropertyReceiver, String p);
+    method public static void setCustomActions(androidx.ui.semantics.SemanticsPropertyReceiver, java.util.List<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>> p);
+    method public static void setEnabled(androidx.ui.semantics.SemanticsPropertyReceiver, boolean p);
+    method public static void setHidden(androidx.ui.semantics.SemanticsPropertyReceiver, boolean p);
+    method public static void setOnClick(androidx.ui.semantics.SemanticsPropertyReceiver, androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>> p);
+    method public static void setTestTag(androidx.ui.semantics.SemanticsPropertyReceiver, String p);
+    method public static void setTextDirection(androidx.ui.semantics.SemanticsPropertyReceiver, androidx.ui.text.style.TextDirection p);
+  }
+
+}
+
diff --git a/ui/ui-framework/api/restricted_current.txt b/ui/ui-framework/api/restricted_current.txt
index 56e2390..2f60003 100644
--- a/ui/ui-framework/api/restricted_current.txt
+++ b/ui/ui-framework/api/restricted_current.txt
@@ -6,12 +6,23 @@
     method public static void Clip(androidx.ui.engine.geometry.Shape shape, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
+  public final class ComplexLayoutBlockReceiver implements androidx.ui.core.DensityReceiver {
+    method public androidx.ui.core.Density getDensity();
+    method public androidx.ui.core.LayoutResult layout(androidx.ui.core.IntPx width, androidx.ui.core.IntPx height, kotlin.jvm.functions.Function1<? super androidx.ui.core.PositioningBlockReceiver,kotlin.Unit> positioningBlock);
+    method public androidx.ui.core.IntPx maxIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
+    method public androidx.ui.core.IntPx maxIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
+    method public androidx.ui.core.Placeable measure(androidx.ui.core.Measurable, androidx.ui.core.Constraints constraints);
+    method public androidx.ui.core.IntPx minIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
+    method public androidx.ui.core.IntPx minIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
+    property public androidx.ui.core.Density density;
+  }
+
   public final class ComplexLayoutReceiver {
-    method public void layout(kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutBlockReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,kotlin.Unit> layoutBlock);
-    method public void maxIntrinsicHeight(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementsReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> maxIntrinsicHeightBlock);
-    method public void maxIntrinsicWidth(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementsReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> maxIntrinsicWidthBlock);
-    method public void minIntrinsicHeight(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementsReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> minIntrinsicHeightBlock);
-    method public void minIntrinsicWidth(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementsReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> minIntrinsicWidthBlock);
+    method public void maxIntrinsicHeight(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> maxIntrinsicHeightBlock);
+    method public void maxIntrinsicWidth(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> maxIntrinsicWidthBlock);
+    method public void measure(kotlin.jvm.functions.Function3<? super androidx.ui.core.ComplexLayoutBlockReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,androidx.ui.core.LayoutResult> layoutBlock);
+    method public void minIntrinsicHeight(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> minIntrinsicHeightBlock);
+    method public void minIntrinsicWidth(kotlin.jvm.functions.Function3<? super androidx.ui.core.IntrinsicMeasurementReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.IntPx,androidx.ui.core.IntPx> minIntrinsicWidthBlock);
   }
 
   public final class DrawKt {
@@ -20,19 +31,12 @@
     method public static void Draw(kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function3<? super androidx.ui.core.DrawReceiver,? super androidx.ui.painting.Canvas,? super androidx.ui.core.PxSize,kotlin.Unit> onPaint);
   }
 
-  public final class EditorStyle {
-    ctor public EditorStyle(androidx.ui.text.TextStyle? textStyle, androidx.ui.graphics.Color compositionColor, androidx.ui.graphics.Color selectionColor);
-    ctor public EditorStyle();
-    method public androidx.ui.text.TextStyle? component1();
-    method public androidx.ui.graphics.Color component2();
-    method public androidx.ui.graphics.Color component3();
-    method public androidx.ui.core.EditorStyle copy(androidx.ui.text.TextStyle? textStyle, androidx.ui.graphics.Color compositionColor, androidx.ui.graphics.Color selectionColor);
-    method public androidx.ui.graphics.Color getCompositionColor();
-    method public androidx.ui.graphics.Color getSelectionColor();
-    method public androidx.ui.text.TextStyle? getTextStyle();
+  public final class DrawShadowKt {
+    ctor public DrawShadowKt();
+    method public static void DrawShadow(androidx.ui.engine.geometry.Shape shape, androidx.ui.core.Dp elevation);
   }
 
-  public final class IntrinsicMeasurementsReceiver implements androidx.ui.core.DensityReceiver {
+  public final class IntrinsicMeasurementReceiver implements androidx.ui.core.DensityReceiver {
     method public androidx.ui.core.Density getDensity();
     method public androidx.ui.core.IntPx maxIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
     method public androidx.ui.core.IntPx maxIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
@@ -42,13 +46,10 @@
   }
 
   public final class LayoutBlockReceiver implements androidx.ui.core.DensityReceiver {
+    method public operator java.util.List<androidx.ui.core.Measurable> get(java.util.List<? extends androidx.ui.core.Measurable>, kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public androidx.ui.core.Density getDensity();
-    method public void layoutResult(androidx.ui.core.IntPx width, androidx.ui.core.IntPx height, kotlin.jvm.functions.Function1<? super androidx.ui.core.PositioningBlockReceiver,kotlin.Unit> block);
-    method public androidx.ui.core.IntPx maxIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
-    method public androidx.ui.core.IntPx maxIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
+    method public androidx.ui.core.LayoutResult layout(androidx.ui.core.IntPx width, androidx.ui.core.IntPx height, kotlin.jvm.functions.Function1<? super androidx.ui.core.PositioningBlockReceiver,kotlin.Unit> positioningBlock);
     method public androidx.ui.core.Placeable measure(androidx.ui.core.Measurable, androidx.ui.core.Constraints constraints);
-    method public androidx.ui.core.IntPx minIntrinsicHeight(androidx.ui.core.Measurable, androidx.ui.core.IntPx w);
-    method public androidx.ui.core.IntPx minIntrinsicWidth(androidx.ui.core.Measurable, androidx.ui.core.IntPx h);
     property public androidx.ui.core.Density density;
   }
 
@@ -67,19 +68,18 @@
   public final class LayoutKt {
     ctor public LayoutKt();
     method public static void ComplexLayout(kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function1<? super androidx.ui.core.ComplexLayoutReceiver,kotlin.Unit> block);
-    method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,kotlin.Unit> layoutBlock);
-    method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit>![] childrenArray, kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,kotlin.Unit> layoutBlock);
+    method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutBlockReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,androidx.ui.core.LayoutResult> measureBlock);
+    method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit>![] childrenArray, kotlin.jvm.functions.Function3<? super androidx.ui.core.LayoutBlockReceiver,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,androidx.ui.core.LayoutResult> measureBlock);
     method public static void OnChildPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned, kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static void OnPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned);
     method public static void WithConstraints(kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
   }
 
-  public final class LayoutReceiver implements androidx.ui.core.DensityReceiver {
-    method public operator java.util.List<androidx.ui.core.Measurable> get(java.util.List<? extends androidx.ui.core.Measurable>, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public androidx.ui.core.Density getDensity();
-    method public void layout(androidx.ui.core.IntPx width, androidx.ui.core.IntPx height, kotlin.jvm.functions.Function1<? super androidx.ui.core.PositioningBlockReceiver,kotlin.Unit> block);
-    method public androidx.ui.core.Placeable measure(androidx.ui.core.Measurable, androidx.ui.core.Constraints constraints);
-    property public androidx.ui.core.Density density;
+  public final class LayoutResult {
+    field public static final androidx.ui.core.LayoutResult.Companion! Companion;
+  }
+
+  public static final class LayoutResult.Companion {
   }
 
   public interface Measurable {
@@ -87,11 +87,6 @@
     property public abstract Object? parentData;
   }
 
-  public interface OffsetMap {
-    method public int originalToTransformed(int offset);
-    method public int transformedToOriginal(int offset);
-  }
-
   public final class OpacityKt {
     ctor public OpacityKt();
     method public static void Opacity(@FloatRange(from=0.0, to=1.0) float opacity, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -102,13 +97,6 @@
     method public static void ParentData(Object data, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class PasswordVisualTransformation implements androidx.ui.core.VisualTransformation {
-    ctor public PasswordVisualTransformation(char mask);
-    ctor public PasswordVisualTransformation();
-    method public androidx.ui.core.TransformedText filter(androidx.ui.text.AnnotatedString text);
-    method public char getMask();
-  }
-
   public abstract class Placeable {
     ctor public Placeable();
     method public abstract androidx.ui.core.IntPx getHeight();
@@ -134,11 +122,6 @@
     method public static void RepaintBoundary(String? name = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class SemanticsKt {
-    ctor public SemanticsKt();
-    method public static void Semantics(boolean container = false, boolean explicitChildNodes = false, Boolean? enabled = null, Boolean? checked = null, Boolean? selected = null, Boolean? button = null, Boolean? inMutuallyExclusiveGroup = null, Boolean? hidden = null, String? label = null, String? value = null, androidx.ui.text.style.TextDirection? textDirection = null, String? testTag = null, java.util.List<? extends androidx.ui.core.semantics.SemanticsAction<?>> actions = emptyList(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
   public final class TestTagProviderKt {
     ctor public TestTagProviderKt();
     method public static void TestTag(String tag, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -146,9 +129,13 @@
     method public static androidx.compose.Ambient<java.lang.String> getTestTagAmbient();
   }
 
+  public final class TextFieldDelegateKt {
+    ctor public TextFieldDelegateKt();
+  }
+
   public final class TextFieldKt {
     ctor public TextFieldKt();
-    method public static void TextField(androidx.ui.input.EditorModel value, androidx.ui.core.EditorStyle editorStyle, androidx.ui.input.KeyboardType keyboardType = KeyboardType.Text, androidx.ui.input.ImeAction imeAction = ImeAction.Unspecified, kotlin.jvm.functions.Function1<? super androidx.ui.input.EditorModel,kotlin.Unit> onValueChange = {}, kotlin.jvm.functions.Function0<kotlin.Unit> onFocus = {}, kotlin.jvm.functions.Function0<kotlin.Unit> onBlur = {}, kotlin.jvm.functions.Function1<? super androidx.ui.input.ImeAction,kotlin.Unit> onImeActionPerformed = {}, androidx.ui.core.VisualTransformation? visualTransformation = null);
+    method public static void TextField(androidx.ui.input.EditorModel value, androidx.ui.input.EditorStyle editorStyle, androidx.ui.input.KeyboardType keyboardType = KeyboardType.Text, androidx.ui.input.ImeAction imeAction = ImeAction.Unspecified, kotlin.jvm.functions.Function1<? super androidx.ui.input.EditorModel,kotlin.Unit> onValueChange = {}, kotlin.jvm.functions.Function0<kotlin.Unit> onFocus = {}, kotlin.jvm.functions.Function0<kotlin.Unit> onBlur = {}, kotlin.jvm.functions.Function1<? super androidx.ui.input.ImeAction,kotlin.Unit> onImeActionPerformed = {}, androidx.ui.input.VisualTransformation? visualTransformation = null);
   }
 
   public final class TextKt {
@@ -186,31 +173,18 @@
     method public androidx.ui.core.TextSpanComposition getComposer();
   }
 
-  public final class TransformedText {
-    ctor public TransformedText(androidx.ui.text.AnnotatedString transformedText, androidx.ui.core.OffsetMap offsetMap);
-    method public androidx.ui.text.AnnotatedString component1();
-    method public androidx.ui.core.OffsetMap component2();
-    method public androidx.ui.core.TransformedText copy(androidx.ui.text.AnnotatedString transformedText, androidx.ui.core.OffsetMap offsetMap);
-    method public androidx.ui.core.OffsetMap getOffsetMap();
-    method public androidx.ui.text.AnnotatedString getTransformedText();
-  }
-
-  public interface VisualTransformation {
-    method public androidx.ui.core.TransformedText filter(androidx.ui.text.AnnotatedString text);
-  }
-
-  public final class VisualTransformationKt {
-    ctor public VisualTransformationKt();
-  }
-
   public final class WrapperKt {
     ctor public WrapperKt();
     method public static void ComposeView(kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static void WithDensity(kotlin.jvm.functions.Function1<? super androidx.ui.core.DensityReceiver,kotlin.Unit> block);
     method @CheckResult(suggest="+") public static androidx.compose.Effect<androidx.ui.core.Density> ambientDensity();
+    method public static androidx.compose.Ambient<androidx.ui.autofill.Autofill> getAutofillAmbient();
+    method public static androidx.compose.Ambient<androidx.ui.autofill.AutofillTree> getAutofillTreeAmbient();
+    method public static androidx.compose.Ambient<android.content.res.Configuration> getConfigurationAmbient();
     method public static androidx.compose.Ambient<android.content.Context> getContextAmbient();
     method public static androidx.compose.Ambient<kotlin.coroutines.CoroutineContext> getCoroutineContextAmbient();
     method public static androidx.compose.Ambient<androidx.ui.core.Density> getDensityAmbient();
+    method public static androidx.compose.Ambient<androidx.ui.core.LayoutDirection> getLayoutDirectionAmbient();
     method public static androidx.compose.CompositionContext? setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.CompositionContext? setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @CheckResult(suggest="+") public static <R> androidx.compose.Effect<R> withDensity(kotlin.jvm.functions.Function1<? super androidx.ui.core.DensityReceiver,? extends R> block);
@@ -246,11 +220,6 @@
     method public static void DoubleTapGestureDetector(kotlin.jvm.functions.Function1<? super androidx.ui.core.PxPosition,kotlin.Unit> onDoubleTap, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class DragGestureDetectorKt {
-    ctor public DragGestureDetectorKt();
-    method public static void DragGestureDetector(kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean>? canDrag = null, androidx.ui.core.gesture.DragObserver? dragObserver = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
   public interface DragObserver {
     method public default androidx.ui.core.PxPosition onDrag(androidx.ui.core.PxPosition dragDistance);
     method public default void onStart();
@@ -277,6 +246,21 @@
     method public static void PressReleasedGestureDetector(kotlin.jvm.functions.Function0<kotlin.Unit>? onRelease = null, boolean consumeDownOnStart = true, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
+  public final class RawDragGestureDetectorKt {
+    ctor public RawDragGestureDetectorKt();
+    method public static void RawDragGestureDetector(androidx.ui.core.gesture.DragObserver dragObserver, kotlin.jvm.functions.Function0<java.lang.Boolean>? canStartDragging = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+  }
+
+  public final class TouchSlopDragGestureDetectorKt {
+    ctor public TouchSlopDragGestureDetectorKt();
+    method public static void TouchSlopDragGestureDetector(androidx.ui.core.gesture.DragObserver dragObserver, kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean>? canDrag = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+  }
+
+  public final class TouchSlopExceededGestureDetectorKt {
+    ctor public TouchSlopExceededGestureDetectorKt();
+    method public static void TouchSlopExceededGestureDetector(kotlin.jvm.functions.Function0<kotlin.Unit> onTouchSlopExceeded, kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean>? canDrag = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+  }
+
 }
 
 package androidx.ui.core.gesture.util {
@@ -369,7 +353,8 @@
 
   public final class VectorComposeKt {
     ctor public VectorComposeKt();
-    method public static void DrawVector(float viewportWidth, float viewportHeight, androidx.ui.core.Px defaultWidth = Px(viewportWidth), androidx.ui.core.Px defaultHeight = Px(viewportHeight), String name = "", kotlin.jvm.functions.Function1<? super androidx.ui.vector.VectorScope,kotlin.Unit> children);
+    method public static void DrawVector(androidx.ui.core.Dp defaultWidth, androidx.ui.core.Dp defaultHeight, float viewportWidth = -1.0f, float viewportHeight = -1.0f, String name = "", kotlin.jvm.functions.Function3<? super androidx.ui.vector.VectorScope,? super java.lang.Float,? super java.lang.Float,kotlin.Unit> children);
+    method public static void DrawVector(androidx.ui.core.Px defaultWidth, androidx.ui.core.Px defaultHeight, float viewportWidth = defaultWidth.value, float viewportHeight = defaultHeight.value, String name = "", kotlin.jvm.functions.Function3<? super androidx.ui.vector.VectorScope,? super java.lang.Float,? super java.lang.Float,kotlin.Unit> children);
     method public static void Group(androidx.ui.vector.VectorScope, String name = "", float rotation = 0.0f, float pivotX = 0.0f, float pivotY = 0.0f, float scaleX = 1.0f, float scaleY = 1.0f, float translationX = 0.0f, float translationY = 0.0f, Object? clipPathData = EmptyPath, kotlin.jvm.functions.Function1<? super androidx.ui.vector.VectorScope,kotlin.Unit> children);
     method public static void Path(androidx.ui.vector.VectorScope, Object? pathData, String name = "", Object fill = EmptyBrush, float fillAlpha = 1.0f, Object stroke = EmptyBrush, float strokeAlpha = 1.0f, float strokeLineWidth = 0.0f, androidx.ui.painting.StrokeCap strokeLineCap = DefaultStrokeLineCap, androidx.ui.painting.StrokeJoin strokeLineJoin = DefaultStrokeLineJoin, float strokeLineMiter = 4.0f);
   }
@@ -415,8 +400,9 @@
 
   public final class VectorResourceKt {
     ctor public VectorResourceKt();
-    method public static void VectorResource(int resId);
+    method public static void DrawVectorResource(int resId);
     method public static androidx.ui.core.vectorgraphics.VectorAsset loadVectorResource(android.content.res.Resources.Theme? theme = null, android.content.res.Resources res, int resId) throws org.xmlpull.v1.XmlPullParserException;
+    method @CheckResult(suggest="+") public static androidx.compose.Effect<androidx.ui.core.vectorgraphics.VectorAsset> vectorResource(int resId);
   }
 
   public final class XmlVectorParserKt {
@@ -425,3 +411,61 @@
 
 }
 
+package androidx.ui.semantics {
+
+  public final class SemanticsActions {
+    ctor public SemanticsActions();
+    field public static final androidx.ui.semantics.SemanticsActions.Companion! Companion;
+  }
+
+  public static final class SemanticsActions.Companion {
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.util.List<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>>> getCustomActions();
+    method public androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>> getOnClick();
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.util.List<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>>> CustomActions;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>> OnClick;
+  }
+
+  public final class SemanticsKt {
+    ctor public SemanticsKt();
+    method public static void Semantics(boolean container = false, boolean explicitChildNodes = false, kotlin.jvm.functions.Function1<? super androidx.ui.semantics.SemanticsPropertyReceiver,kotlin.Unit>? properties = null, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+  }
+
+  public final class SemanticsProperties {
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> getAccessibilityLabel();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> getAccessibilityValue();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getEnabled();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getHidden();
+    method public androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> getTestTag();
+    method public androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.text.style.TextDirection> getTextDirection();
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> AccessibilityLabel;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> AccessibilityValue;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Enabled;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Hidden;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<java.lang.String> TestTag;
+    property public final androidx.ui.semantics.SemanticsPropertyKey<androidx.ui.text.style.TextDirection> TextDirection;
+    field public static final androidx.ui.semantics.SemanticsProperties! INSTANCE;
+  }
+
+  public final class SemanticsPropertiesKt {
+    ctor public SemanticsPropertiesKt();
+    method public static String getAccessibilityLabel(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static String getAccessibilityValue(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static java.util.List<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>> getCustomActions(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static boolean getEnabled(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static boolean getHidden(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>> getOnClick(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static String getTestTag(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.ui.text.style.TextDirection getTextDirection(androidx.ui.semantics.SemanticsPropertyReceiver);
+    method public static void onClick(androidx.ui.semantics.SemanticsPropertyReceiver, String? label = null, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+    method public static void setAccessibilityLabel(androidx.ui.semantics.SemanticsPropertyReceiver, String p);
+    method public static void setAccessibilityValue(androidx.ui.semantics.SemanticsPropertyReceiver, String p);
+    method public static void setCustomActions(androidx.ui.semantics.SemanticsPropertyReceiver, java.util.List<androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>>> p);
+    method public static void setEnabled(androidx.ui.semantics.SemanticsPropertyReceiver, boolean p);
+    method public static void setHidden(androidx.ui.semantics.SemanticsPropertyReceiver, boolean p);
+    method public static void setOnClick(androidx.ui.semantics.SemanticsPropertyReceiver, androidx.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<kotlin.Unit>> p);
+    method public static void setTestTag(androidx.ui.semantics.SemanticsPropertyReceiver, String p);
+    method public static void setTextDirection(androidx.ui.semantics.SemanticsPropertyReceiver, androidx.ui.text.style.TextDirection p);
+  }
+
+}
+
diff --git a/ui/ui-framework/build.gradle b/ui/ui-framework/build.gradle
index 5d162f6..c0a57c1 100644
--- a/ui/ui-framework/build.gradle
+++ b/ui/ui-framework/build.gradle
@@ -37,9 +37,9 @@
     implementation "androidx.core:core:1.0.2"
 
     implementation project(":compose:compose-runtime")
-    implementation project(":ui:ui-core")
+    api project(":ui:ui-core")
     implementation project(":ui:ui-platform")
-    implementation project(":ui:ui-text")
+    api project(":ui:ui-text")
     implementation project(":ui:ui-vector")
 
     testImplementation(ANDROIDX_TEST_RULES)
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/AndroidManifest.xml b/ui/ui-framework/integration-tests/framework-demos/src/main/AndroidManifest.xml
index 77971ae..0ac212b 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/AndroidManifest.xml
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/AndroidManifest.xml
@@ -15,55 +15,105 @@
   -->
 
 <manifest
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        package="androidx.ui.framework.demos">
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    package="androidx.ui.framework.demos">
 
     <application>
         <activity android:name=".AnimationGestureSemanticsActivity"
-            android:configChanges="orientation|screenSize"
-            android:label="Semantics/Animations Gestures and Semantics">
+                  android:configChanges="orientation|screenSize"
+                  android:label="Semantics/Animations Gestures and Semantics">
             <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="androidx.ui.demos.SAMPLE_CODE" />
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="androidx.ui.demos.SAMPLE_CODE"/>
+            </intent-filter>
+        </activity>
+        <activity android:name=".autofill.ExplicitAutofillTypesActivity"
+                  android:configChanges="orientation|screenSize"
+                  android:label="Semantics/Autofill/Explicit Autofill Types">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="androidx.ui.demos.SAMPLE_CODE"/>
             </intent-filter>
         </activity>
         <activity android:name=".VectorGraphicsActivity"
                   android:configChanges="orientation|screenSize"
                   android:label="Graphics/Vector graphics">
             <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="androidx.ui.demos.SAMPLE_CODE" />
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="androidx.ui.demos.SAMPLE_CODE"/>
             </intent-filter>
         </activity>
 
-        <!-- Gestures -->
-        <activity android:name=".gestures.DragGestureDetectorDemo"
-            android:configChanges="orientation|screenSize"
-            android:label="Gestures/Single GestureDetectors/DragGestureDetector">
+        <!-- Simple Non-Movement Based GestureDetector Demos -->
+        <activity android:name=".gestures.PressReleasedGestureDetectorDemo"
+                  android:configChanges="orientation|screenSize"
+                  android:label="Gestures/Simple - Non-Movement/PressReleasedGestureDetectorDemo">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="androidx.ui.demos.SAMPLE_CODE" />
             </intent-filter>
         </activity>
         <activity android:name=".gestures.LongPressGestureDetectorDemo"
-            android:configChanges="orientation|screenSize"
-            android:label="Gestures/Single GestureDetectors/LongPressGestureDetectorDemo">
+                  android:configChanges="orientation|screenSize"
+                  android:label="Gestures/Simple - Non-Movement/LongPressGestureDetectorDemo">
             <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="androidx.ui.demos.SAMPLE_CODE" />
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="androidx.ui.demos.SAMPLE_CODE"/>
             </intent-filter>
         </activity>
         <activity android:name=".gestures.DoubleTapGestureDetectorDemo"
                   android:configChanges="orientation|screenSize"
-                  android:label="Gestures/Single GestureDetectors/DoubleTapGestureDetectorDemo">
+                  android:label="Gestures/Simple - Non-Movement/DoubleTapGestureDetectorDemo">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="androidx.ui.demos.SAMPLE_CODE" />
             </intent-filter>
         </activity>
+        <activity android:name=".gestures.PressIndicatorGestureDetectorDemo"
+                  android:configChanges="orientation|screenSize"
+                  android:label="Gestures/Simple - Non-Movement/PressIndicatorGestureDetectorDemo">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="androidx.ui.demos.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+        <!-- Simple Movement Based GestureDetector Demos -->
+        <activity android:name=".gestures.TouchSlopDragGestureDetectorDemo"
+                  android:configChanges="orientation|screenSize"
+                  android:label="Gestures/Simple - Movement/TouchSlopDragGestureDetector">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="androidx.ui.demos.SAMPLE_CODE"/>
+            </intent-filter>
+        </activity>
+        <activity android:name=".gestures.RawDragGestureDetectorDemo"
+                  android:configChanges="orientation|screenSize"
+                  android:label="Gestures/Simple - Movement/RawDragGestureDetector">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="androidx.ui.demos.SAMPLE_CODE"/>
+            </intent-filter>
+        </activity>
+        <activity android:name=".gestures.TouchSlopExceededGestureDetectorDemo"
+                  android:configChanges="orientation|screenSize"
+                  android:label="Gestures/Simple - Movement/TouchSlopExceededGestureFilter">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="androidx.ui.demos.SAMPLE_CODE"/>
+            </intent-filter>
+        </activity>
+        <!-- Complex GestureDetector Demos -->
         <activity android:name=".gestures.NestedScrollingDemo"
-            android:configChanges="orientation|screenSize"
-            android:label="Gestures/Complex Demos/Nested Scrolling">
+                  android:configChanges="orientation|screenSize"
+                  android:label="Gestures/Complex/Nested Scrolling">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="androidx.ui.demos.SAMPLE_CODE"/>
+            </intent-filter>
+        </activity>
+        <activity android:name=".gestures.NestedPressDemo"
+                  android:configChanges="orientation|screenSize"
+                  android:label="Gestures/Complex/Nested Pressing">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="androidx.ui.demos.SAMPLE_CODE" />
@@ -71,11 +121,11 @@
         </activity>
 
         <activity android:name=".MultipleCollectActivity"
-            android:configChanges="orientation|screenSize"
-            android:label="Layout/Multiple collects measure">
+                  android:configChanges="orientation|screenSize"
+                  android:label="Layout/Multiple collects measure">
             <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="androidx.ui.demos.SAMPLE_CODE" />
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="androidx.ui.demos.SAMPLE_CODE"/>
             </intent-filter>
         </activity>
     </application>
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/AnimationGestureSemanticsActivity.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/AnimationGestureSemanticsActivity.kt
index 9646e80..5fde1f2 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/AnimationGestureSemanticsActivity.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/AnimationGestureSemanticsActivity.kt
@@ -205,7 +205,7 @@
             ) { state ->
                 Circle(color = state[colorKey], sizeRatio = state[sizeKey])
             }
-        }, layoutBlock = { _, constraints ->
+        }, measureBlock = { _, constraints ->
             layout(constraints.maxWidth, constraints.maxHeight) {}
         })
     }
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/MultipleCollect.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/MultipleCollect.kt
index 2d01e25..f1b1249 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/MultipleCollect.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/MultipleCollect.kt
@@ -27,22 +27,21 @@
 import androidx.ui.core.toRect
 import androidx.ui.graphics.Color
 import androidx.ui.painting.Paint
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
-import androidx.ui.graphics.vectorgraphics.Brush
-import androidx.ui.graphics.vectorgraphics.SolidColor
+import androidx.ui.graphics.Brush
+import androidx.ui.graphics.SolidColor
 
 @Composable
 fun ColoredRect(brush: Brush, width: Dp? = null, height: Dp? = null) {
-    Layout(children = { DrawFillRect(brush = brush) }, layoutBlock = { _, constraints ->
+    Layout(children = { DrawFillRect(brush = brush) }) { _, constraints ->
         layout(
             width?.toIntPx()?.coerceIn(constraints.minWidth, constraints.maxWidth)
                 ?: constraints.maxWidth,
             height?.toIntPx()?.coerceIn(constraints.minHeight, constraints.maxHeight)
                 ?: constraints.maxHeight
         ) {}
-    })
+    }
 }
 
 @Composable
@@ -66,33 +65,31 @@
     content: @Composable() () -> Unit
 ) {
     @Suppress("USELESS_CAST")
-    Layout(
-        childrenArray = arrayOf(header, content, footer),
-        layoutBlock = { measurables, constraints ->
-            val headerPlaceable = measurables[header].first().measure(
-                Constraints.tightConstraints(constraints.maxWidth, 100.ipx)
-            )
-            val footerPadding = 50.ipx
-            val footerPlaceable = measurables[footer].first().measure(
-                Constraints.tightConstraints(constraints.maxWidth - footerPadding * 2, 100.ipx)
-            )
-            val itemHeight =
-                (constraints.maxHeight - headerPlaceable.height - footerPlaceable.height) /
-                        measurables[content].size
-            val contentPlaceables = measurables[content].map { measurable ->
-                measurable.measure(Constraints.tightConstraints(constraints.maxWidth, itemHeight))
-            }
+    Layout(header, content, footer) { measurables, constraints ->
+        val headerPlaceable = measurables[header].first().measure(
+            Constraints.tightConstraints(constraints.maxWidth, 100.ipx)
+        )
+        val footerPadding = 50.ipx
+        val footerPlaceable = measurables[footer].first().measure(
+            Constraints.tightConstraints(constraints.maxWidth - footerPadding * 2, 100.ipx)
+        )
+        val itemHeight =
+            (constraints.maxHeight - headerPlaceable.height - footerPlaceable.height) /
+                    measurables[content].size
+        val contentPlaceables = measurables[content].map { measurable ->
+            measurable.measure(Constraints.tightConstraints(constraints.maxWidth, itemHeight))
+        }
 
-            layout(constraints.maxWidth, constraints.maxHeight) {
-                headerPlaceable.place(0.ipx, 0.ipx)
-                footerPlaceable.place(footerPadding, constraints.maxHeight - footerPlaceable.height)
-                var top = headerPlaceable.height
-                contentPlaceables.forEach { placeable ->
-                    placeable.place(0.ipx, top)
-                    top += itemHeight
-                }
+        layout(constraints.maxWidth, constraints.maxHeight) {
+            headerPlaceable.place(0.ipx, 0.ipx)
+            footerPlaceable.place(footerPadding, constraints.maxHeight - footerPlaceable.height)
+            var top = headerPlaceable.height
+            contentPlaceables.forEach { placeable ->
+                placeable.place(0.ipx, top)
+                top += itemHeight
             }
-        })
+        }
+    }
 }
 
 @Composable
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/VectorGraphicsActivity.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/VectorGraphicsActivity.kt
index 37f6735..e765850 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/VectorGraphicsActivity.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/VectorGraphicsActivity.kt
@@ -17,32 +17,30 @@
 package androidx.ui.framework.demos
 
 import android.app.Activity
-import android.graphics.Shader
 import android.os.Bundle
 import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
-import androidx.ui.core.IntPx
-import androidx.ui.core.Layout
+import androidx.compose.unaryPlus
+import androidx.ui.core.Dp
 import androidx.ui.core.Px
+import androidx.ui.core.WithDensity
 import androidx.ui.core.dp
-import androidx.ui.core.px
-import androidx.ui.core.round
-import androidx.ui.core.vectorgraphics.DrawVector
-import androidx.ui.core.vectorgraphics.Group
-import androidx.ui.core.vectorgraphics.Path
 import androidx.ui.graphics.Color
-import androidx.ui.graphics.vectorgraphics.HorizontalGradient
+import androidx.ui.graphics.HorizontalGradient
 import androidx.ui.graphics.vectorgraphics.PathBuilder
-import androidx.ui.graphics.vectorgraphics.PathDelegate
-import androidx.ui.graphics.vectorgraphics.RadialGradient
-import androidx.ui.graphics.vectorgraphics.VerticalGradient
+import androidx.ui.graphics.RadialGradient
+import androidx.ui.graphics.VerticalGradient
 import androidx.ui.layout.Center
 import androidx.ui.layout.Column
 import androidx.ui.layout.Container
 import androidx.ui.painting.TileMode
 import androidx.ui.core.setContent
-import androidx.ui.core.vectorgraphics.compat.VectorResource
+import androidx.ui.core.vectorgraphics.DrawVector
+import androidx.ui.core.vectorgraphics.Group
+import androidx.ui.core.vectorgraphics.Path
+import androidx.ui.core.vectorgraphics.compat.vectorResource
+import androidx.ui.vector.PathDelegate
 import androidx.ui.vector.VectorScope
 
 class VectorGraphicsActivity : Activity() {
@@ -52,15 +50,20 @@
 
         setContent {
             Column {
-                Container(width = 480.dp, height = 480.dp) {
-                    VectorResource(resId = R.drawable.ic_crane)
+                val vectorAsset = +vectorResource(R.drawable.ic_crane)
+                WithDensity {
+                    val width = vectorAsset.defaultWidth.toDp()
+                    val height = vectorAsset.defaultHeight.toDp()
+                    Container(width = width, height = height) {
+                        DrawVector(vectorAsset)
+                    }
                 }
 
                 Center {
-                    val width = 300.px
-                    val height = 300.px
-                    FixedLayout(width.round(), height.round()) {
-                        vectorShape(width, height)
+                    val width = 120.dp
+                    val height = 120.dp
+                    Container(width = width, height = height) {
+                        VectorShape(width, height)
                     }
                 }
             }
@@ -68,24 +71,12 @@
     }
 
     @Composable
-    fun FixedLayout(width: IntPx, height: IntPx, @Children child: @Composable() () -> Unit) {
-        Layout(children = { child() },
-            layoutBlock = { _, _ ->
-                layout(width, height) {}
-            })
-    }
-
-    @Composable
-    fun vectorShape(width: Px, height: Px) {
-        val viewportWidth = width.value
-        val viewportHeight = height.value
+    fun VectorShape(width: Dp, height: Dp) {
         DrawVector(
             name = "vectorShape",
             defaultWidth = width,
-            defaultHeight = height,
-            viewportWidth = viewportWidth,
-            viewportHeight = viewportHeight
-        ) {
+            defaultHeight = height
+        ) { viewportWidth, viewportHeight ->
             Group(
                 scaleX = 0.75f,
                 scaleY = 0.75f,
@@ -93,8 +84,8 @@
                 pivotX = (viewportWidth / 2),
                 pivotY = (viewportHeight / 2)
             ) {
-                backgroundPath(vectorWidth = viewportWidth, vectorHeight = viewportHeight)
-                stripePath(vectorWidth = viewportWidth, vectorHeight = viewportHeight)
+                BackgroundPath(viewportWidth, viewportHeight)
+                StripePath(viewportWidth, viewportHeight)
                 Group(
                     translationX = 50.0f,
                     translationY = 50.0f,
@@ -119,14 +110,14 @@
                         pathData = pathData
                     )
                 }
-                triangle()
-                triangleWithOffsets()
+                Triangle()
+                TriangleWithOffsets()
             }
         }
     }
 
     @Composable
-    fun VectorScope.backgroundPath(vectorWidth: Float, vectorHeight: Float) {
+    fun VectorScope.BackgroundPath(vectorWidth: Float, vectorHeight: Float) {
         val background = PathDelegate {
             horizontalLineTo(vectorWidth)
             verticalLineTo(vectorHeight)
@@ -147,7 +138,7 @@
     }
 
     @Composable
-    fun VectorScope.triangle() {
+    fun VectorScope.Triangle() {
         val length = 150.0f
         Path(
             fill = RadialGradient(
@@ -168,7 +159,7 @@
     }
 
     @Composable
-    fun VectorScope.triangleWithOffsets() {
+    fun VectorScope.TriangleWithOffsets() {
 
         val side1 = 150.0f
         val side2 = 150.0f
@@ -190,7 +181,7 @@
     }
 
     @Composable
-    fun VectorScope.stripePath(vectorWidth: Float, vectorHeight: Float) {
+    fun VectorScope.StripePath(vectorWidth: Float, vectorHeight: Float) {
         val stripeDelegate = PathDelegate {
             stripe(vectorWidth, vectorHeight, 10)
         }
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/autofill/ExplicitAutofillTypesActivity.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/autofill/ExplicitAutofillTypesActivity.kt
new file mode 100644
index 0000000..dca00a9
--- /dev/null
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/autofill/ExplicitAutofillTypesActivity.kt
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2019 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.ui.framework.demos.autofill
+
+import android.app.Activity
+import android.graphics.Rect
+import android.os.Bundle
+import androidx.compose.Children
+import androidx.compose.Composable
+import androidx.compose.ambient
+import androidx.compose.composer
+import androidx.compose.state
+import androidx.compose.unaryPlus
+import androidx.ui.autofill.AutofillNode
+import androidx.ui.autofill.AutofillType
+import androidx.ui.core.AutofillAmbient
+import androidx.ui.core.AutofillTreeAmbient
+import androidx.ui.core.TextField
+import androidx.ui.core.Text
+import androidx.ui.material.themeTextStyle
+import androidx.ui.core.LayoutCoordinates
+import androidx.ui.core.OnChildPositioned
+import androidx.ui.core.PxPosition
+import androidx.ui.core.dp
+import androidx.ui.core.setContent
+import androidx.ui.input.EditorModel
+import androidx.ui.input.EditorStyle
+import androidx.ui.input.ImeAction
+import androidx.ui.input.KeyboardType
+import androidx.ui.layout.Column
+import androidx.ui.layout.CrossAxisAlignment
+import androidx.ui.layout.HeightSpacer
+import androidx.ui.material.MaterialTheme
+
+class ExplicitAutofillTypesActivity : Activity() {
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContent {
+            MaterialTheme {
+                Column(crossAxisAlignment = CrossAxisAlignment.Start) {
+
+                    val nameState = +state { EditorModel(text = "Enter name here") }
+                    val emailState = +state { EditorModel(text = "Enter email here") }
+                    val autofill = +ambient(AutofillAmbient)
+                    val labelStyle = +themeTextStyle { subtitle1.copy() }
+                    val textStyle = +themeTextStyle { h6.copy() }
+
+                    Text("Name", style = labelStyle)
+                    Autofill(
+                        autofillTypes = listOf(AutofillType.Name),
+                        onFill = { nameState.value = EditorModel(it) }
+                    ) { autofillNode ->
+                        TextField(
+                            value = nameState.value,
+                            keyboardType = KeyboardType.Text,
+                            imeAction = ImeAction.Unspecified,
+                            onValueChange = { nameState.value = it },
+                            onFocus = { autofill?.requestAutofillForNode(autofillNode) },
+                            onBlur = { autofill?.cancelAutofillForNode(autofillNode) },
+                            editorStyle = EditorStyle(textStyle = textStyle)
+                        )
+                    }
+
+                    HeightSpacer(40.dp)
+
+                    Text("Email", style = labelStyle)
+                    Autofill(
+                        autofillTypes = listOf(AutofillType.EmailAddress),
+                        onFill = { emailState.value = EditorModel(it) }
+                    ) { autofillNode ->
+                        TextField(
+                            value = emailState.value,
+                            keyboardType = KeyboardType.Text,
+                            imeAction = ImeAction.Unspecified,
+                            onValueChange = { emailState.value = it },
+                            onFocus = { autofill?.requestAutofillForNode(autofillNode) },
+                            onBlur = { autofill?.cancelAutofillForNode(autofillNode) },
+                            editorStyle = EditorStyle(textStyle = textStyle)
+                        )
+                    }
+                }
+            }
+        }
+    }
+}
+
+@Composable
+fun Autofill(
+    autofillTypes: List<AutofillType>,
+    onFill: ((String) -> Unit),
+    @Children children: @Composable() (AutofillNode) -> Unit
+) {
+    val autofillNode = AutofillNode(onFill = onFill, autofillTypes = autofillTypes)
+
+    val autofillTree = +ambient(AutofillTreeAmbient)
+    autofillTree += autofillNode
+
+    OnChildPositioned(onPositioned = { autofillNode.boundingBox = it.boundingBox() }) {
+        children(autofillNode)
+    }
+}
+
+private fun LayoutCoordinates.boundingBox() = localToGlobal(PxPosition.Origin).run {
+    Rect(
+        x.value.toInt(),
+        y.value.toInt(),
+        x.value.toInt() + size.width.value.toInt(),
+        y.value.toInt() + size.height.value.toInt()
+    )
+}
\ No newline at end of file
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/Colors.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/Colors.kt
index eaea537..6b46490 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/Colors.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/Colors.kt
@@ -19,6 +19,10 @@
 import androidx.ui.graphics.Color
 import kotlin.random.Random
 
+val DefaultBackgroundColor = Color(0xffffffff.toInt())
+val PressedColor = Color(0x1f000000)
+val BorderColor = Color(0x1f000000)
+
 val Red = Color(0xFFf44336.toInt())
 val Pink = Color(0xFFe91e63.toInt())
 val Purple = Color(0xFF9c27b0.toInt())
@@ -101,4 +105,20 @@
         }
 
     return this[next]
+}
+
+fun Color.over(that: Color): Color {
+
+    val a = this.getComponents()
+    val b = that.getComponents()
+
+    val result = FloatArray(4)
+
+    for (i in 0..2) {
+        result[i] = (a[i] * a[3] + (b[i] * b[3]) * (1 - a[3])) / (a[3] + b[3] * (1 - a[3]))
+    }
+
+    result[3] = a[3] + b[3] * (1 - a[3])
+
+    return Color(result[0], result[1], result[2], result[3])
 }
\ No newline at end of file
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/DoubleTapGestureDetectorDemo.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/DoubleTapGestureDetectorDemo.kt
index 7a972c5..a2d340a 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/DoubleTapGestureDetectorDemo.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/DoubleTapGestureDetectorDemo.kt
@@ -28,7 +28,7 @@
 import androidx.ui.core.gesture.DoubleTapGestureDetector
 
 /**
- * Simple demo that shows off DragGestureDetector.
+ * Simple DoubleTapGestureDetector demo.
  */
 class DoubleTapGestureDetectorDemo : Activity() {
     override fun onCreate(savedInstanceState: Bundle?) {
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/DragGestureDetectorDemo.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/DragGestureDetectorDemo.kt
deleted file mode 100644
index f7dabe6..0000000
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/DragGestureDetectorDemo.kt
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2019 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.ui.framework.demos.gestures
-
-import android.app.Activity
-import android.os.Bundle
-import androidx.compose.state
-import androidx.compose.unaryPlus
-import androidx.ui.core.PxPosition
-import androidx.ui.core.gesture.DragObserver
-import androidx.ui.core.px
-import androidx.ui.core.setContent
-import androidx.ui.graphics.Color
-import androidx.compose.composer
-import androidx.ui.core.dp
-import androidx.ui.core.gesture.DragGestureDetector
-
-/**
- * Simple demo that shows off DragGestureDetector.
- */
-class DragGestureDetectorDemo : Activity() {
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-        setContent {
-            val xOffset = +state { 0.px }
-            val yOffset = +state { 0.px }
-
-            val dragObserver = object : DragObserver {
-                override fun onDrag(dragDistance: PxPosition): PxPosition {
-                    xOffset.value += dragDistance.x
-                    yOffset.value += dragDistance.y
-                    return dragDistance
-                }
-            }
-
-            DragGestureDetector(dragObserver = dragObserver) {
-                MatchParent {
-                    DrawBox(
-                        xOffset.value,
-                        yOffset.value,
-                        96.dp,
-                        96.dp,
-                        Color(0xFF9e9e9e.toInt())
-                    )
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/LongPressGestureDetectorDemo.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/LongPressGestureDetectorDemo.kt
index 0cd4f12..4737d71 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/LongPressGestureDetectorDemo.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/LongPressGestureDetectorDemo.kt
@@ -28,7 +28,7 @@
 import androidx.ui.core.gesture.LongPressGestureDetector
 
 /**
- * Simple demo that shows off DragGestureDetector.
+ * Simple LongPressGestureDetector demo.
  */
 class LongPressGestureDetectorDemo : Activity() {
     override fun onCreate(savedInstanceState: Bundle?) {
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedPressDemo.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedPressDemo.kt
new file mode 100644
index 0000000..c5e852a
--- /dev/null
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedPressDemo.kt
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2019 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.ui.framework.demos.gestures
+
+import android.app.Activity
+import android.os.Bundle
+import androidx.compose.Children
+import androidx.compose.Composable
+import androidx.compose.state
+import androidx.compose.unaryPlus
+import androidx.ui.core.px
+import androidx.compose.composer
+import androidx.compose.memo
+import androidx.ui.core.Dp
+import androidx.ui.core.PxPosition
+import androidx.ui.core.dp
+import androidx.ui.core.gesture.DoubleTapGestureDetector
+import androidx.ui.core.gesture.LongPressGestureDetector
+import androidx.ui.core.gesture.PressIndicatorGestureDetector
+import androidx.ui.core.gesture.PressReleasedGestureDetector
+import androidx.ui.core.setContent
+
+/**
+ * Demonstration of how various press/tap gesture interact together in a nested fashion.
+ */
+class NestedPressDemo : Activity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContent {
+            PressableContainer(
+                paddingLeft = 48.dp,
+                paddingRight = 48.dp,
+                paddingTop = 96.dp,
+                paddingBottom = 96.dp
+            ) {
+                PressableContainer(
+                    paddingLeft = 48.dp,
+                    paddingRight = 48.dp,
+                    paddingTop = 96.dp,
+                    paddingBottom = 96.dp
+                ) {
+                    PressableContainer {}
+                }
+            }
+        }
+    }
+}
+
+@Composable
+fun PressableContainer(
+    paddingLeft: Dp? = null,
+    paddingTop: Dp? = null,
+    paddingRight: Dp? = null,
+    paddingBottom: Dp? = null,
+    @Children children: (@Composable() () -> Unit)
+) {
+    val defaultColor = DefaultBackgroundColor
+    val pressedColor = PressedColor
+
+    val currentColor = +memo { Single(defaultColor) }
+    val pressed = +state { false }
+
+    val onStart: (Any) -> Unit = {
+        pressed.value = true
+    }
+
+    val onStop: () -> Unit = {
+        pressed.value = false
+    }
+
+    val onLongPress = { _: PxPosition ->
+        pressed.value = false
+        currentColor.value = defaultColor
+    }
+
+    val onTap = {
+        currentColor.value = currentColor.value.next()
+    }
+
+    val onDoubleTap = { _: PxPosition ->
+        currentColor.value = currentColor.value.prev().prev()
+    }
+
+    val color = if (pressed.value) {
+        pressedColor.over(currentColor.value)
+    } else {
+        currentColor.value
+    }
+
+    PressIndicatorGestureDetector(
+        onStart = onStart,
+        onStop = onStop,
+        onCancel = onStop
+    ) {
+        PressReleasedGestureDetector(onTap, false) {
+            DoubleTapGestureDetector(onDoubleTap) {
+                LongPressGestureDetector(onLongPress) {
+                    Border(BorderColor, 2.dp) {
+                        DrawBox(
+                            0.px,
+                            0.px,
+                            (-1).dp,
+                            (-1).dp,
+                            color
+                        )
+                        Padding(paddingLeft, paddingTop, paddingRight, paddingBottom) {
+                            children()
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+data class Single<T>(var value: T)
\ No newline at end of file
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedScrollingDemo.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedScrollingDemo.kt
index ffadb06..93e3407 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedScrollingDemo.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedScrollingDemo.kt
@@ -18,7 +18,6 @@
 
 import android.app.Activity
 import android.os.Bundle
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.state
 import androidx.compose.unaryPlus
@@ -28,7 +27,7 @@
 import androidx.ui.core.Layout
 import androidx.ui.core.PxPosition
 import androidx.ui.core.coerceIn
-import androidx.ui.core.gesture.DragGestureDetector
+import androidx.ui.core.gesture.TouchSlopDragGestureDetector
 import androidx.ui.core.gesture.DragObserver
 import androidx.ui.core.gesture.PressIndicatorGestureDetector
 import androidx.ui.core.ipx
@@ -47,7 +46,7 @@
 import androidx.ui.core.toRect
 
 /**
- * Demo app created to study some complex interactions of multiple DragGestureDetectors.
+ * Demonstration for how multiple DragGestureDetectors interact.
  */
 class NestedScrollingDemo : Activity() {
     override fun onCreate(savedInstanceState: Bundle?) {
@@ -109,7 +108,7 @@
         }
     }
 
-    DragGestureDetector(canDrag, dragObserver) {
+    TouchSlopDragGestureDetector(dragObserver, canDrag) {
         Layout(children = {
             Draw { canvas, parentSize ->
                 canvas.save()
@@ -119,7 +118,7 @@
             Draw { canvas, _ ->
                 canvas.restore()
             }
-        }, layoutBlock = { measurables, constraints ->
+        }, measureBlock = { measurables, constraints ->
             val placeable =
                 measurables.first()
                     .measure(constraints.copy(minHeight = 0.ipx, maxHeight = IntPx.Infinity))
@@ -141,8 +140,8 @@
     height: Dp
 ) {
 
-    val pressedColor = Color(0x1f000000)
-    val defaultColor = Color(0xFFFFFFFF.toInt())
+    val pressedColor = PressedColor
+    val defaultColor = DefaultBackgroundColor
 
     val color = +state { defaultColor }
     val showPressed = +state { false }
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/PressIndicatorGestureDetectorDemo.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/PressIndicatorGestureDetectorDemo.kt
new file mode 100644
index 0000000..d8de0d1
--- /dev/null
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/PressIndicatorGestureDetectorDemo.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2019 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.ui.framework.demos.gestures
+
+import android.app.Activity
+import android.os.Bundle
+import androidx.compose.state
+import androidx.compose.unaryPlus
+import androidx.ui.core.px
+import androidx.ui.core.setContent
+import androidx.compose.composer
+import androidx.ui.core.PxPosition
+import androidx.ui.core.dp
+import androidx.ui.core.gesture.PressIndicatorGestureDetector
+
+/**
+ * Simple PressIndicatorGestureDetector demo.
+ */
+class PressIndicatorGestureDetectorDemo : Activity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContent {
+            val pressed = +state { false }
+
+            val onStart: (PxPosition) -> Unit = {
+                pressed.value = true
+            }
+
+            val onStop = {
+                pressed.value = false
+            }
+
+            val color =
+                if (pressed.value) {
+                    PressedColor.over(Grey)
+                } else {
+                    Grey
+                }
+
+            PressIndicatorGestureDetector(onStart = onStart, onStop = onStop, onCancel = onStop) {
+                MatchParent {
+                    DrawBox(
+                        0.px,
+                        0.px,
+                        96.dp,
+                        96.dp,
+                        color
+                    )
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/PressReleasedGestureDetectorDemo.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/PressReleasedGestureDetectorDemo.kt
new file mode 100644
index 0000000..f90345b
--- /dev/null
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/PressReleasedGestureDetectorDemo.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2019 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.ui.framework.demos.gestures
+
+import android.app.Activity
+import android.os.Bundle
+import androidx.compose.state
+import androidx.compose.unaryPlus
+import androidx.ui.core.px
+import androidx.ui.core.setContent
+import androidx.compose.composer
+import androidx.ui.core.dp
+import androidx.ui.core.gesture.PressReleasedGestureDetector
+
+/**
+ * Simple PressReleasedGestureDetector demo.
+ */
+class PressReleasedGestureDetectorDemo : Activity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContent {
+            val color = +state { Colors.random() }
+
+            val onRelease = {
+                color.value = color.value.anotherRandomColor()
+            }
+
+            PressReleasedGestureDetector(onRelease) {
+                MatchParent {
+                    DrawBox(
+                        0.px,
+                        0.px,
+                        96.dp,
+                        96.dp,
+                        color.value
+                    )
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/RawDragGestureDetectorDemo.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/RawDragGestureDetectorDemo.kt
new file mode 100644
index 0000000..f2db005
--- /dev/null
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/RawDragGestureDetectorDemo.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2019 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.ui.framework.demos.gestures
+
+import android.app.Activity
+import android.os.Bundle
+import androidx.compose.state
+import androidx.compose.unaryPlus
+import androidx.ui.core.PxPosition
+import androidx.ui.core.gesture.DragObserver
+import androidx.ui.core.px
+import androidx.ui.core.setContent
+import androidx.compose.composer
+import androidx.ui.core.dp
+import androidx.ui.core.gesture.RawDragGestureDetector
+
+/**
+ * Simple DragGestureDetector demo.
+ */
+class RawDragGestureDetectorDemo : Activity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContent {
+            val xOffset = +state { 0.px }
+            val yOffset = +state { 0.px }
+
+            val dragObserver = object : DragObserver {
+                override fun onDrag(dragDistance: PxPosition): PxPosition {
+                    xOffset.value += dragDistance.x
+                    yOffset.value += dragDistance.y
+                    return dragDistance
+                }
+            }
+
+            RawDragGestureDetector(dragObserver = dragObserver) {
+                MatchParent {
+                    DrawBox(
+                        xOffset.value,
+                        yOffset.value,
+                        96.dp,
+                        96.dp,
+                        Grey
+                    )
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/SimpleComposables.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/SimpleComposables.kt
index dc07bc9..4cc8df7 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/SimpleComposables.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/SimpleComposables.kt
@@ -16,7 +16,6 @@
 
 package androidx.ui.framework.demos.gestures
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.memo
 import androidx.compose.unaryPlus
@@ -30,6 +29,7 @@
 import androidx.ui.painting.Paint
 import androidx.compose.composer
 import androidx.ui.core.Draw
+import androidx.ui.core.IntPx
 
 /**
  * A simple layout composable that matches the size of it's parent layout.
@@ -59,12 +59,26 @@
  * A simple composable that pads items by [padding].
  */
 @Composable
-private fun Padding(padding: Dp?, children: @Composable() () -> Unit) {
+private fun Padding(padding: Dp, children: @Composable() () -> Unit) {
+    Padding(padding, padding, padding, padding, children)
+}
+
+@Composable
+internal fun Padding(
+    paddingLeft: Dp? = null,
+    paddingTop: Dp? = null,
+    paddingRight: Dp? = null,
+    paddingBottom: Dp? = null,
+    children: @Composable() () -> Unit
+) {
     Layout(children) { measurables, constraints ->
-        val paddingPx = padding?.toIntPx() ?: 0.ipx
-        val doublePadding = paddingPx * 2
-        val maxWidth = constraints.maxWidth - doublePadding
-        val maxHeight = constraints.maxHeight - doublePadding
+        println(constraints)
+        val paddingLeftIpx = paddingLeft?.toIntPx() ?: IntPx.Zero
+        val paddingTopIpx = paddingTop?.toIntPx() ?: IntPx.Zero
+        val paddingRightIpx = paddingRight?.toIntPx() ?: IntPx.Zero
+        val paddingBottomIpx = paddingBottom?.toIntPx() ?: IntPx.Zero
+        val maxWidth = constraints.maxWidth - paddingLeftIpx - paddingRightIpx
+        val maxHeight = constraints.maxHeight - paddingTopIpx - paddingBottomIpx
         val minWidth =
             if (constraints.minWidth > maxWidth) {
                 maxWidth
@@ -77,20 +91,21 @@
             } else {
                 constraints.minHeight
             }
-        val placeable = measurables.first().measure(
-            Constraints(minWidth, maxWidth, minHeight, maxHeight)
-        )
+
+        val placeable = if (measurables.isNotEmpty()) {
+            measurables.first().measure(Constraints(minWidth, maxWidth, minHeight, maxHeight))
+        } else {
+            null
+        }
+
         layout(constraints.maxWidth, constraints.maxHeight) {
-            placeable.place(paddingPx, paddingPx)
+            placeable?.place(paddingLeftIpx, paddingTopIpx)
         }
     }
 }
 
-/**
- * A simple composable that draws a border around it's children.
- */
 @Composable
-private fun Border(color: Color, width: Dp, children: @Composable() () -> Unit) {
+internal fun Border(color: Color, width: Dp, children: @Composable() () -> Unit) {
     Layout(
         children = {
             children()
@@ -114,7 +129,7 @@
                 )
             }
         },
-        layoutBlock = { measurables, constraints ->
+        measureBlock = { measurables, constraints ->
             val placeable =
                 if (measurables.isNotEmpty()) measurables.first().measure(constraints) else null
             val layoutWidth = placeable?.width ?: constraints.maxWidth
@@ -125,16 +140,6 @@
         })
 }
 
-/**
- * A simple composable that contains items within optional [width] and [height] dimensions, wraps
- * the contents in a border (with [borderColor] and [borderWidth]), and optionally pads everything
- * with [padding],
- *
- * If [width] or [height] are not set, the parent's min and max constraints are passed through for
- * the given dimension.  If [padding] is not set, no padding will be applied. If
- * [borderColor] is not set, a reasonable default will be used, and if [borderWidth] is not set,
- * no border will be drawn.
- */
 @Composable
 internal fun SimpleContainer(
     width: Dp,
@@ -144,7 +149,7 @@
 ) {
 
     val borderWidth: Dp = 2.dp
-    val borderColor: Color = Color(0f, 0f, 0f, .12f)
+    val borderColor = BorderColor
 
     Layout({
         Padding(padding) {
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/TouchSlopDragGestureDetectorDemo.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/TouchSlopDragGestureDetectorDemo.kt
new file mode 100644
index 0000000..c91bad5
--- /dev/null
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/TouchSlopDragGestureDetectorDemo.kt
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2019 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.ui.framework.demos.gestures
+
+import android.app.Activity
+import android.os.Bundle
+import androidx.compose.state
+import androidx.compose.unaryPlus
+import androidx.ui.core.PxPosition
+import androidx.ui.core.gesture.DragObserver
+import androidx.ui.core.px
+import androidx.ui.core.setContent
+import androidx.ui.graphics.Color
+import androidx.ui.core.Direction
+import androidx.ui.core.dp
+import androidx.ui.core.gesture.TouchSlopDragGestureDetector
+import androidx.compose.composer
+
+/**
+ * Simple demo that shows off TouchSlopDragGestureDetector.
+ */
+class TouchSlopDragGestureDetectorDemo : Activity() {
+
+    val VerticalColor = Color(0xfff44336.toInt())
+    val HorizontalColor = Color(0xff2196f3.toInt())
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContent {
+            val xOffset = +state { 0.px }
+            val yOffset = +state { 0.px }
+            val canStartVertically = +state { true }
+
+            val dragObserver =
+                if (canStartVertically.value) {
+                    object : DragObserver {
+                        override fun onDrag(dragDistance: PxPosition): PxPosition {
+                            yOffset.value += dragDistance.y
+                            return dragDistance
+                        }
+
+                        override fun onStop(velocity: PxPosition) {
+                            canStartVertically.value = !canStartVertically.value
+                            super.onStop(velocity)
+                        }
+                    }
+                } else {
+                    object : DragObserver {
+                        override fun onDrag(dragDistance: PxPosition): PxPosition {
+                            xOffset.value += dragDistance.x
+                            return dragDistance
+                        }
+
+                        override fun onStop(velocity: PxPosition) {
+                            canStartVertically.value = !canStartVertically.value
+                            super.onStop(velocity)
+                        }
+                    }
+                }
+
+            val canDrag =
+                if (canStartVertically.value) {
+                    { direction: Direction ->
+                        when (direction) {
+                            Direction.DOWN -> true
+                            Direction.UP -> true
+                            else -> false
+                        }
+                    }
+                } else {
+                    { direction: Direction ->
+                        when (direction) {
+                            Direction.LEFT -> true
+                            Direction.RIGHT -> true
+                            else -> false
+                        }
+                    }
+                }
+
+            val color =
+                if (canStartVertically.value) {
+                    VerticalColor
+                } else {
+                    HorizontalColor
+                }
+
+            TouchSlopDragGestureDetector(dragObserver, canDrag) {
+                MatchParent {
+                    DrawBox(
+                        xOffset.value,
+                        yOffset.value,
+                        96.dp,
+                        96.dp,
+                        color
+                    )
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/TouchSlopExceededGestureDetectorDemo.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/TouchSlopExceededGestureDetectorDemo.kt
new file mode 100644
index 0000000..0ff9f44
--- /dev/null
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/TouchSlopExceededGestureDetectorDemo.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2019 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.ui.framework.demos.gestures
+
+import android.app.Activity
+import android.os.Bundle
+import androidx.compose.state
+import androidx.compose.unaryPlus
+import androidx.ui.core.px
+import androidx.ui.core.setContent
+import androidx.ui.graphics.Color
+import androidx.ui.core.dp
+import androidx.compose.composer
+import androidx.ui.core.Direction
+import androidx.ui.core.gesture.TouchSlopExceededGestureDetector
+
+/**
+ * Simple demo that shows off TouchSlopExceededGestureDetector.
+ */
+class TouchSlopExceededGestureDetectorDemo : Activity() {
+
+    val VerticalColor = Color(0xfff44336.toInt())
+    val HorizontalColor = Color(0xff2196f3.toInt())
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContent {
+            val xOffset = +state { 0.px }
+            val yOffset = +state { 0.px }
+            val orientationVertical = +state { true }
+
+            // This would be more efficient if onTouchSlopExceeded were memoized because it's
+            // value doesn't need to change for each new composition.  Like this, every time
+            // we recompose, a new lambda is created.  Here we aren't memoizing to demonstrate
+            // that TouchSlopExceededGestureDetector behaves correctly when it is recomposed
+            // because onTouchSlopExceeded changes.
+            val onTouchSlopExceeded =
+                {
+                    orientationVertical.value = !orientationVertical.value
+                }
+
+            val canDrag =
+                if (orientationVertical.value) {
+                    { direction: Direction ->
+                        when (direction) {
+                            Direction.UP -> true
+                            Direction.DOWN -> true
+                            else -> false
+                        }
+                    }
+                } else {
+                    { direction: Direction ->
+                        when (direction) {
+                            Direction.LEFT -> true
+                            Direction.RIGHT -> true
+                            else -> false
+                        }
+                    }
+                }
+
+            val color =
+                if (orientationVertical.value) {
+                    VerticalColor
+                } else {
+                    HorizontalColor
+                }
+
+            TouchSlopExceededGestureDetector(onTouchSlopExceeded, canDrag) {
+                MatchParent {
+                    DrawBox(
+                        xOffset.value,
+                        yOffset.value,
+                        96.dp,
+                        96.dp,
+                        color
+                    )
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-framework/integration-tests/samples/src/main/java/androidx/ui/framework/samples/DrawShadowSample.kt b/ui/ui-framework/integration-tests/samples/src/main/java/androidx/ui/framework/samples/DrawShadowSample.kt
new file mode 100644
index 0000000..f646a45
--- /dev/null
+++ b/ui/ui-framework/integration-tests/samples/src/main/java/androidx/ui/framework/samples/DrawShadowSample.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2019 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.ui.framework.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.Composable
+import androidx.compose.composer
+import androidx.ui.core.DrawShadow
+import androidx.ui.core.dp
+import androidx.ui.foundation.shape.RectangleShape
+
+@Sampled
+@Composable
+fun DrawShadowSample() {
+    DrawShadow(shape = RectangleShape, elevation = 12.dp)
+}
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
index 3c79ab3..48461f4 100644
--- a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
@@ -24,7 +24,6 @@
 import android.view.ViewGroup
 import android.view.ViewTreeObserver
 import androidx.annotation.RequiresApi
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.Compose
 import androidx.compose.Model
@@ -289,7 +288,7 @@
                     Padding(size = model.size) {
                         FillColor(model.innerColor)
                     }
-                }, layoutBlock = { measurables, constraints ->
+                }, measureBlock = { measurables, constraints ->
                     val placeables = measurables.map { it.measure(constraints) }
                     layout(placeables[0].width, placeables[0].height) {
                         placeables[0].place(0.ipx, 0.ipx)
@@ -366,11 +365,11 @@
                     Padding(size = size) {
                         WithConstraints { constraints ->
                             paddedConstraints.value = constraints
-                            Layout(layoutBlock = { _, childConstraints ->
+                            Layout(measureBlock = { _, childConstraints ->
                                 firstChildConstraints.value = childConstraints
                                 layout(size, size) { }
                             }, children = { })
-                            Layout(layoutBlock = { _, chilConstraints ->
+                            Layout(measureBlock = { _, chilConstraints ->
                                 secondChildConstraints.value = chilConstraints
                                 layout(size, size) { }
                             }, children = { })
@@ -424,20 +423,23 @@
         activityTestRule.runOnUiThreadIR {
             activity.setContent {
                 val header = @Composable {
-                    Layout(layoutBlock = { _, constraints ->
+                    Layout(measureBlock = { _, constraints ->
                         assertEquals(childConstraints[0], constraints)
+                        layout(0.ipx, 0.ipx) {}
                     }, children = {})
                 }
                 val footer = @Composable {
-                    Layout(layoutBlock = { _, constraints ->
+                    Layout(measureBlock = { _, constraints ->
                         assertEquals(childConstraints[1], constraints)
+                        layout(0.ipx, 0.ipx) {}
                     }, children = {})
-                    Layout(layoutBlock = { _, constraints ->
+                    Layout(measureBlock = { _, constraints ->
                         assertEquals(childConstraints[2], constraints)
+                        layout(0.ipx, 0.ipx) {}
                     }, children = {})
                 }
                 @Suppress("USELESS_CAST")
-                Layout(childrenArray = arrayOf(header, footer)) { measurables, _ ->
+                Layout(header, footer) { measurables, _ ->
                     assertEquals(childrenCount, measurables.size)
                     measurables.forEachIndexed { index, measurable ->
                         measurable.measure(childConstraints[index])
@@ -447,6 +449,7 @@
                     assertEquals(footerChildrenCount, measurables[footer].size)
                     assertSame(measurables[1], measurables[footer][0])
                     assertSame(measurables[2], measurables[footer][1])
+                    layout(0.ipx, 0.ipx) {}
                 }
             }
         }
@@ -458,18 +461,19 @@
             activity.setContent {
                 val header = @Composable {
                     ParentData(data = 0) {
-                        Layout(layoutBlock = { _, _ -> }, children = {})
+                        Layout(measureBlock = { _, _ -> layout(0.ipx, 0.ipx, {}) }, children = {})
                     }
                 }
                 val footer = @Composable {
                     ParentData(data = 1) {
-                        Layout(layoutBlock = { _, _ -> }, children = {})
+                        Layout(measureBlock = { _, _ -> layout(0.ipx, 0.ipx, {}) }, children = {})
                     }
                 }
 
-                Layout(childrenArray = arrayOf(header, footer)) { measurables, _ ->
+                Layout(header, footer) { measurables, _ ->
                     assertEquals(0, measurables[0].parentData)
                     assertEquals(1, measurables[1].parentData)
+                    layout(0.ipx, 0.ipx, {})
                 }
             }
         }
@@ -517,7 +521,7 @@
                             canvas.drawRect(parentSize.toRect(), paint)
                         }
                     }
-                }, layoutBlock = { measurables, constraints ->
+                }, measureBlock = { measurables, constraints ->
                     measureCalls++
                     layout(30.ipx, 30.ipx) {
                         layoutCalls++
@@ -555,7 +559,7 @@
             height: IntPx,
             children: @Composable() () -> Unit
         ) {
-            Layout(children = children, layoutBlock = { measurables, constraints ->
+            Layout(children = children, measureBlock = { measurables, constraints ->
                 val resolvedWidth = width.coerceIn(constraints.minWidth, constraints.maxWidth)
                 val resolvedHeight = height.coerceIn(constraints.minHeight, constraints.maxHeight)
                 layout(resolvedWidth, resolvedHeight) {
@@ -591,7 +595,7 @@
                     drawn.value = true
                     latch.countDown()
                 }
-            }, layoutBlock = { _, constraints ->
+            }, measureBlock = { _, constraints ->
                 measured.value = true
                 val resolvedWidth = width.coerceIn(constraints.minWidth, constraints.maxWidth)
                 val resolvedHeight = constraints.minHeight
@@ -938,7 +942,7 @@
 @Composable
 fun AtLeastSize(size: IntPx, children: @Composable() () -> Unit) {
     Layout(
-        layoutBlock = { measurables, constraints ->
+        measureBlock = { measurables, constraints ->
             val newConstraints = Constraints(
                 minWidth = max(size, constraints.minWidth),
                 maxWidth = max(size, constraints.maxWidth),
@@ -966,7 +970,7 @@
 @Composable
 fun Align(children: @Composable() () -> Unit) {
     Layout(
-        layoutBlock = { measurables, constraints ->
+        measureBlock = { measurables, constraints ->
             val newConstraints = Constraints(
                 minWidth = IntPx.Zero,
                 maxWidth = constraints.maxWidth,
@@ -994,7 +998,7 @@
 @Composable
 fun Padding(size: IntPx, children: @Composable() () -> Unit) {
     Layout(
-        layoutBlock = { measurables, constraints ->
+        measureBlock = { measurables, constraints ->
             val totalDiff = size * 2
             val newConstraints = Constraints(
                 minWidth = (constraints.minWidth - totalDiff).coerceAtLeast(0.ipx),
@@ -1042,6 +1046,7 @@
             // expected
             latch.countDown()
         }
+        layout(0.ipx, 0.ipx, {})
     }
 }
 
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/DrawShadowTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/DrawShadowTest.kt
new file mode 100644
index 0000000..6c9b274
--- /dev/null
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/DrawShadowTest.kt
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2019 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.ui.core.test
+
+import android.graphics.Bitmap
+import android.os.Build
+import androidx.compose.Composable
+import androidx.compose.Model
+import androidx.compose.composer
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import androidx.test.rule.ActivityTestRule
+import androidx.ui.core.Density
+import androidx.ui.core.Dp
+import androidx.ui.core.Draw
+import androidx.ui.core.DrawShadow
+import androidx.ui.core.PxSize
+import androidx.ui.core.dp
+import androidx.ui.core.ipx
+import androidx.ui.core.setContent
+import androidx.ui.core.toRect
+import androidx.ui.engine.geometry.Outline
+import androidx.ui.engine.geometry.Shape
+import androidx.ui.framework.test.TestActivity
+import androidx.ui.graphics.Color
+import androidx.ui.painting.Paint
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotEquals
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+
+@SmallTest
+@RunWith(JUnit4::class)
+class DrawShadowTest {
+
+    @get:Rule
+    val rule = ActivityTestRule<TestActivity>(TestActivity::class.java)
+    private lateinit var activity: TestActivity
+    private lateinit var drawLatch: CountDownLatch
+
+    // TODO move RectangleShape to ui-framework b/137222372
+    private val rectShape = object : Shape {
+        override fun createOutline(size: PxSize, density: Density): Outline =
+            Outline.Rectangle(size.toRect())
+    }
+
+    @Before
+    fun setup() {
+        activity = rule.activity
+        activity.hasFocusLatch.await(5, TimeUnit.SECONDS)
+        drawLatch = CountDownLatch(1)
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun shadowDrawn() {
+        rule.runOnUiThreadIR {
+            activity.setContent {
+                AtLeastSize(size = 12.ipx) {
+                    FillColor(Color.White)
+                    AtLeastSize(size = 10.ipx) {
+                        DrawShadow(rectShape, 8.dp)
+                    }
+                }
+            }
+        }
+
+        assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
+        takeScreenShot(12).apply {
+            assertNotEquals(color(5, 11), Color.White)
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun switchFromShadowToNoShadow() {
+        val model = ShadowModel(12.dp)
+
+        rule.runOnUiThreadIR {
+            activity.setContent {
+                AtLeastSize(size = 12.ipx) {
+                    FillColor(Color.White)
+                    AtLeastSize(size = 10.ipx) {
+                        DrawShadow(rectShape, model.elevation)
+                    }
+                }
+            }
+        }
+        assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
+
+        rule.runOnUiThreadIR {
+            model.elevation = 0.dp
+        }
+
+        takeScreenShot(12).apply {
+            assertEquals(color(5, 11), Color.White)
+        }
+    }
+
+    @Composable
+    private fun FillColor(color: Color) {
+        Draw { canvas, parentSize ->
+            canvas.drawRect(parentSize.toRect(), Paint().apply {
+                this.color = color
+            })
+            drawLatch.countDown()
+        }
+    }
+
+    private fun takeScreenShot(width: Int, height: Int = width): Bitmap {
+        val bitmap = rule.waitAndScreenShot()
+        assertEquals(width, bitmap.width)
+        assertEquals(height, bitmap.height)
+        return bitmap
+    }
+}
+
+@Model
+private data class ShadowModel(var elevation: Dp)
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/ParentDataTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/ParentDataTest.kt
index c8de633..196df60 100644
--- a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/ParentDataTest.kt
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/ParentDataTest.kt
@@ -65,7 +65,7 @@
             activity.setContent {
                 Layout(children = {
                     SimpleDrawChild(drawLatch = drawLatch)
-                }, layoutBlock = { measurables, constraints ->
+                }, measureBlock = { measurables, constraints ->
                     assertEquals(1, measurables.size)
                     parentData.value = measurables[0].parentData
 
@@ -90,7 +90,7 @@
                     ParentData(data = "Hello") {
                         SimpleDrawChild(drawLatch = drawLatch)
                     }
-                }, layoutBlock = { measurables, constraints ->
+                }, measureBlock = { measurables, constraints ->
                     assertEquals(1, measurables.size)
                     parentData.value = measurables[0].parentData
 
@@ -115,7 +115,7 @@
                 ParentData(data = "Hello") {
                     Layout(children = {
                         SimpleDrawChild(drawLatch = drawLatch)
-                    }, layoutBlock = { measurables, constraints ->
+                    }, measureBlock = { measurables, constraints ->
                         assertEquals(1, measurables.size)
                         parentData.value = measurables[0].parentData
 
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/TextLayoutTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/TextLayoutTest.kt
index 9f42391..8e5c1d9 100644
--- a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/TextLayoutTest.kt
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/TextLayoutTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.ui.core.test
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.test.filters.SmallTest
@@ -130,14 +129,14 @@
                 Text("aaaa", style = TextStyle(fontFamily = fontFamily))
             }
             ComplexLayout(text) {
-                layout { measurables, _ ->
+                measure { measurables, _ ->
                     val textMeasurable = measurables.first()
 
                     // Min width.
                     var threw = false
                     try {
                         textMeasurable.minIntrinsicWidth(0.ipx)
-                    } catch(e: UnsupportedOperationException) {
+                    } catch (e: UnsupportedOperationException) {
                         threw = true
                     }
                     assertTrue(threw)
@@ -153,6 +152,8 @@
                     assertEquals(textHeight, textMeasurable.maxIntrinsicHeight(IntPx.Infinity))
 
                     intrinsicsLatch.countDown()
+
+                    layout(0.ipx, 0.ipx) {}
                 }
                 minIntrinsicWidth { _, _ -> 0.ipx }
                 minIntrinsicHeight { _, _ -> 0.ipx }
@@ -182,4 +183,4 @@
         }
         activityTestRule.runOnUiThread(runnable)
     }
-}
\ No newline at end of file
+}
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Draw.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Draw.kt
index b637111..b45e613 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Draw.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/Draw.kt
@@ -35,7 +35,6 @@
  */
 @Composable
 fun Draw(
-    @Children(composable = false)
     onPaint: DensityReceiver.(canvas: Canvas, parentSize: PxSize) -> Unit
 ) {
     // Hide the internals of DrawNode
@@ -60,7 +59,6 @@
 @Composable
 fun Draw(
     children: @Composable() () -> Unit,
-    @Children(composable = false)
     onPaint: DrawReceiver.(canvas: Canvas, parentSize: PxSize) -> Unit
 ) {
     // Hide the internals of DrawNode
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/DrawShadow.kt b/ui/ui-framework/src/main/java/androidx/ui/core/DrawShadow.kt
new file mode 100644
index 0000000..1b0c296
--- /dev/null
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/DrawShadow.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019 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.ui.core
+
+import androidx.compose.Composable
+import androidx.compose.composer
+import androidx.ui.engine.geometry.Shape
+
+/**
+ * Draws the shadow. The [elevation] defines the visual dept of the physical object.
+ * The physical object has a shape specified by [shape].
+ *
+ * Example usage:
+ *
+ * @sample androidx.ui.framework.samples.DrawShadowSample
+ *
+ * @param elevation The z-coordinate at which to place this physical object.
+ * @param shape Defines a shape of the physical object
+ */
+@Composable
+fun DrawShadow(shape: Shape, elevation: Dp) {
+    <RepaintBoundaryNode name=null shape=shape elevation=elevation/>
+}
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Layout.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Layout.kt
index 168452a..b1f1b1c 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Layout.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/Layout.kt
@@ -16,7 +16,6 @@
 
 package androidx.ui.core
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.Compose
 import androidx.compose.ambient
@@ -27,14 +26,28 @@
 import androidx.compose.trace
 import androidx.compose.unaryPlus
 
-internal typealias LayoutBlock = LayoutBlockReceiver.(List<Measurable>, Constraints) -> Unit
-internal typealias IntrinsicMeasurementBlock = IntrinsicMeasurementsReceiver
-    .(List<Measurable>, IntPx) -> IntPx
-internal val LayoutBlockStub: LayoutBlock = { _, _ -> }
+internal typealias LayoutBlock =
+        LayoutBlockReceiver.(List<Measurable>, Constraints) -> LayoutResult
+internal typealias ComplexLayoutBlock =
+        ComplexLayoutBlockReceiver.(List<Measurable>, Constraints) -> LayoutResult
+internal typealias IntrinsicMeasurementBlock =
+        IntrinsicMeasurementReceiver.(List<Measurable>, IntPx) -> IntPx
+
+internal val ComplexLayoutBlockStub: ComplexLayoutBlock = { _, _ -> LayoutResult.instance }
 internal val IntrinsicMeasurementBlockStub: IntrinsicMeasurementBlock = { _, _ -> 0.ipx }
 
+/**
+ * Object returned from [LayoutBlockReceiver.layout] and [ComplexLayoutBlockReceiver.layoutResult]
+ * to deliver proof the method was called in [LayoutBlock] and [ComplexLayoutBlock], respectively.
+ */
+class LayoutResult private constructor() {
+    companion object {
+        internal val instance = LayoutResult()
+    }
+}
+
 internal class ComplexLayoutState(
-    internal var layoutBlock: LayoutBlock = LayoutBlockStub,
+    internal var layoutBlock: ComplexLayoutBlock = ComplexLayoutBlockStub,
     internal var minIntrinsicWidthBlock: IntrinsicMeasurementBlock = IntrinsicMeasurementBlockStub,
     internal var maxIntrinsicWidthBlock: IntrinsicMeasurementBlock = IntrinsicMeasurementBlockStub,
     internal var minIntrinsicHeightBlock: IntrinsicMeasurementBlock = IntrinsicMeasurementBlockStub,
@@ -57,9 +70,9 @@
     internal var block: ComplexLayoutReceiver.() -> Unit = {}
     internal var positioningBlock: PositioningBlockReceiver.() -> Unit = {}
 
-    internal val layoutBlockReceiver = LayoutBlockReceiver(this)
+    internal val layoutBlockReceiver = ComplexLayoutBlockReceiver(this)
     internal val intrinsicMeasurementsReceiver =
-        IntrinsicMeasurementsReceiver(this)
+        IntrinsicMeasurementReceiver(this)
     internal val positioningBlockReceiver = PositioningBlockReceiver()
 
     internal val layoutNodeRef = Ref<LayoutNode>()
@@ -203,7 +216,7 @@
  * Receiver scope for the [ComplexLayout] lambda.
  */
 class ComplexLayoutReceiver internal constructor(internal val layoutState: ComplexLayoutState) {
-    fun layout(layoutBlock: LayoutBlock) {
+    fun measure(layoutBlock: ComplexLayoutBlock) {
         layoutState.layoutBlock = layoutBlock
     }
     fun minIntrinsicWidth(minIntrinsicWidthBlock: IntrinsicMeasurementBlock) {
@@ -220,7 +233,7 @@
     }
 
     internal fun runBlock(block: ComplexLayoutReceiver.() -> Unit) {
-        layoutState.layoutBlock = LayoutBlockStub
+        layoutState.layoutBlock = ComplexLayoutBlockStub
         layoutState.minIntrinsicWidthBlock = IntrinsicMeasurementBlockStub
         layoutState.maxIntrinsicWidthBlock = IntrinsicMeasurementBlockStub
         layoutState.minIntrinsicHeightBlock = IntrinsicMeasurementBlockStub
@@ -231,7 +244,7 @@
         val noLambdaMessage = { subject: String ->
             { "No $subject lambda provided in ComplexLayout" }
         }
-        require(layoutState.layoutBlock != LayoutBlockStub, noLambdaMessage("layout"))
+        require(layoutState.layoutBlock != ComplexLayoutBlockStub, noLambdaMessage("layout"))
         require(
             layoutState.minIntrinsicWidthBlock != IntrinsicMeasurementBlockStub,
             noLambdaMessage("minIntrinsicWidth")
@@ -264,7 +277,7 @@
 @Composable
 fun ComplexLayout(
     children: @Composable() () -> Unit,
-    @Children(composable = false) block: ComplexLayoutReceiver.() -> Unit
+    block: ComplexLayoutReceiver.() -> Unit
 ) {
     val density = +ambientDensity()
     val layoutState = +memo { ComplexLayoutState(density = density) }
@@ -283,7 +296,7 @@
 /**
  * Receiver scope for [ComplexLayout]'s intrinsic measurements lambdas.
  */
-class IntrinsicMeasurementsReceiver internal constructor(
+class IntrinsicMeasurementReceiver internal constructor(
     internal val layoutState: ComplexLayoutState
 ) : DensityReceiver {
     override val density: Density
@@ -301,7 +314,7 @@
 /**
  * Receiver scope for [ComplexLayout]'s layout lambda.
  */
-class LayoutBlockReceiver internal constructor(
+class ComplexLayoutBlockReceiver internal constructor(
     internal val layoutState: ComplexLayoutState
 ) : DensityReceiver {
     override val density: Density
@@ -311,13 +324,14 @@
         this as ComplexLayoutState
         return this.measure(constraints)
     }
-    fun layoutResult(
+    fun layout(
         width: IntPx,
         height: IntPx,
-        block: PositioningBlockReceiver.() -> Unit
-    ) {
+        positioningBlock: PositioningBlockReceiver.() -> Unit
+    ): LayoutResult {
         layoutState.resize(width, height)
-        layoutState.positioningBlock = block
+        layoutState.positioningBlock = positioningBlock
+        return LayoutResult.instance
     }
     fun Measurable.minIntrinsicWidth(h: IntPx) =
         (this as ComplexLayoutState).minIntrinsicWidth(h)
@@ -344,20 +358,19 @@
 @Composable
 fun Layout(
     children: @Composable() () -> Unit,
-    @Children(composable = false) layoutBlock: LayoutReceiver
-        .(measurables: List<Measurable>, constraints: Constraints) -> Unit
+    measureBlock: LayoutBlock
 ) {
     trace("UI:Layout") {
         ComplexLayout(children = children, block = {
-            val layoutReceiver = LayoutReceiver(
+            val layoutReceiver = LayoutBlockReceiver(
                 layoutState,
                 LayoutMeasure, /* measure lambda */
                 { _, _, _ -> }
             )
-            layout { measurables, constraints ->
+            measure { measurables, constraints ->
                 layoutReceiver.complexMeasure = LayoutMeasure
-                layoutReceiver.complexLayoutResult = this::layoutResult
-                layoutReceiver.layoutBlock(measurables, constraints)
+                layoutReceiver.complexLayoutResult = { w, h, block -> layout(w, h, block) }
+                layoutReceiver.measureBlock(measurables, constraints)
             }
 
             minIntrinsicWidth { measurables, h ->
@@ -368,7 +381,7 @@
                 }
                 layoutReceiver.complexLayoutResult = { width, _, _ -> intrinsicWidth = width }
                 val constraints = Constraints(maxHeight = h)
-                layoutBlock(layoutReceiver, measurables, constraints)
+                layoutReceiver.measureBlock(measurables, constraints)
                 intrinsicWidth
             }
 
@@ -380,7 +393,7 @@
                 }
                 layoutReceiver.complexLayoutResult = { width, _, _ -> intrinsicWidth = width }
                 val constraints = Constraints(maxHeight = h)
-                layoutBlock(layoutReceiver, measurables, constraints)
+                layoutReceiver.measureBlock(measurables, constraints)
                 intrinsicWidth
             }
 
@@ -392,7 +405,7 @@
                 }
                 layoutReceiver.complexLayoutResult = { _, height, _ -> intrinsicHeight = height }
                 val constraints = Constraints(maxWidth = w)
-                layoutBlock(layoutReceiver, measurables, constraints)
+                layoutReceiver.measureBlock(measurables, constraints)
                 intrinsicHeight
             }
 
@@ -404,7 +417,7 @@
                 }
                 layoutReceiver.complexLayoutResult = { _, height, _ -> intrinsicHeight = height }
                 val constraints = Constraints(maxWidth = w)
-                layoutBlock(layoutReceiver, measurables, constraints)
+                layoutReceiver.measureBlock(measurables, constraints)
                 intrinsicHeight
             }
         })
@@ -436,13 +449,12 @@
  */
 @Composable
 fun Layout(
-    childrenArray: Array<@Composable() () -> Unit>,
-    @Children(composable = false) layoutBlock: LayoutReceiver
-        .(measurables: List<Measurable>, constraints: Constraints) -> Unit
+    vararg childrenArray: @Composable() () -> Unit,
+    measureBlock: LayoutBlock
 ) {
     val ChildrenEndMarker = @Composable { children: @Composable() () -> Unit ->
         ParentData(data = ChildrenEndParentData(children)) {
-            Layout(layoutBlock={_, _ -> layout(0.ipx, 0.ipx){}}, children = {})
+            Layout(measureBlock={_, _ -> layout(0.ipx, 0.ipx){}}, children = {})
         }
     }
     val children = @Composable {
@@ -453,14 +465,14 @@
         }
     }
 
-    Layout(layoutBlock = layoutBlock, children = children)
+    Layout(measureBlock = measureBlock, children = children)
 }
 
 /**
- * Receiver scope for the lambda of [Layout].
+ * Receiver scope for [Layout]'s layout lambda.
  * Used to mask away intrinsics inside [Layout].
  */
-class LayoutReceiver internal constructor(
+class LayoutBlockReceiver internal constructor(
     internal val layoutState: ComplexLayoutState,
     internal var complexMeasure: (Measurable, Constraints) -> Placeable,
     internal var complexLayoutResult: (IntPx, IntPx, PositioningBlockReceiver.() -> Unit) -> Unit
@@ -487,8 +499,13 @@
      * calls to [Placeable.place], defining the positions of the children relative to the current
      * layout.
      */
-    fun layout(width: IntPx, height: IntPx, block: PositioningBlockReceiver.() -> Unit) {
-        complexLayoutResult(width, height, block)
+    fun layout(
+        width: IntPx,
+        height: IntPx,
+        positioningBlock: PositioningBlockReceiver.() -> Unit
+    ): LayoutResult {
+        complexLayoutResult(width, height, positioningBlock)
+        return LayoutResult.instance
     }
 }
 
@@ -520,33 +537,31 @@
     val ref = +compositionReference()
     val context = +ambient(ContextAmbient)
 
-    Layout(
-        layoutBlock = { _, constraints ->
-            val root = layoutState.layoutNode
-            // Start subcomposition from the current node.
-            Compose.composeInto(
-                root,
-                context,
-                ref
-            ) {
-                children(p1 = constraints)
-            }
+    Layout(children = {}) { _, constraints ->
+        val root = layoutState.layoutNode
+        // Start subcomposition from the current node.
+        Compose.composeInto(
+            root,
+            context,
+            ref
+        ) {
+            children(p1 = constraints)
+        }
 
-            // Measure the obtained children and compute our size.
-            val measurables = layoutState.childrenMeasurables
-            val placeables = measurables.map { it.measure(constraints) }
-            val layoutSize = constraints.constrain(IntPxSize(
-                placeables.map { it.width }.maxBy { it.value } ?: IntPx.Zero,
-                placeables.map { it.height }.maxBy { it.value } ?: IntPx.Zero
-            ))
+        // Measure the obtained children and compute our size.
+        val measurables = layoutState.childrenMeasurables
+        val placeables = measurables.map { it.measure(constraints) }
+        val layoutSize = constraints.constrain(IntPxSize(
+            placeables.map { it.width }.maxBy { it.value } ?: IntPx.Zero,
+            placeables.map { it.height }.maxBy { it.value } ?: IntPx.Zero
+        ))
 
-            layout(layoutSize.width, layoutSize.height) {
-                placeables.forEach { placeable ->
-                    placeable.place(IntPx.Zero, IntPx.Zero)
-                }
+        layout(layoutSize.width, layoutSize.height) {
+            placeables.forEach { placeable ->
+                placeable.place(IntPx.Zero, IntPx.Zero)
             }
-        },
-        children={})
+        }
+    }
 }
 
 private val OnPositionedKey = DataNodeKey<(LayoutCoordinates) -> Unit>("Compose:OnPositioned")
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Semantics.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Semantics.kt
deleted file mode 100644
index dad6816..0000000
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Semantics.kt
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 2019 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.ui.core
-
-import androidx.ui.core.semantics.SemanticsAction
-import androidx.ui.text.style.TextDirection
-import androidx.compose.Children
-import androidx.compose.Composable
-import androidx.compose.ambient
-import androidx.compose.composer
-import androidx.compose.unaryPlus
-
-// TODO(ryanmentley): This is the wrong package, move it as a standalone CL
-
-@Composable
-@Suppress("PLUGIN_ERROR")
-fun Semantics(
-    /**
-     * If 'container' is true, this component will introduce a new
-     * node in the semantics tree. Otherwise, the semantics will be
-     * merged with the semantics of any ancestors.
-     *
-     * Whether descendants of this component can add their semantic information
-     * to the [SemanticsNode] introduced by this configuration is controlled by
-     * [explicitChildNodes].
-     */
-    container: Boolean = false,
-    /**
-     * Whether descendants of this component are allowed to add semantic
-     * information to the [SemanticsNode] annotated by this widget.
-     *
-     * When set to false descendants are allowed to annotate [SemanticNode]s of
-     * their parent with the semantic information they want to contribute to the
-     * semantic tree.
-     * When set to true the only way for descendants to contribute semantic
-     * information to the semantic tree is to introduce new explicit
-     * [SemanticNode]s to the tree.
-     *
-     * This setting is often used in combination with [isSemanticBoundary] to
-     * create semantic boundaries that are either writable or not for children.
-     */
-    explicitChildNodes: Boolean = false,
-    /**
-     * Whether the component represented by this configuration is currently enabled.
-     *
-     * A disabled object does not respond to user interactions. Only objects that
-     * usually respond to user interactions, but which currently do not (like a
-     * disabled button) should be marked as disabled.
-     *
-     * The corresponding getter on [SemanticsConfiguration] will return null if the component
-     * doesn't support the concept of being enabled/disabled.
-     */
-    enabled: Boolean? = null,
-    /**
-     * If this node has Boolean state that can be controlled by the user, whether
-     * that state is checked or unchecked, corresponding to true and false,
-     * respectively.
-     *
-     * Do not set this field if the component doesn't have checked/unchecked state that can be
-     * controlled by the user.
-     *
-     * The corresponding getter on [SemanticsConfiguration] returns null if the component does not
-     * have checked/unchecked state.
-     */
-    checked: Boolean? = null,
-    /** Whether the component represented by this configuration is selected (true) or not (false). */
-    selected: Boolean? = null,
-    /** Whether the component represented by this configuration is a button (true) or not (false). */
-    button: Boolean? = null,
-//    header: Boolean? = null,
-//    textField: Boolean? = null,
-//    focused: Boolean? = null,
-    /**
-     * Whether this component corresponds to UI that allows the user to
-     * pick one of several mutually exclusive options.
-     *
-     * For example, a [Radio] button is in a mutually exclusive group because
-     * only one radio button in that group can be marked as [isChecked].
-     */
-    inMutuallyExclusiveGroup: Boolean? = null,
-//    obscured: Boolean? = null,
-//    scopesRoute: Boolean? = null,
-//    namesRoute: Boolean? = null,
-    hidden: Boolean? = null,
-    /**
-     * A textual description of the component
-     *
-     * On iOS this is used for the `accessibilityLabel` property defined in the
-     * `UIAccessibility` Protocol. On Android it is concatenated together with
-     * [value] and [hint] in the following order: [value], [label], [hint].
-     * The concatenated value is then used as the `Text` description.
-     *
-     * The reading direction is given by [textDirection].
-     */
-    label: String? = null,
-    /**
-     * A textual description for the current value of the owning component.
-     *
-     * On iOS this is used for the `accessibilityValue` property defined in the
-     * `UIAccessibility` Protocol. On Android it is concatenated together with
-     * [label] and [hint] in the following order: [value], [label], [hint].
-     * The concatenated value is then used as the `Text` description.
-     *
-     * The reading direction is given by [textDirection].
-     */
-    value: String? = null,
-//    hint: String? = null,
-    /**
-     * The reading direction for the text in [label], [value],  and [hint]
-     */
-    textDirection: TextDirection? = null,
-    testTag: String? = null,
-    actions: List<SemanticsAction<*>> = emptyList(),
-    children: @Composable() () -> Unit
-) {
-    val providedTestTag = +ambient(TestTagAmbient)
-    <SemanticsComponentNode
-        container
-        explicitChildNodes
-        enabled
-        checked
-        selected
-        button
-        header=null
-        textField=null
-        focused=null
-        inMutuallyExclusiveGroup
-        obscured=null
-        scopesRoute=null
-        namesRoute=null
-        hidden
-        label
-        value
-        hint=null
-        textDirection
-        testTag=(testTag ?: providedTestTag)
-        actions>
-        TestTag(tag=DefaultTestTag) {
-            children()
-        }
-    </SemanticsComponentNode>
-}
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Text.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Text.kt
index 4d0fd2a..4ce2cf1 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Text.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/Text.kt
@@ -17,7 +17,6 @@
 
 import android.annotation.SuppressLint
 import androidx.compose.Ambient
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.ambient
 import androidx.compose.composer
@@ -36,10 +35,13 @@
 import androidx.ui.text.ParagraphStyle
 import androidx.ui.core.selection.TextSelectionHandler
 import androidx.ui.core.selection.TextSelectionProcessor
+import androidx.ui.semantics.Semantics
+import androidx.ui.semantics.accessibilityLabel
 import androidx.ui.text.TextSelection
-import androidx.ui.text.TextPainter
+import androidx.ui.text.TextDelegate
 import androidx.ui.text.TextSpan
 import androidx.ui.text.TextStyle
+import androidx.ui.text.style.TextAlign
 import androidx.ui.text.toAnnotatedString
 import androidx.ui.text.style.TextOverflow
 
@@ -76,7 +78,7 @@
      *  Whether the text should break at soft line breaks.
      *  If false, the glyphs in the text will be positioned as if there was unlimited horizontal
      *  space.
-     *  If [softWrap] is false, [overflow] and [textAlign] may have unexpected effects.
+     *  If [softWrap] is false, [overflow] and [TextAlign] may have unexpected effects.
      */
     softWrap: Boolean = DefaultSoftWrap,
     /** How visual overflow should be handled. */
@@ -169,7 +171,7 @@
      *  Whether the text should break at soft line breaks.
      *  If false, the glyphs in the text will be positioned as if there was unlimited horizontal
      *  space.
-     *  If [softWrap] is false, [overflow] and [textAlign] may have unexpected effects.
+     *  If [softWrap] is false, [overflow] and [TextAlign] may have unexpected effects.
      */
     softWrap: Boolean = DefaultSoftWrap,
     /** How visual overflow should be handled. */
@@ -198,7 +200,11 @@
     val density = +ambientDensity()
     val resourceLoader = +ambient(FontLoaderAmbient)
 
-    Semantics(label = text.text) {
+    Semantics(
+        properties = {
+            accessibilityLabel = text.text
+        }
+    ) {
         val textPainter = +memo(
             text,
             mergedStyle,
@@ -208,7 +214,7 @@
             maxLines,
             density
         ) {
-            TextPainter(
+            TextDelegate(
                 text = text,
                 style = mergedStyle,
                 paragraphStyle = paragraphStyle,
@@ -227,21 +233,22 @@
             Draw { canvas, _ ->
                 internalSelection.value?.let {
                     textPainter.paintBackground(
-                        it.start, it.end, selectionColor, canvas)
+                        it.start, it.end, selectionColor, canvas
+                    )
                 }
                 textPainter.paint(canvas)
             }
         }
         ComplexLayout(children) {
-            layout { _, constraints ->
+            measure { _, constraints ->
                 textPainter.layout(constraints)
-                layoutResult(textPainter.width.px.round(), textPainter.height.px.round()) {}
+                layout(textPainter.width.px.round(), textPainter.height.px.round()) {}
             }
             minIntrinsicWidth { _, _ ->
                 // TODO(popam): discuss with the Text team about this
                 throw UnsupportedOperationException()
-                // textPainter.layout(Constraints(0.ipx, IntPx.Infinity, 0.ipx, h))
-                // textPainter.minIntrinsicWidth.px.round()
+                // textDelegate.layout(Constraints(0.ipx, IntPx.Infinity, 0.ipx, h))
+                // textDelegate.minIntrinsicWidth.px.round()
             }
             minIntrinsicHeight { _, w ->
                 textPainter.layout(Constraints(0.ipx, w, 0.ipx, IntPx.Infinity))
@@ -283,11 +290,12 @@
                             selectionCoordinates = Pair(startPx, endPx),
                             mode = mode,
                             onSelectionChange = { internalSelection.value = it },
-                            textPainter = textPainter
+                            textDelegate = textPainter
                         )
                         if (!textSelectionProcessor.isSelected) return null
 
-                        // TODO(qqd): Determine a set of coordinates around a character that we need.
+                        // TODO(qqd): Determine a set of coordinates around a character that we
+                        //  need.
                         return Selection(
                             startCoordinates = textSelectionProcessor.startCoordinates,
                             endCoordinates = textSelectionProcessor.endCoordinates,
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/TextField.kt b/ui/ui-framework/src/main/java/androidx/ui/core/TextField.kt
index 656a8a4..9dfb3d3 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/TextField.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/TextField.kt
@@ -16,52 +16,28 @@
 package androidx.ui.core
 
 import androidx.compose.composer
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.ambient
 import androidx.compose.memo
 import androidx.compose.state
 import androidx.compose.unaryPlus
-import androidx.ui.core.gesture.DragGestureDetector
+import androidx.ui.core.gesture.TouchSlopDragGestureDetector
 import androidx.ui.core.gesture.DragObserver
 import androidx.ui.core.gesture.PressGestureDetector
 import androidx.ui.core.input.FocusManager
-import androidx.ui.graphics.Color
 import androidx.ui.input.EditProcessor
 import androidx.ui.input.EditorModel
+import androidx.ui.input.EditorStyle
 import androidx.ui.input.ImeAction
 import androidx.ui.input.KeyboardType
-import androidx.ui.text.TextPainter
-import androidx.ui.text.TextStyle
-
-/**
- * Data class holding text display attributes used for editors.
- */
-data class EditorStyle(
-    /** The  editor text style */
-    val textStyle: TextStyle? = null,
-
-    /**
-     * The composition background color
-     *
-     * @see EditorModel.composition
-     */
-    val compositionColor: Color = Color(alpha = 0xFF, red = 0xB0, green = 0xE0, blue = 0xE6),
-
-    /**
-     *  The selection background color
-     *
-     *  @see EditorModel.selection
-     */
-    // TODO(nona): share with Text.DEFAULT_SELECTION_COLOR
-    val selectionColor: Color = Color(alpha = 0x66, red = 0x33, green = 0xB5, blue = 0xE5)
-)
+import androidx.ui.input.VisualTransformation
+import androidx.ui.text.TextDelegate
 
 /**
  * A default implementation of TextField
  *
  * To make TextField work with platoform input service, you must keep the editor state and update
- * in [onValueChagne] callback.
+ * in [onValueChange] callback.
  *
  * Example:
  *     var state = +state { EditorModel() }
@@ -126,7 +102,7 @@
     }
     val textPainter = +memo(visualText, mergedStyle, density, resourceLoader) {
         // TODO(nona): Add parameter for text direction, softwrap, etc.
-        TextPainter(
+        TextDelegate(
             text = visualText,
             style = mergedStyle,
             density = density,
@@ -210,7 +186,7 @@
                     hasFocus.value,
                     editorStyle) }
             },
-            layoutBlock = { _, constraints ->
+            measureBlock = { _, constraints ->
                 TextFieldDelegate.layout(textPainter, constraints).let {
                     layout(it.first, it.second) {}
                 }
@@ -312,7 +288,7 @@
         },
         onRelease = { onRelease(tracker.value.getPosition()) }
     ) {
-        DragGestureDetector(
+        TouchSlopDragGestureDetector(
             dragObserver = object : DragObserver {
                 override fun onDrag(dragDistance: PxPosition): PxPosition {
                     tracker.value.onDrag(dragDistance)
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/TextFieldDelegate.kt b/ui/ui-framework/src/main/java/androidx/ui/core/TextFieldDelegate.kt
index 9d66efa..884806f 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/TextFieldDelegate.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/TextFieldDelegate.kt
@@ -21,48 +21,85 @@
 import androidx.ui.input.EditOperation
 import androidx.ui.input.EditProcessor
 import androidx.ui.input.EditorModel
+import androidx.ui.input.EditorStyle
 import androidx.ui.input.FinishComposingTextEditOp
 import androidx.ui.input.ImeAction
 import androidx.ui.input.KeyboardType
+import androidx.ui.input.OffsetMap
 import androidx.ui.input.SetSelectionEditOp
 import androidx.ui.input.TextInputService
+import androidx.ui.input.TransformedText
+import androidx.ui.input.VisualTransformation
+import androidx.ui.input.identityOffsetMap
 import androidx.ui.painting.Canvas
 import androidx.ui.text.AnnotatedString
-import androidx.ui.text.TextPainter
+import androidx.ui.text.Paragraph
+import androidx.ui.text.ParagraphConstraints
+import androidx.ui.text.ParagraphStyle
+import androidx.ui.text.TextDelegate
+import androidx.ui.text.TextStyle
+import androidx.ui.text.font.Font
+import kotlin.math.roundToInt
+
+/**
+ * Computed the line height for the empty TextField.
+ *
+ * The bounding box or x-advance of the empty text is empty, i.e. 0x0 box or 0px advance. However
+ * this is not useful for TextField since text field want to reserve some amount of height for
+ * accepting touch for starting text input. In Android, uses FontMetrics of the first font in the
+ * fallback chain to compute this height, this is because custom font may have different
+ * ascender/descender from the default font in Android.
+ *
+ * Until we have font metrics APIs, use the height of reference text as a workaround.
+ *
+ * TODO(nona): Add FontMetrics API and stop doing this workaround.
+ */
+private fun computeLineHeightForEmptyText(
+    textStyle: TextStyle,
+    density: Density,
+    resourceLoader: Font.ResourceLoader
+): IntPx {
+    return Paragraph(
+        text = "H", // No meaning: just a reference character.
+        style = textStyle,
+        paragraphStyle = ParagraphStyle(),
+        textStyles = listOf(),
+        maxLines = 1,
+        ellipsis = false,
+        density = density,
+        resourceLoader = resourceLoader
+    ).apply {
+        layout(ParagraphConstraints(width = Float.POSITIVE_INFINITY))
+    }.height.roundToInt().ipx
+}
 
 internal class TextFieldDelegate {
     companion object {
         /**
          * Process text layout with given constraint.
          *
-         * @param textPainter The text painter
+         * @param textDelegate The text painter
          * @param constraints The layout constraints
          * @return the bounding box size(width and height) of the layout result
          */
         @JvmStatic
-        fun layout(textPainter: TextPainter, constraints: Constraints): Pair<IntPx, IntPx> {
-            val isEmptyText = textPainter.text?.text?.isEmpty() ?: true
-            val activeTextPainter = if (isEmptyText) {
-                // Even with empty text, edit filed must have at least non-zero height widget. Use
-                // "H" height for this empty text height.
-                TextPainter(
-                    text = AnnotatedString(text = "H"),
-                    style = textPainter.style,
-                    density = textPainter.density,
-                    resourceLoader = textPainter.resourceLoader
-                ).apply {
-                    layout(constraints)
-                }
-            } else {
-                textPainter
-            }
+        fun layout(textDelegate: TextDelegate, constraints: Constraints): Pair<IntPx, IntPx> {
 
             // We anyway need to compute layout for preventing NPE during draw which require layout
             // result.
             // TODO(nona): Fix this?
-            textPainter.layout(constraints)
+            textDelegate.layout(constraints)
 
-            val height = activeTextPainter.height.px.round()
+            val isEmptyText = textDelegate.text?.text?.isEmpty() ?: true
+            val height = if (isEmptyText) {
+                computeLineHeightForEmptyText(
+                    textStyle = textDelegate.style ?: TextStyle(),
+                    density = textDelegate.density,
+                    resourceLoader = textDelegate.resourceLoader
+                )
+            } else {
+                textDelegate.height.px.round()
+            }
             val width = constraints.maxWidth
             return Pair(width, height)
         }
@@ -73,7 +110,7 @@
          * @param canvas The target canvas.
          * @param value The editor state
          * @param offsetMap The offset map
-         * @param textPainter The text painter
+         * @param textDelegate The text painter
          * @param hasFocus true if this widget is focused, otherwise false
          * @param editorStyle The editor style.
          */
@@ -82,12 +119,12 @@
             canvas: Canvas,
             value: EditorModel,
             offsetMap: OffsetMap,
-            textPainter: TextPainter,
+            textDelegate: TextDelegate,
             hasFocus: Boolean,
             editorStyle: EditorStyle
         ) {
             value.composition?.let {
-                textPainter.paintBackground(
+                textDelegate.paintBackground(
                     offsetMap.originalToTransformed(it.start),
                     offsetMap.originalToTransformed(it.end),
                     editorStyle.compositionColor,
@@ -96,18 +133,18 @@
             }
             if (value.selection.collapsed) {
                 if (hasFocus) {
-                    textPainter.paintCursor(
+                    textDelegate.paintCursor(
                         offsetMap.originalToTransformed(value.selection.start), canvas)
                 }
             } else {
-                textPainter.paintBackground(
+                textDelegate.paintBackground(
                     offsetMap.originalToTransformed(value.selection.start),
                     offsetMap.originalToTransformed(value.selection.end),
                     editorStyle.selectionColor,
                     canvas
                 )
             }
-            textPainter.paint(canvas)
+            textDelegate.paint(canvas)
         }
 
         /**
@@ -118,7 +155,7 @@
         @JvmStatic
         fun notifyFocusedRect(
             value: EditorModel,
-            textPainter: TextPainter,
+            textDelegate: TextDelegate,
             layoutCoordinates: LayoutCoordinates,
             textInputService: TextInputService,
             hasFocus: Boolean,
@@ -129,11 +166,17 @@
             }
 
             val bbox = if (value.selection.end < value.text.length) {
-                textPainter.getBoundingBox(offsetMap.originalToTransformed(value.selection.end))
+                textDelegate.getBoundingBox(offsetMap.originalToTransformed(value.selection.end))
             } else if (value.selection.end != 0) {
-                textPainter.getBoundingBox(offsetMap.originalToTransformed(value.selection.end) - 1)
+                textDelegate.getBoundingBox(
+                    offsetMap.originalToTransformed(value.selection.end) - 1)
             } else {
-                Rect(0f, 0f, 1.0f, textPainter.preferredLineHeight)
+                val lineHeightForEmptyText = computeLineHeightForEmptyText(
+                    textDelegate.style ?: TextStyle(),
+                    textDelegate.density,
+                    textDelegate.resourceLoader
+                )
+                Rect(0f, 0f, 1.0f, lineHeightForEmptyText.value.toFloat())
             }
             val globalLT = layoutCoordinates.localToRoot(PxPosition(bbox.left.px, bbox.top.px))
 
@@ -178,7 +221,7 @@
          * Called when onRelease event is fired.
          *
          * @param position The event position in widget coordinate.
-         * @param textPainter The text painter
+         * @param textDelegate The text painter
          * @param editProcessor The edit processor
          * @param offsetMap The offset map
          * @param onValueChange The callback called when the new editor state arrives.
@@ -188,7 +231,7 @@
         @JvmStatic
         fun onRelease(
             position: PxPosition,
-            textPainter: TextPainter,
+            textDelegate: TextDelegate,
             editProcessor: EditProcessor,
             offsetMap: OffsetMap,
             onValueChange: (EditorModel) -> Unit,
@@ -198,7 +241,7 @@
             textInputService?.showSoftwareKeyboard()
             if (hasFocus) {
                 val offset = offsetMap.transformedToOriginal(
-                    textPainter.getOffsetForPosition(position))
+                    textDelegate.getOffsetForPosition(position))
                 onEditCommand(
                     listOf(SetSelectionEditOp(offset, offset)),
                     editProcessor,
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/VisualTransformation.kt b/ui/ui-framework/src/main/java/androidx/ui/core/VisualTransformation.kt
deleted file mode 100644
index 23ff8a6..0000000
--- a/ui/ui-framework/src/main/java/androidx/ui/core/VisualTransformation.kt
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2019 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.ui.core
-
-import androidx.ui.text.AnnotatedString
-
-/**
- * The map interface used for bidirectional offset mapping from original to transformed text.
- */
-interface OffsetMap {
-    /**
-     * Convert offset in original text into the offset in transformed text.
-     *
-     * This function must be a monotonically non-decreasing function. In other words, if a cursor
-     * advances in the original text, the cursor in the transformed text must advance or stay there.
-     *
-     * @param offset offset in original text.
-     * @return offset in transformed text
-     * @see VisualTransformation
-     */
-    fun originalToTransformed(offset: Int): Int
-
-    /**
-     * Convert offset in transformed text into the offset in original text.
-     *
-     * This function must be a monotonically non-decreasing function. In other words, if a cursor
-     * advances in the transformed text, the cusrsor in the original text must advance or stay
-     * there.
-     *
-     * @param offset offset in transformed text
-     * @return offset in original text
-     * @see VisualTransformation
-     */
-    fun transformedToOriginal(offset: Int): Int
-}
-
-/**
- * The transformed text with offset offset mapping
- */
-data class TransformedText(
-    /**
-     * The transformed text
-     */
-    val transformedText: AnnotatedString,
-
-    /**
-     * The map used for bidirectional offset mapping from original to transformed text.
-     */
-    val offsetMap: OffsetMap
-)
-
-/**
- * Interface used for changing visual output of the input field.
- *
- * This interface can be used for changing visual output of the text in the input field.
- * For example, you can mask characters in password filed with asterisk with
- * PasswordVisualTransformation.
- */
-interface VisualTransformation {
-    /**
-     * Change the visual output of given text.
-     *
-     * Note that the returned text length can be different length from the given text. The widget
-     * will call the offset translator for converting offsets for various reasons, cursor drawing
-     * position, text selection by gesture, etc.
-     *
-     * Example: Credit Card Visual Output (inserting hyphens each 4 digits)
-     *  original text   : 1234567890123456
-     *  transformed text: 1234-5678-9012-3456
-     *
-     *  Then, the offset translator should ignore the hyphen characters, so conversion from
-     *  original offset to transformed text works like
-     *  - The 4th char of the original text is 5th char in the transformed text.
-     *  - The 13th char of the original text is 15th char in the transformed text.
-     *  Similarly, the reverse conversion works like
-     *  - The 5th char of the transformed text is 4th char in the original text.
-     *  - The 12th char of the transformed text is 10th char in the original text.
-     *
-     *  The reference implementation would be like as follows:
-     *  <pre>
-     *  val creditCardOffsetTranslator = object : OffsetMap {
-     *      override fun originalToTransformed(originalOffset: Int): Int {
-     *          if (originalOffset <= 3) return originalOffset
-     *          if (originalOffset <= 7) return originalOffset + 1
-     *          if (originalOffset <= 11) return originalOffset + 2
-     *          if (originalOffset <= 16) return originalOffset + 3
-     *          return 19
-     *      }
-     *
-     *      override fun transformedToOriginal(transformedOffset: Int): Int {
-     *          if (transformedOffset <= 4) return transformedOffset
-     *          if (transformedOffset <= 9) return transformedOffset - 1
-     *          if (transformedOffset <= 14) return transformedOffset - 2
-     *          if (transformedOffset <= 19) return transformedOffset - 3
-     *          return 16
-     *      }
-     *  }
-     *  </pre>
-     *
-     * TODO(nona): Add paragraph direction argument for determining offset conversion.
-     *
-     * @param text The original text
-     * @return the pair of filtered text and offset translator.
-     */
-    fun filter(text: AnnotatedString): TransformedText
-}
-
-/**
- * The Visual Filter can be used for password Input Field.
- *
- * Note that this visual filter only works for ASCII characters.
- *
- * @param mask The mask character used instead of original text.
- */
-class PasswordVisualTransformation(val mask: Char = '\u2022') : VisualTransformation {
-    override fun filter(text: AnnotatedString): TransformedText {
-        return TransformedText(AnnotatedString(Character.toString(mask).repeat(text.text.length)),
-            identityOffsetMap)
-    }
-}
-
-/**
- * The offset map used for identity mapping.
- */
-internal val identityOffsetMap = object : OffsetMap {
-    override fun originalToTransformed(offset: Int): Int = offset
-    override fun transformedToOriginal(offset: Int): Int = offset
-}
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Wrapper.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Wrapper.kt
index ed51529..0b7d2f0 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Wrapper.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/Wrapper.kt
@@ -17,13 +17,13 @@
 
 import android.app.Activity
 import android.content.Context
+import android.content.res.Configuration
 import android.view.ViewGroup
 import androidx.annotation.CheckResult
 import androidx.ui.core.input.FocusManager
 import androidx.ui.input.TextInputService
 import androidx.compose.Ambient
 import androidx.compose.composer
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.Compose
 import androidx.compose.CompositionContext
@@ -34,7 +34,10 @@
 import androidx.compose.effectOf
 import androidx.compose.memo
 import androidx.compose.onPreCommit
+import androidx.compose.state
 import androidx.compose.unaryPlus
+import androidx.ui.autofill.Autofill
+import androidx.ui.autofill.AutofillTree
 import androidx.ui.core.text.AndroidFontResourceLoader
 import androidx.ui.text.font.Font
 import kotlinx.coroutines.Dispatchers
@@ -149,18 +152,50 @@
     // TODO(nona): Tie the focus manger lifecycle to Window, otherwise FocusManager won't work
     //             with nested AndroidCraneView case
     val focusManager = +memo { FocusManager() }
+    val configuration = +state { context.applicationContext.resources.configuration }
+
+    // We don't use the attached View's layout direction here since that layout direction may not
+    // be resolved since the widgets may be composed without attaching to the RootViewImpl.
+    // In Jetpack Compose, use the locale layout direction (i.e. layoutDirection came from
+    // configuration) as a default layout direction.
+    val layoutDirection = when(configuration.value.layoutDirection) {
+        android.util.LayoutDirection.LTR -> LayoutDirection.Ltr
+        android.util.LayoutDirection.RTL -> LayoutDirection.Rtl
+        // API doc says Configuration#getLayoutDirection only returns LTR or RTL.
+        // Fallback to LTR for unexpected return value.
+        else -> LayoutDirection.Ltr
+    }
+    +memo {
+        craneView.configurationChangeObserver = {
+            // onConfigurationChange is the correct hook to update configuration, however it is
+            // possible that the configuration object itself may come from a wrapped
+            // context / themed activity, and may not actually reflect the system. So instead we
+            // use this hook to grab the applicationContext's configuration, which accurately
+            // reflects the state of the application / system.
+            configuration.value = context.applicationContext.resources.configuration
+        }
+    }
+
     ContextAmbient.Provider(value = context) {
         CoroutineContextAmbient.Provider(value = coroutineContext) {
-        DensityAmbient.Provider(value = Density(context)) {
-            FocusManagerAmbient.Provider(value = focusManager) {
-                TextInputServiceAmbient.Provider(value = craneView.textInputService) {
-                    FontLoaderAmbient.Provider(value = AndroidFontResourceLoader(context)) {
-                        content()
+            DensityAmbient.Provider(value = Density(context)) {
+                FocusManagerAmbient.Provider(value = focusManager) {
+                    TextInputServiceAmbient.Provider(value = craneView.textInputService) {
+                        FontLoaderAmbient.Provider(value = AndroidFontResourceLoader(context)) {
+                            AutofillTreeAmbient.Provider(value = craneView.autofillTree) {
+                                AutofillAmbient.Provider(value = craneView.autofill) {
+                                    ConfigurationAmbient.Provider(value = configuration.value) {
+                                        LayoutDirectionAmbient.Provider(value = layoutDirection) {
+                                            content()
+                                        }
+                                    }
+                                }
+                            }
+                        }
                     }
                 }
             }
         }
-        }
     }
 }
 
@@ -170,6 +205,15 @@
 
 val CoroutineContextAmbient = Ambient.of<CoroutineContext>()
 
+val ConfigurationAmbient = Ambient.of<Configuration>()
+
+val AutofillAmbient = Ambient.of<Autofill?>()
+
+// This will ultimately be replaced by Autofill Semantics (b/138604305).
+val AutofillTreeAmbient = Ambient.of<AutofillTree>()
+
+val LayoutDirectionAmbient = Ambient.of<LayoutDirection>()
+
 internal val FocusManagerAmbient = Ambient.of<FocusManager>()
 
 internal val TextInputServiceAmbient = Ambient.of<TextInputService?>()
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/DoubleTapGestureDetector.kt b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/DoubleTapGestureDetector.kt
index c887644..ee5268a 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/DoubleTapGestureDetector.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/DoubleTapGestureDetector.kt
@@ -19,7 +19,6 @@
 import androidx.ui.core.PointerEventPass
 import androidx.ui.core.PointerInputChange
 import androidx.ui.core.changedToDown
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.ambient
 import androidx.compose.memo
@@ -39,6 +38,7 @@
 // TODO(b/138605697): This bug tracks the note below: DoubleTapGestureDetector should use the
 //  eventual api that will allow it to temporary block tap.
 // TODO(b/138754591): The behavior of this gesture detector needs to be finalized.
+// TODO(b/139020678): Probably has shared functionality with other press based detectors.
 /**
  * Responds to pointers going up, down within a small duration, and then up again.
  *
@@ -54,17 +54,20 @@
     onDoubleTap: (PxPosition) -> Unit,
     children: @Composable() () -> Unit
 ) {
+    val coroutineContext = +ambient(CoroutineContextAmbient)
     val recognizer =
-        +memo { DoubleTapGestureRecognizer(onDoubleTap, +ambient(CoroutineContextAmbient)) }
+        +memo { DoubleTapGestureRecognizer(coroutineContext) }
+    recognizer.onDoubleTap = onDoubleTap
+
     PointerInputWrapper(pointerInputHandler = recognizer.pointerInputHandler) {
         children()
     }
 }
 
 internal class DoubleTapGestureRecognizer(
-    val onDoubleTap: (PxPosition) -> Unit,
     coroutineContext: CoroutineContext
 ) {
+    lateinit var onDoubleTap: (PxPosition) -> Unit
 
     private enum class State {
         Idle, Down, Up, SecondDown, Cancelled
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/DragGestureDetector.kt b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/DragGestureDetector.kt
deleted file mode 100644
index 0692d57..0000000
--- a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/DragGestureDetector.kt
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Copyright 2019 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.ui.core.gesture
-
-import androidx.compose.Children
-import androidx.compose.Composable
-import androidx.compose.memo
-import androidx.compose.unaryPlus
-import androidx.ui.core.Direction
-import androidx.ui.core.PointerEventPass
-import androidx.ui.core.PointerInputChange
-import androidx.ui.core.PxPosition
-import androidx.ui.core.changedToDown
-import androidx.ui.core.changedToDownIgnoreConsumed
-import androidx.ui.core.changedToUp
-import androidx.ui.core.changedToUpIgnoreConsumed
-import androidx.ui.core.consumeDownChange
-import androidx.ui.core.consumePositionChange
-import androidx.ui.core.gesture.util.VelocityTracker
-import androidx.ui.core.ipx
-import androidx.ui.core.positionChange
-import androidx.ui.core.px
-import androidx.ui.core.withDensity
-import androidx.ui.core.PointerInputWrapper
-import androidx.compose.composer
-
-interface DragObserver {
-
-    /**
-     * Override to be notified when a drag has started.
-     *
-     * This will occur when a pointer has moved far enough to surpass [TouchSlop] in a supported
-     * direction (as reported by DragGestureDetector.canDrag. Always called before [onDrag] and
-     * isn't called again until after [onStop].
-     *
-     * @see onDrag
-     * @see onStop
-     * @see DragGestureRecognizer.canDrag
-     */
-    fun onStart() {}
-
-    /**
-     * Override to be notified when a distance has been dragged.
-     *
-     * When overridden, return the amount of the [dragDistance] that has been consumed.
-     *
-     * Called after [onStart] and for every subsequent pointer movement, as long as the movement
-     * was enough to constitute a drag (the average movement on the x or y axis is not equal to 0).
-     *
-     * @param dragDistance The distance that has been dragged.  Reflects the average drag distance
-     * of all pointers.
-     */
-    fun onDrag(dragDistance: PxPosition) = PxPosition.Origin
-
-    /**
-     * Override to be notified when a drag has stopped.
-     *
-     * This is called once all pointers have stopped interacting with this DragGestureDetector.
-     *
-     * Only called after [onStart], followed by one or more calls to [onDrag].
-     */
-    fun onStop(velocity: PxPosition) {}
-}
-
-// TODO(shepshapard): Convert to functional component with effects once effects are ready.
-// TODO(shepshapard): Should this calculate the drag distance as the average of all fingers
-// (Shep thinks this is better), or should it only track the most recent finger to have
-// touched the screen over the detector (this is how Android currently does it)?
-/**
- * This gesture detector detects dragging in any direction.
- *
- * Dragging begins when the touch slop distance is surpassed in a supported direction
- * (see [DragObserver.onDrag]).  When dragging begins, [DragObserver.onStart] is called, followed
- * immediately by a call to [DragObserver.onDrag].  [DragObserver.onDrag] is then continuously
- * called whenever pointers have moved.  [DragObserver.onDrag] is called when the dragging ends due
- * to all of the pointers no longer interacting with the DragGestureDetector (for example, the last
- * finger has been lifted off of the DragGestureDetector).
- *
- * When multiple pointers are touching the detector, the drag distance is taken as the average of
- * all of the pointers.
- *
- * @param canDrag Set to limit the directions under which a drag can be started. Return true if you
- * want a drag to be started due to the touch slop being surpassed in given [Direction]
- */
-@Composable
-fun DragGestureDetector(
-    canDrag: ((Direction) -> Boolean)? = null,
-    dragObserver: DragObserver? = null,
-    children: @Composable() () -> Unit
-) {
-    val recognizer = +memo { DragGestureRecognizer() }
-    recognizer.canDrag = canDrag
-    // TODO(b/129784010): Consider also allowing onStart, onDrag, and onEnd to be set individually.
-    recognizer.dragObserver = dragObserver
-
-    +withDensity {
-        recognizer.touchSlop = TouchSlop.toIntPx()
-    }
-
-    PointerInputWrapper(pointerInputHandler = recognizer.pointerInputHandler) {
-        children()
-    }
-}
-
-internal class DragGestureRecognizer {
-    private val pointerTrackers: MutableMap<Int, PointerTrackingData> = mutableMapOf()
-    private var passedSlop = false
-    var touchSlop = 0.ipx
-
-    var canDrag: ((Direction) -> Boolean)? = null
-    var dragObserver: DragObserver? = null
-
-    val pointerInputHandler =
-        { changes: List<PointerInputChange>, pass: PointerEventPass ->
-
-            var changesToReturn = changes
-
-            if (pass == PointerEventPass.InitialDown) {
-                if (passedSlop) {
-                    // If we are passedSlop, we are actively dragging so we want to prevent any
-                    // children from reacting to any down change.
-                    changesToReturn = changesToReturn.map {
-                        if (it.changedToDown()) {
-                            it.consumeDownChange()
-                        } else {
-                            it
-                        }
-                    }
-                } else {
-                    // If we aren't passed slop, reset the tracking information given the multiple
-                    // passes that DragGestureDetector reacts to.
-                    pointerTrackers.forEach {
-                        it.value.dxForPass = 0f
-                        it.value.dyForPass = 0f
-                    }
-                }
-            }
-
-            if (pass == PointerEventPass.PostUp) {
-
-                // Handle up changes, which includes removing individual pointer VelocityTrackers
-                // and potentially calling onStop().
-                if (changesToReturn.any { it.changedToUpIgnoreConsumed() }) {
-
-                    var velocityTracker: VelocityTracker? = null
-
-                    changesToReturn.forEach {
-                        // This pointer is up (consumed or not), so we should stop tracking information
-                        // about it.  Get a reference for the velocity tracker in case this is the last
-                        // pointer and thus we are going to fling.
-                        if (it.changedToUp()) {
-                            velocityTracker = pointerTrackers.remove(it.id)?.velocityTracker
-                        } else if (it.changedToUpIgnoreConsumed()) {
-                            pointerTrackers.remove(it.id)
-                        }
-                    }
-
-                    if (changesToReturn.all { it.changedToUpIgnoreConsumed() } && passedSlop) {
-                        // If all of the fingers are up and we passedSlop, then we may need to call
-                        // onStop.
-                        passedSlop = false
-                        if (velocityTracker != null) {
-                            // If all of the pointers went up, and there is a VelocityTracker
-                            // (which means that at least one had an unconsumed up change), we
-                            // are responding to the change so consume all of the down changes, and
-                            // maybe fire off en event.
-
-                            changesToReturn = changesToReturn.map {
-                                it.consumeDownChange()
-                            }
-
-                            if (dragObserver != null) {
-                                val velocity = velocityTracker!!.calculateVelocity().pixelsPerSecond
-                                dragObserver!!.onStop(PxPosition(velocity.x, velocity.y))
-                            }
-                        }
-                    }
-                }
-
-                // For each new pointer that has been added, start tracking information about it.
-                if (changesToReturn.any { it.changedToDownIgnoreConsumed() }) {
-                    changesToReturn.forEach {
-                        // If a pointer has changed to down, we should start tracking information
-                        // about it.
-                        if (it.changedToDownIgnoreConsumed()) {
-                            pointerTrackers[it.id] = PointerTrackingData()
-                                .apply {
-                                    velocityTracker.addPosition(
-                                        it.current.timestamp!!,
-                                        it.current.position!!
-                                    )
-                                }
-                        }
-                    }
-                }
-            }
-
-            // This if block is run for both PostUp and PostDown to allow for the detector to
-            // respond to modified changes after ancestors may have modified them.  (This allows
-            // for things like dragging an ancestor scrolling container, while keeping a finger on
-            // a descendant scrolling container, and the descendant scrolling container keeping the
-            // descendant still.)
-            if (pass == PointerEventPass.PostUp || pass == PointerEventPass.PostDown) {
-
-                var (movedChanges, otherChanges) = changesToReturn.partition {
-                    it.current.down && !it.changedToDownIgnoreConsumed()
-                }
-
-                movedChanges.forEach {
-                    // TODO(shepshapard): handle the case that the pointerTrackingData is null,
-                    // either with an exception or a logged error, or something else.
-                    val pointerTracker: PointerTrackingData? = pointerTrackers[it.id]
-
-                    if (pointerTracker != null) {
-
-                        // Add information to the velocity tracker only during one pass.
-                        // TODO(shepshapard): VelocityTracker needs to be updated to not accept
-                        // position information, but rather vector information about movement.
-                        if (pass == PointerEventPass.PostUp) {
-                            pointerTracker.velocityTracker.addPosition(
-                                it.current.timestamp!!,
-                                it.current.position!!
-                            )
-                        }
-
-                        val dx = it.positionChange().x.value
-                        val dy = it.positionChange().y.value
-
-                        // If we aren't passed slop, calculate things related to slop, and start drag
-                        // if we do pass touch slop.
-                        if (!passedSlop) {
-                            // TODO(shepshapard): I believe the logic in this block could be simplified
-                            // to be much more clear.  Will need to revisit. The need to make
-                            // improvements may be rendered obsolete with upcoming changes however.
-
-                            val directionX = when {
-                                dx == 0f -> null
-                                dx < 0f -> Direction.LEFT
-                                else -> Direction.RIGHT
-                            }
-                            val directionY = when {
-                                dy == 0f -> null
-                                dy < 0f -> Direction.UP
-                                else -> Direction.DOWN
-                            }
-
-                            val canDragX =
-                                if (directionX != null) {
-                                    canDrag?.invoke(directionX) ?: true
-                                } else false
-                            val canDragY =
-                                if (directionY != null) {
-                                    canDrag?.invoke(directionY) ?: true
-                                } else false
-
-                            if (pass == PointerEventPass.PostUp) {
-                                pointerTracker.dxForPass = dx
-                                pointerTracker.dyForPass = dy
-                                pointerTracker.dxUnderSlop += dx
-                                pointerTracker.dyUnderSlop += dy
-                            } else {
-                                pointerTracker.dxUnderSlop += dx - pointerTracker.dxForPass
-                                pointerTracker.dyUnderSlop += dy - pointerTracker.dyForPass
-                            }
-
-                            val passedSlopX =
-                                canDragX && Math.abs(pointerTracker.dxUnderSlop) > touchSlop.value
-                            val passedSlopY =
-                                canDragY && Math.abs(pointerTracker.dyUnderSlop) > touchSlop.value
-
-                            if (passedSlopX || passedSlopY) {
-                                passedSlop = true
-                                dragObserver?.onStart()
-                            } else {
-                                if (!canDragX &&
-                                    ((directionX == Direction.LEFT &&
-                                            pointerTracker.dxUnderSlop < 0) ||
-                                            (directionX == Direction.RIGHT &&
-                                                    pointerTracker.dxUnderSlop > 0))
-                                ) {
-                                    pointerTracker.dxUnderSlop = 0f
-                                }
-                                if (!canDragY &&
-                                    ((directionY == Direction.LEFT &&
-                                            pointerTracker.dyUnderSlop < 0) ||
-                                            (directionY == Direction.DOWN &&
-                                                    pointerTracker.dyUnderSlop > 0))
-                                ) {
-                                    pointerTracker.dyUnderSlop = 0f
-                                }
-                            }
-                        }
-                    }
-                }
-
-                // At this point, check to see if we have passed touch slop, and if we have, we may
-                // be calling onDrag and updating change information on the PointerInputChanges.
-                if (passedSlop) {
-
-                    var totalDx = 0f
-                    var totalDy = 0f
-
-                    movedChanges.forEach {
-                        totalDx += it.positionChange().x.value
-                        totalDy += it.positionChange().y.value
-                    }
-
-                    if (totalDx != 0f || totalDy != 0f) {
-                        dragObserver?.run {
-                            val (consumedDx, consumedDy) = onDrag(
-                                PxPosition(
-                                    (totalDx / changesToReturn.size).px,
-                                    (totalDy / changesToReturn.size).px
-                                )
-                            )
-                            movedChanges = movedChanges.map {
-                                it.consumePositionChange(consumedDx, consumedDy)
-                            }
-                        }
-                    }
-                }
-
-                changesToReturn = movedChanges + otherChanges
-            }
-
-            changesToReturn
-        }
-
-    internal data class PointerTrackingData(
-        val velocityTracker: VelocityTracker = VelocityTracker(),
-        var dxUnderSlop: Float = 0f,
-        var dyUnderSlop: Float = 0f,
-        var dxForPass: Float = 0f,
-        var dyForPass: Float = 0f
-    )
-}
\ No newline at end of file
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/LongPressGestureDetector.kt b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/LongPressGestureDetector.kt
index d269572..106b7db 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/LongPressGestureDetector.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/LongPressGestureDetector.kt
@@ -20,7 +20,6 @@
 import androidx.ui.core.PointerInputChange
 import androidx.ui.core.anyPositionChangeConsumed
 import androidx.ui.core.changedToDown
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.ambient
 import androidx.compose.memo
@@ -36,29 +35,35 @@
 import kotlinx.coroutines.Job
 import kotlin.coroutines.CoroutineContext
 
-// TODO(b/137569202): This bug tracks the note below regarding the need to eventually improve LongPressGestureDetector.
+// TODO(b/137569202): This bug tracks the note below regarding the need to eventually
+//  improve LongPressGestureDetector.
+// TODO(b/139020678): Probably has shared functionality with other press based detectors.
 /**
  * Responds to a pointer being "down" for an extended amount of time.
  *
- * Note: this is likely a temporary, naive, and flawed approach. It is not necessarily guaranteed to interoperate well
- * with forthcoming behavior related to disambiguation between multi-tap (double tap, triple tap) and tap.
+ * Note: this is likely a temporary, naive, and flawed approach. It is not necessarily guaranteed
+ * to interoperate well with forthcoming behavior related to disambiguation between multi-tap
+ * (double tap, triple tap) and tap.
  */
 @Composable
 fun LongPressGestureDetector(
     onLongPress: (PxPosition) -> Unit,
     children: @Composable() () -> Unit
 ) {
+    val coroutineContext = +ambient(CoroutineContextAmbient)
     val recognizer =
-        +memo { LongPressGestureRecognizer(onLongPress, +ambient(CoroutineContextAmbient)) }
+        +memo { LongPressGestureRecognizer(coroutineContext) }
+    recognizer.onLongPress = onLongPress
+
     PointerInputWrapper(pointerInputHandler = recognizer.pointerInputHandler) {
         children()
     }
 }
 
 internal class LongPressGestureRecognizer(
-    val onLongPress: (PxPosition) -> Unit,
     coroutineContext: CoroutineContext
 ) {
+    lateinit var onLongPress: (PxPosition) -> Unit
 
     private enum class State {
         Idle, Primed, Fired
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/PressIndicatorGestureDetector.kt b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/PressIndicatorGestureDetector.kt
index 423b917..fbea4ed 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/PressIndicatorGestureDetector.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/PressIndicatorGestureDetector.kt
@@ -21,16 +21,14 @@
 import androidx.ui.core.PxPosition
 import androidx.ui.core.anyPositionChangeConsumed
 import androidx.ui.core.changedToDown
-import androidx.ui.core.changedToDownIgnoreConsumed
-import androidx.ui.core.changedToUpIgnoreConsumed
 import androidx.ui.core.consumeDownChange
 import androidx.ui.engine.geometry.Offset
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.compose.memo
 import androidx.compose.unaryPlus
 import androidx.ui.core.PointerInputWrapper
+import androidx.ui.core.changedToUpIgnoreConsumed
 
 /**
  * This gesture detector has callbacks for when a press gesture starts and ends for the purposes of
@@ -48,6 +46,7 @@
  *
  * This gesture detector always consumes the down change during the [PointerEventPass.PostUp] pass.
  */
+// TODO(b/139020678): Probably has shared functionality with other press based detectors.
 @Composable
 fun PressIndicatorGestureDetector(
     onStart: ((PxPosition) -> Unit)? = null,
@@ -59,6 +58,7 @@
     recognizer.onStart = onStart
     recognizer.onStop = onStop
     recognizer.onCancel = onCancel
+
     PointerInputWrapper(pointerInputHandler = recognizer.pointerInputHandler) {
         children()
     }
@@ -92,50 +92,55 @@
      */
     var onCancel: (() -> Unit)? = null
 
-    private var pointerCount = 0
     private var started = false
 
     val pointerInputHandler =
         { changes: List<PointerInputChange>, pass: PointerEventPass ->
-            changes.map { processChange(it, pass) }
-        }
 
-    private fun processChange(
-        pointerInputChange: PointerInputChange,
-        pass: PointerEventPass
-    ): PointerInputChange {
-        var change = pointerInputChange
+            var internalChanges = changes
 
-        if (pass == PointerEventPass.InitialDown && change.changedToDownIgnoreConsumed()) {
-            pointerCount++
-        }
-
-        if (pass == PointerEventPass.PostUp &&
-            pointerCount == 1
-        ) {
-            if (change.changedToDown()) {
-                started = true
-                onStart?.invoke(change.current.position!!)
-                change = change.consumeDownChange()
+            if (pass == PointerEventPass.InitialDown && started) {
+                internalChanges = internalChanges.map {
+                    if (it.changedToDown()) {
+                        it.consumeDownChange()
+                    } else {
+                        it
+                    }
+                }
             }
-            if (started && change.changedToUpIgnoreConsumed()) {
+
+            if (pass == PointerEventPass.PostUp) {
+
+                if (!started && internalChanges.all { it.changedToDown() }) {
+                    // If we have not yet started and all of the changes changed to down, we are
+                    // starting.
+                    started = true
+                    onStart?.invoke(internalChanges.first().current.position!!)
+                    internalChanges = internalChanges.map { it.consumeDownChange() }
+                } else if (started) {
+                    if (internalChanges.all { it.changedToUpIgnoreConsumed() }) {
+                        // If we have started and all of the changes changed to up, we are stopping.
+                        started = false
+                        onStop?.invoke()
+                    }
+                }
+
+                if (started) {
+                    internalChanges = internalChanges.map { it.consumeDownChange() }
+                }
+            }
+
+            if (pass == PointerEventPass.PostDown &&
+                started &&
+                internalChanges
+                    .any { it.anyPositionChangeConsumed() }
+            ) {
+                // On the final pass, if we have started and any of the changes had consumed
+                // position changes, we cancel.
                 started = false
-                onStop?.invoke()
+                onCancel?.invoke()
             }
-        }
 
-        if (pass == PointerEventPass.PostDown && started && change.anyPositionChangeConsumed()) {
-            started = false
-            onCancel?.invoke()
+            internalChanges
         }
-
-        if (pass == PointerEventPass.PostDown && change.changedToUpIgnoreConsumed()) {
-            pointerCount--
-            if (pointerCount == 0) {
-                started = false
-            }
-        }
-
-        return change
-    }
 }
\ No newline at end of file
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/PressReleasedGestureDetector.kt b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/PressReleasedGestureDetector.kt
index 99a0daa..40e7a4d 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/PressReleasedGestureDetector.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/PressReleasedGestureDetector.kt
@@ -20,11 +20,8 @@
 import androidx.ui.core.PointerInputChange
 import androidx.ui.core.anyPositionChangeConsumed
 import androidx.ui.core.changedToDown
-import androidx.ui.core.changedToDownIgnoreConsumed
 import androidx.ui.core.changedToUp
-import androidx.ui.core.changedToUpIgnoreConsumed
 import androidx.ui.core.consumeDownChange
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.compose.memo
@@ -32,15 +29,16 @@
 import androidx.ui.core.PointerInputWrapper
 
 /**
- * This gesture detector has a callback for when a press gesture being released for the purposes of
- * firing an event in response to something like a button being pressed.
+ * This gesture detector fires a callback when a traditional press is being released.  This is
+ * generally the same thing as "onTap" or "onClick".
  *
  * More specifically, it will call [onRelease] if:
- * - The first [PointerInputChange] it receives during the [PointerEventPass.PostUp] pass has
- *   an unconsumed down change.
- * - The last [PointerInputChange]  it receives during the [PointerEventPass.PostUp] pass has
+ * - All of the first [PointerInputChange]s it receives during the [PointerEventPass.PostUp] pass
+ *   have unconsumed down changes, thus representing new set of pointers, none of which have had
+ *   their down events consumed.
+ * - The last [PointerInputChange] it receives during the [PointerEventPass.PostUp] pass has
  *   an unconsumed up change.
- * - And while it has at least one pointer touching it, no [PointerInputChange] has had any
+ * - While it has at least one pointer touching it, no [PointerInputChange] has had any
  *   movement consumed (as that would indicate that something in the heirarchy moved and this a
  *   press should be cancelled.
  *
@@ -48,6 +46,7 @@
  * [PointerEventPass.PostUp] pass if it has not already been consumed. That behavior can be changed
  * via [consumeDownOnStart].
  */
+// TODO(b/139020678): Probably has shared functionality with other press based detectors.
 @Composable
 fun PressReleasedGestureDetector(
     onRelease: (() -> Unit)? = null,
@@ -57,6 +56,7 @@
     val recognizer = +memo { PressReleaseGestureRecognizer() }
     recognizer.onRelease = onRelease
     recognizer.consumeDownOnStart = consumeDownOnStart
+
     PointerInputWrapper(pointerInputHandler = recognizer.pointerInputHandler) {
         children()
     }
@@ -74,48 +74,43 @@
      */
     var consumeDownOnStart = true
 
-    private var pointerCount = 0
-    private var shouldRespondToUp = false
+    /**
+     * True when we are primed to call [onRelease] and may be consuming all down changes.
+     */
+    private var active = false
 
     val pointerInputHandler =
         { changes: List<PointerInputChange>, pass: PointerEventPass ->
-            changes.map { processChange(it, pass) }
-        }
 
-    private fun processChange(
-        pointerInputChange: PointerInputChange,
-        pass: PointerEventPass
-    ): PointerInputChange {
-        var change = pointerInputChange
+            var internalChanges = changes
 
-        if (pass == PointerEventPass.InitialDown && change.changedToDownIgnoreConsumed()) {
-            pointerCount++
-        }
+            if (pass == PointerEventPass.PostUp) {
 
-        if (pass == PointerEventPass.PostUp && pointerCount == 1) {
-            if (change.changedToDown()) {
-                shouldRespondToUp = true
-                if (consumeDownOnStart) {
-                    change = change.consumeDownChange()
+                if (internalChanges.all { it.changedToDown() }) {
+                    // If we have not yet started and all of the changes changed to down, we are
+                    // starting.
+                    active = true
+                } else if (active && internalChanges.all { it.changedToUp() }) {
+                    // If we have started and all of the changes changed to up, we are stopping.
+                    active = false
+                    internalChanges = internalChanges.map { it.consumeDownChange() }
+                    onRelease?.invoke()
+                }
+
+                if (active && consumeDownOnStart) {
+                    // If we have started, we should consume the down change on all changes.
+                    internalChanges = internalChanges.map { it.consumeDownChange() }
                 }
             }
-            if (shouldRespondToUp && change.changedToUp()) {
-                onRelease?.invoke()
-                change = change.consumeDownChange()
+
+            if (pass == PointerEventPass.PostDown && active &&
+                internalChanges.any { it.anyPositionChangeConsumed() }
+            ) {
+                // On the final pass, if we have started and any of the changes had consumed
+                // position changes, we cancel.
+                active = false
             }
-        }
 
-        if (pass == PointerEventPass.PostDown && change.anyPositionChangeConsumed()) {
-            shouldRespondToUp = false
+            internalChanges
         }
-
-        if (pass == PointerEventPass.PostDown && change.changedToUpIgnoreConsumed()) {
-            pointerCount--
-            if (pointerCount == 0) {
-                shouldRespondToUp = false
-            }
-        }
-
-        return change
-    }
 }
\ No newline at end of file
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/RawDragGestureDetector.kt b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/RawDragGestureDetector.kt
new file mode 100644
index 0000000..26a0800
--- /dev/null
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/RawDragGestureDetector.kt
@@ -0,0 +1,285 @@
+/*
+ * Copyright 2019 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.ui.core.gesture
+
+import androidx.compose.Composable
+import androidx.compose.memo
+import androidx.compose.unaryPlus
+import androidx.ui.core.PointerEventPass
+import androidx.ui.core.PointerInputChange
+import androidx.ui.core.PxPosition
+import androidx.ui.core.changedToDown
+import androidx.ui.core.changedToDownIgnoreConsumed
+import androidx.ui.core.changedToUp
+import androidx.ui.core.changedToUpIgnoreConsumed
+import androidx.ui.core.consumeDownChange
+import androidx.ui.core.consumePositionChange
+import androidx.ui.core.gesture.util.VelocityTracker
+import androidx.ui.core.positionChange
+import androidx.ui.core.px
+import androidx.compose.composer
+import androidx.ui.core.PointerInputWrapper
+
+interface DragObserver {
+
+    /**
+     * Override to be notified when a drag has started.
+     *
+     * This will be called as soon as the DragGestureDetector is allowed to start (canStartDragging is null or
+     * returns true) and the average distance the pointers have moved
+     * are not 0 on both the x and y axes.
+     *
+     * @see onDrag
+     * @see onStop
+     */
+    fun onStart() {}
+
+    /**
+     * Override to be notified when a distance has been dragged.
+     *
+     * When overridden, return the amount of the [dragDistance] that has been consumed.
+     *
+     * Called immediately after [onStart] and for every subsequent pointer movement, as long as the
+     * movement was enough to constitute a drag (the average movement on the x or y axis is not
+     * equal to 0).
+     *
+     * Note: This may be called multiple times in a single pass and the values should be accumulated
+     * for each call.
+     *
+     * @param dragDistance The distance that has been dragged.  Reflects the average drag distance
+     * of all pointers.
+     */
+    fun onDrag(dragDistance: PxPosition) = PxPosition.Origin
+
+    /**
+     * Override to be notified when a drag has stopped.
+     *
+     * This is called once all pointers have stopped interacting with this DragGestureDetector.
+     *
+     * Only called if the last call between [onStart] and [onStop] was [onStart].
+     */
+    fun onStop(velocity: PxPosition) {}
+}
+
+// TODO(shepshapard): Convert to functional component with effects once effects are ready.
+// TODO(shepshapard): Should this calculate the drag distance as the average of all fingers
+//  (Shep thinks this is better), or should it only track the most recent finger to have
+//  touched the screen over the detector (this is how Android currently does it)?
+// TODO(b/139020678): Probably has shared functionality with other movement based detectors.
+/**
+ * This gesture detector detects dragging in any direction.
+ *
+ * Note: By default, this gesture detector only waits for a single pointer to have moved to start
+ * dragging.  It is extremely likely that you don't want to use this gesture detector directly, but
+ * instead use a drag gesture detector that does wait for some other condition to have occurred
+ * (such as [TouchSlopDragGestureDetector] which waits for a single pointer to have passed touch
+ * slop before dragging starts).
+ *
+ * Dragging begins when the a single pointer has moved and either [canStartDragging] is null or
+ * returns true.  When dragging begins, [DragObserver.onStart] is called.  [DragObserver.onDrag] is
+ * then continuously called whenever the average movement of all pointers has movement along the x
+ * or y axis.  [DragObserver.onStop] is called when the dragging ends due to all of the pointers no
+ * longer interacting with the DragGestureDetector (for example, the last pointer has been lifted
+ * off of the DragGestureDetector).
+ *
+ * When multiple pointers are touching the detector, the drag distance is taken as the average of
+ * all of the pointers.
+ *
+ * @param dragObserver The callback interface to report all events related to dragging.
+ * @param canStartDragging If set, Before dragging is started ([DragObserver.onStart] is called),
+ *                         canStartDragging is called to check to see if it is allowed to start.
+ */
+
+// TODO(b/129784010): Consider also allowing onStart, onDrag, and onStop to be set individually (instead of all being
+//  set via DragObserver).
+@Composable
+fun RawDragGestureDetector(
+    dragObserver: DragObserver,
+    canStartDragging: (() -> Boolean)? = null,
+    children: @Composable() () -> Unit
+) {
+    val recognizer = +memo {
+        RawDragGestureRecognizer()
+    }
+
+    recognizer.dragObserver = dragObserver
+    recognizer.canStartDragging = canStartDragging
+
+    PointerInputWrapper(pointerInputHandler = recognizer.pointerInputHandler) {
+        children()
+    }
+}
+
+internal class RawDragGestureRecognizer {
+    private val velocityTrackers: MutableMap<Int, VelocityTracker> = mutableMapOf()
+    private var started = false
+    var canStartDragging: (() -> Boolean)? = null
+    lateinit var dragObserver: DragObserver
+
+    val pointerInputHandler =
+        { changes: List<PointerInputChange>, pass: PointerEventPass ->
+
+            var changesToReturn = changes
+
+            if (pass == PointerEventPass.InitialDown) {
+
+                if (started) {
+                    // If we are have started we want to prevent any descendants from reacting to
+                    // any down change.
+                    changesToReturn = changesToReturn.map {
+                        if (it.changedToDown()) {
+                            it.consumeDownChange()
+                        } else {
+                            it
+                        }
+                    }
+                }
+            }
+
+            if (pass == PointerEventPass.PostUp) {
+
+                // Handle up changes, which includes removing individual pointer VelocityTrackers
+                // and potentially calling onStop().
+                if (changesToReturn.any { it.changedToUpIgnoreConsumed() }) {
+
+                    var velocityTracker: VelocityTracker? = null
+
+                    changesToReturn.forEach {
+                        // This pointer is up (consumed or not), so we should stop tracking
+                        // information about it.  Get a reference for the velocity tracker in case
+                        // this is the last pointer and thus we are going to fling.
+                        if (it.changedToUp()) {
+                            velocityTracker = velocityTrackers.remove(it.id)
+                        } else if (it.changedToUpIgnoreConsumed()) {
+                            velocityTrackers.remove(it.id)
+                        }
+                    }
+
+                    if (changesToReturn.all { it.changedToUpIgnoreConsumed() }) {
+                        // All of the pointers are up, so reset and call onStop.  If we have a
+                        // velocityTracker at this point, that means at least one of the up events
+                        // was not consumed so we should send velocity for flinging.
+                        if (started) {
+                            val velocity: PxPosition? =
+                                if (velocityTracker != null) {
+                                    changesToReturn = changesToReturn.map {
+                                        it.consumeDownChange()
+                                    }
+                                    velocityTracker!!.calculateVelocity().pixelsPerSecond
+                                } else {
+                                    null
+                                }
+                            started = false
+                            dragObserver.onStop(velocity ?: PxPosition.Origin)
+                        }
+                    }
+                }
+
+                // For each new pointer that has been added, start tracking information about it.
+                if (changesToReturn.any { it.changedToDownIgnoreConsumed() }) {
+                    changesToReturn.forEach {
+                        // If a pointer has changed to down, we should start tracking information
+                        // about it.
+                        if (it.changedToDownIgnoreConsumed()) {
+                            velocityTrackers[it.id] = VelocityTracker()
+                                .apply {
+                                    addPosition(
+                                        it.current.timestamp!!,
+                                        it.current.position!!
+                                    )
+                                }
+                        }
+                    }
+                }
+            }
+
+            // This if block is run for both PostUp and PostDown to allow for the detector to
+            // respond to modified changes after ancestors may have modified them.  (This allows
+            // for things like dragging an ancestor scrolling container, while keeping a pointer on
+            // a descendant scrolling container, and the descendant scrolling container keeping the
+            // descendant still.)
+            if (pass == PointerEventPass.PostUp || pass == PointerEventPass.PostDown) {
+
+                var (movedChanges, otherChanges) = changesToReturn.partition {
+                    it.current.down && !it.changedToDownIgnoreConsumed()
+                }
+
+                movedChanges.forEach {
+                    // TODO(shepshapard): handle the case that the pointerTrackingData is null,
+                    // either with an exception or a logged error, or something else.
+                    val velocityTracker = velocityTrackers[it.id]
+
+                    if (velocityTracker != null) {
+
+                        // Add information to the velocity tracker only during one pass.
+                        // TODO(shepshapard): VelocityTracker needs to be updated to not accept
+                        // position information, but rather vector information about movement.
+                        if (pass == PointerEventPass.PostUp) {
+                            velocityTracker.addPosition(
+                                it.current.timestamp!!,
+                                it.current.position!!
+                            )
+                        }
+                    }
+                }
+
+                // Check to see if we are already started so we don't have to call canStartDragging again.
+                val canStart = !started && canStartDragging?.invoke() ?: true
+
+                // At this point, check to see if we have started, and if we have, we may
+                // be calling onDrag and updating change information on the PointerInputChanges.
+                if (started || canStart) {
+
+                    var totalDx = 0f
+                    var totalDy = 0f
+
+                    movedChanges.forEach {
+                        totalDx += it.positionChange().x.value
+                        totalDy += it.positionChange().y.value
+                    }
+
+                    if (totalDx != 0f || totalDy != 0f) {
+
+                        // At this point, if we have not started, check to see if we should start
+                        // and if we should, update our state and call onStart().
+                        if (!started && canStart) {
+                            started = true
+                            dragObserver.onStart()
+                        }
+
+                        if (started) {
+
+                            val (consumedDx, consumedDy) = dragObserver.onDrag(
+                                PxPosition(
+                                    (totalDx / changesToReturn.size).px,
+                                    (totalDy / changesToReturn.size).px
+                                )
+                            )
+
+                            movedChanges = movedChanges.map {
+                                it.consumePositionChange(consumedDx, consumedDy)
+                            }
+                        }
+                    }
+                }
+
+                changesToReturn = movedChanges + otherChanges
+            }
+
+            changesToReturn
+        }
+}
\ No newline at end of file
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/TouchSlopDragGestureDetector.kt b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/TouchSlopDragGestureDetector.kt
new file mode 100644
index 0000000..c6fa9e0
--- /dev/null
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/TouchSlopDragGestureDetector.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2019 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.ui.core.gesture
+
+import androidx.compose.Composable
+import androidx.compose.memo
+import androidx.compose.unaryPlus
+import androidx.ui.core.Direction
+import androidx.ui.core.PxPosition
+import androidx.compose.composer
+
+// TODO(shepshapard): Convert to functional component with effects once effects are ready.
+/**
+ * This gesture detector detects dragging in any direction.
+ *
+ * Dragging begins when the touch slop distance (currently defined by [TouchSlop]) is
+ * surpassed in a supported direction (see [DragObserver.onDrag]).  When dragging begins,
+ * [DragObserver.onStart] is called, followed immediately by a call to [DragObserver.onDrag].
+ * [DragObserver.onDrag] is then continuously called whenever pointers have moved.
+ * [DragObserver.onDrag] is called when the dragging ends due to all of the pointers no longer
+ * interacting with the DragGestureDetector (for example, the last finger has been lifted off
+ * of the DragGestureDetector).
+ *
+ * When multiple pointers are touching the detector, the drag distance is taken as the average of
+ * all of the pointers.
+ *
+ * @param canDrag Set to limit the directions under which touch slop can be exceeded. Return true
+ * if you want a drag to be started due to the touch slop being surpassed in the given [Direction].
+ * If [canDrag] is not provided, touch slop will be able to be exceeded in all directions.
+ * @param dragObserver The callback interface to report all events related to dragging.
+ */
+@Composable
+fun TouchSlopDragGestureDetector(
+    dragObserver: DragObserver,
+    canDrag: ((Direction) -> Boolean)? = null,
+    children: @Composable() () -> Unit
+) {
+    val canStartDrag = +memo { Single(false) }
+
+    val internalDragObserver: DragObserver =
+        +memo(dragObserver) {
+            object : DragObserver {
+
+                override fun onStart() {
+                    dragObserver.onStart()
+                }
+
+                override fun onDrag(dragDistance: PxPosition): PxPosition {
+                    return dragObserver.onDrag(dragDistance)
+                }
+
+                override fun onStop(velocity: PxPosition) {
+                    dragObserver.onStop(velocity)
+                    canStartDrag.value = false
+                }
+            }
+        }
+
+    RawDragGestureDetector(internalDragObserver, canStartDrag::value::get) {
+        TouchSlopExceededGestureDetector({ canStartDrag.value = true }, canDrag) {
+            children()
+        }
+    }
+}
+
+
+internal data class Single<T>(var value: T)
\ No newline at end of file
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/TouchSlopExceededGestureDetector.kt b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/TouchSlopExceededGestureDetector.kt
new file mode 100644
index 0000000..f490466
--- /dev/null
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/TouchSlopExceededGestureDetector.kt
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2019 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.ui.core.gesture
+
+import androidx.compose.Composable
+import androidx.compose.memo
+import androidx.compose.unaryPlus
+import androidx.ui.core.Direction
+import androidx.ui.core.PointerEventPass
+import androidx.ui.core.PointerInputChange
+import androidx.ui.core.changedToDownIgnoreConsumed
+import androidx.ui.core.changedToUpIgnoreConsumed
+import androidx.ui.core.positionChange
+import androidx.ui.core.withDensity
+import androidx.ui.core.PointerInputWrapper
+import androidx.compose.composer
+import androidx.ui.core.IntPx
+
+// TODO(shepshapard): Convert to functional component with effects once effects are ready.
+/**
+ * This gesture filter detects when at least one pointer has moved far enough to exceed touch slop.
+ *
+ * The value of touch slop is currently defined internally as the constant [TouchSlop].
+ *
+ * @param onTouchSlopExceeded Lamba that will be called when touch slop by at least 1 pointer has
+ * been exceeded in a supported direction. See [canDrag].
+ * @param canDrag Set to limit the directions under which touch slop can be exceeded. Return true
+ * if you want a drag to be started due to the touch slop being surpassed in the given [Direction].
+ * If [canDrag] is not provided, touch slop will be able to be exceeded in all directions.
+ */
+@Composable
+fun TouchSlopExceededGestureDetector(
+    onTouchSlopExceeded: () -> Unit,
+    canDrag: ((Direction) -> Boolean)? = null,
+    children: @Composable() () -> Unit
+) {
+    val touchSlop = +withDensity { TouchSlop.toIntPx() }
+    val recognizer = +memo { TouchSlopExceededGestureRecognizer(touchSlop) }
+
+    recognizer.canDrag = canDrag
+    recognizer.onTouchSlopExceeded = onTouchSlopExceeded
+
+    PointerInputWrapper(pointerInputHandler = recognizer::onPointerInputChanges) {
+        children()
+    }
+}
+
+internal class TouchSlopExceededGestureRecognizer(private val touchSlop: IntPx) {
+    private val pointerTrackers: MutableMap<Int, PointerTrackingData> = mutableMapOf()
+    private var passedSlop = false
+
+    var canDrag: ((Direction) -> Boolean)? = null
+    var onTouchSlopExceeded: () -> Unit = {}
+
+    fun onPointerInputChanges(
+        changes: List<PointerInputChange>,
+        pass: PointerEventPass
+    ): List<PointerInputChange> {
+        if (pass == PointerEventPass.PostUp) {
+            changes.forEach {
+                if (it.changedToUpIgnoreConsumed()) {
+                    pointerTrackers.remove(it.id)
+                } else if (it.changedToDownIgnoreConsumed()) {
+                    pointerTrackers[it.id] = PointerTrackingData()
+                }
+            }
+
+            if (!passedSlop) {
+                pointerTrackers.forEach {
+                    it.value.dxForPass = 0f
+                    it.value.dyForPass = 0f
+                }
+            }
+        }
+
+        if (!passedSlop &&
+            (pass == PointerEventPass.PostUp || pass == PointerEventPass.PostDown)
+        ) {
+
+            changes.filter { it.current.down && !it.changedToDownIgnoreConsumed() }.forEach {
+
+                if (!passedSlop) {
+
+                    // TODO(shepshapard): handle the case that the pointerTrackingData is null,
+                    //   either with an exception or a logged error, or something else. It should
+                    //   only ever be able to be null at this point if we received a "move" change
+                    //   for a pointer before we received an change that the pointer became "down".
+                    val pointerTracker: PointerTrackingData = pointerTrackers[it.id]!!
+
+                    val positionChanged = it.positionChange()
+                    val dx = positionChanged.x.value
+                    val dy = positionChanged.y.value
+
+                    // TODO(shepshapard): I believe the logic in this block could be simplified
+                    //   to be much more clear.  Will need to revisit. The need to make
+                    //   improvements may be rendered obsolete with upcoming changes however.
+
+                    val directionX = when {
+                        dx == 0f -> null
+                        dx < 0f -> Direction.LEFT
+                        else -> Direction.RIGHT
+                    }
+                    val directionY = when {
+                        dy == 0f -> null
+                        dy < 0f -> Direction.UP
+                        else -> Direction.DOWN
+                    }
+
+                    val internalCanDrag = canDrag
+
+                    val canDragX =
+                        directionX != null &&
+                                (internalCanDrag == null || internalCanDrag.invoke(directionX))
+                    val canDragY =
+                        directionY != null &&
+                                (internalCanDrag == null || internalCanDrag.invoke(directionY))
+
+                    if (pass == PointerEventPass.PostUp) {
+                        pointerTracker.dxForPass = dx
+                        pointerTracker.dyForPass = dy
+                        pointerTracker.dxUnderSlop += dx
+                        pointerTracker.dyUnderSlop += dy
+                    } else {
+                        pointerTracker.dxUnderSlop += dx - pointerTracker.dxForPass
+                        pointerTracker.dyUnderSlop += dy - pointerTracker.dyForPass
+                    }
+
+                    val passedSlopX =
+                        canDragX && Math.abs(pointerTracker.dxUnderSlop) > touchSlop.value
+                    val passedSlopY =
+                        canDragY && Math.abs(pointerTracker.dyUnderSlop) > touchSlop.value
+
+                    if (passedSlopX || passedSlopY) {
+                        passedSlop = true
+                        onTouchSlopExceeded.invoke()
+                    } else {
+                        if (!canDragX &&
+                            ((directionX == Direction.LEFT &&
+                                    pointerTracker.dxUnderSlop < 0) ||
+                                    (directionX == Direction.RIGHT &&
+                                            pointerTracker.dxUnderSlop > 0))
+                        ) {
+                            pointerTracker.dxUnderSlop = 0f
+                        }
+                        if (!canDragY &&
+                            ((directionY == Direction.LEFT &&
+                                    pointerTracker.dyUnderSlop < 0) ||
+                                    (directionY == Direction.DOWN &&
+                                            pointerTracker.dyUnderSlop > 0))
+                        ) {
+                            pointerTracker.dyUnderSlop = 0f
+                        }
+                    }
+                }
+            }
+        }
+
+        if (passedSlop &&
+            pass == PointerEventPass.PostDown &&
+            changes.all { it.changedToUpIgnoreConsumed() }
+        ) {
+            passedSlop = false
+        }
+
+        return changes
+    }
+
+    internal data class PointerTrackingData(
+        var dxUnderSlop: Float = 0f,
+        var dyUnderSlop: Float = 0f,
+        var dxForPass: Float = 0f,
+        var dyForPass: Float = 0f
+    )
+}
\ No newline at end of file
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/selection/SelectionContainer.kt b/ui/ui-framework/src/main/java/androidx/ui/core/selection/SelectionContainer.kt
index 6dfb42c..a4e2b97 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/selection/SelectionContainer.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/selection/SelectionContainer.kt
@@ -16,7 +16,6 @@
 
 package androidx.ui.core.selection
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.compose.memo
@@ -25,7 +24,7 @@
 import androidx.ui.core.IntPx
 import androidx.ui.core.Layout
 import androidx.ui.core.OnPositioned
-import androidx.ui.core.gesture.DragGestureDetector
+import androidx.ui.core.gesture.TouchSlopDragGestureDetector
 import androidx.ui.core.gesture.PressIndicatorGestureDetector
 import androidx.ui.core.ipx
 import androidx.ui.core.round
@@ -65,43 +64,35 @@
                     children()
                 }
             }
-            Layout(children = content, layoutBlock = { measurables, constraints ->
+            Layout(content) { measurables, constraints ->
                 val placeable = measurables.firstOrNull()?.measure(constraints)
                 val width = placeable?.width ?: constraints.minWidth
                 val height = placeable?.height ?: constraints.minHeight
                 layout(width, height) {
                     placeable?.place(0.ipx, 0.ipx)
                 }
-            })
+            }
         }
         val startHandle = @Composable {
-            DragGestureDetector(
-                canDrag = { true },
+            TouchSlopDragGestureDetector(
                 dragObserver = manager.handleDragObserver(dragStartHandle = true)
             ) {
-                Layout(
-                    children = { LeftPointingSelectionHandle() },
-                    layoutBlock = { _, constraints ->
-                        layout(constraints.minWidth, constraints.minHeight) {}
-                    })
+                Layout(children = { LeftPointingSelectionHandle() }) { _, constraints ->
+                    layout(constraints.minWidth, constraints.minHeight) {}
+                }
             }
         }
         val endHandle = @Composable {
-            DragGestureDetector(
-                canDrag = { true },
+            TouchSlopDragGestureDetector(
                 dragObserver = manager.handleDragObserver(dragStartHandle = false)
             ) {
-                Layout(
-                    children = { RightPointingSelectionHandle() },
-                    layoutBlock = { _, constraints ->
-                        layout(constraints.minWidth, constraints.minHeight) {}
-                    })
+                Layout(children = { RightPointingSelectionHandle() }) { _, constraints ->
+                    layout(constraints.minWidth, constraints.minHeight) {}
+                }
             }
         }
         @Suppress("USELESS_CAST")
-        (Layout(
-        childrenArray = arrayOf(content, startHandle, endHandle),
-        layoutBlock = { measurables, constraints ->
+        Layout(content, startHandle, endHandle) { measurables, constraints ->
             val placeable = measurables[0].measure(constraints)
             val width = placeable.width
             val height = placeable.height
@@ -137,6 +128,6 @@
                     end.place(endOffset.x, endOffset.y)
                 }
             }
-        }))
+        }
     }
 }
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/selection/SelectionMode.kt b/ui/ui-framework/src/main/java/androidx/ui/core/selection/SelectionMode.kt
index b405cb2..ba90523 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/selection/SelectionMode.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/selection/SelectionMode.kt
@@ -18,7 +18,7 @@
 
 import androidx.ui.core.PxPosition
 import androidx.ui.core.px
-import androidx.ui.text.TextPainter
+import androidx.ui.text.TextDelegate
 
 /**
  * The enum class allows user to decide the selection mode.
@@ -31,14 +31,14 @@
      */
     Vertical {
         override fun isSelected(
-            textPainter: TextPainter,
+            textDelegate: TextDelegate,
             start: PxPosition,
             end: PxPosition
         ): Boolean {
             val top = 0.px
-            val bottom = textPainter.height.px
+            val bottom = textDelegate.height.px
             val left = 0.px
-            val right = textPainter.width.px
+            val right = textDelegate.width.px
 
             // When the end of the selection is above the top of the widget, the widget is outside
             // of the selection range.
@@ -67,14 +67,14 @@
      */
     Horizontal {
         override fun isSelected(
-            textPainter: TextPainter,
+            textDelegate: TextDelegate,
             start: PxPosition,
             end: PxPosition
         ): Boolean {
             val top = 0.px
-            val bottom = textPainter.height.px
+            val bottom = textDelegate.height.px
             val left = 0.px
-            val right = textPainter.width.px
+            val right = textDelegate.width.px
 
             // When the end of the selection is on the left of the widget, the widget is outside of
             // the selection range.
@@ -97,7 +97,7 @@
     };
 
     internal abstract fun isSelected(
-        textPainter: TextPainter,
+        textDelegate: TextDelegate,
         start: PxPosition,
         end: PxPosition
     ): Boolean
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/selection/TextSelectionProcessor.kt b/ui/ui-framework/src/main/java/androidx/ui/core/selection/TextSelectionProcessor.kt
index 23419ed..6fa8887 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/selection/TextSelectionProcessor.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/selection/TextSelectionProcessor.kt
@@ -19,7 +19,7 @@
 import androidx.ui.core.PxPosition
 import androidx.ui.core.px
 import androidx.ui.text.TextSelection
-import androidx.ui.text.TextPainter
+import androidx.ui.text.TextDelegate
 import kotlin.math.max
 
 /**
@@ -34,8 +34,8 @@
     /** The lambda contains certain behavior when selection changes. Currently this is for changing
      * the selection used for drawing in Text widget. */
     var onSelectionChange: (TextSelection?) -> Unit = {},
-    /** The TextPainter object from Text widget. */
-    val textPainter: TextPainter
+    /** The TextDelegate object from Text widget. */
+    val textDelegate: TextDelegate
 ) {
     /**
      * The coordinates of the graphical position for selection start character offset.
@@ -69,7 +69,7 @@
     internal var isSelected = false
 
     /** The length of the text in text widget. */
-    private val length = textPainter.text?.let { it.text.length } ?: 0
+    private val length = textDelegate.text?.let { it.text.length } ?: 0
 
     init {
         processTextSelection()
@@ -82,19 +82,19 @@
         val startPx = selectionCoordinates.first
         val endPx = selectionCoordinates.second
 
-        if (!mode.isSelected(textPainter, start = startPx, end = endPx)) {
+        if (!mode.isSelected(textDelegate, start = startPx, end = endPx)) {
             onSelectionChange(null)
             return
         }
 
         isSelected = true
         var (textSelectionStart, containsWholeSelectionStart) =
-            getSelectionBorder(textPainter, startPx, true)
+            getSelectionBorder(textDelegate, startPx, true)
         var (textSelectionEnd, containsWholeSelectionEnd) =
-            getSelectionBorder(textPainter, endPx, false)
+            getSelectionBorder(textDelegate, endPx, false)
 
         if (textSelectionStart == textSelectionEnd) {
-            val wordBoundary = textPainter.getWordBoundary(textSelectionStart)
+            val wordBoundary = textDelegate.getWordBoundary(textSelectionStart)
             textSelectionStart = wordBoundary.start
             textSelectionEnd = wordBoundary.end
         }
@@ -113,7 +113,7 @@
      * selection.
      */
     private fun getSelectionBorder(
-        textPainter: TextPainter,
+        textDelegate: TextDelegate,
         // This position is in Text widget coordinate system.
         position: PxPosition,
         isStart: Boolean
@@ -127,9 +127,9 @@
         var containsWholeSelectionBorder = false
 
         val top = 0.px
-        val bottom = textPainter.height.px
+        val bottom = textDelegate.height.px
         val left = 0.px
-        val right = textPainter.width.px
+        val right = textDelegate.width.px
         // If the current text widget contains the whole selection's border, then find the exact
         // character offset of the border, and the flag checking if the widget contains the whole
         // selection's border will be set to true.
@@ -141,7 +141,7 @@
             // Constrain the character offset of the selection border to be within the text range
             // of the current widget.
             val constrainedSelectionBorderOffset =
-                textPainter.getOffsetForPosition(position).coerceIn(0, length - 1)
+                textDelegate.getOffsetForPosition(position).coerceIn(0, length - 1)
             selectionBorder = constrainedSelectionBorderOffset
             containsWholeSelectionBorder = true
         }
@@ -149,10 +149,10 @@
     }
 
     private fun getSelectionHandleCoordinates(offset: Int): PxPosition {
-        val left = textPainter.getPrimaryHorizontal(offset)
+        val left = textDelegate.getPrimaryHorizontal(offset)
 
-        val line = textPainter.getLineForOffset(offset)
-        val bottom = textPainter.getLineBottom(line)
+        val line = textDelegate.getLineForOffset(offset)
+        val bottom = textDelegate.getLineBottom(line)
 
         return PxPosition(left.px, bottom.px)
     }
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/VectorAsset.kt b/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/VectorAsset.kt
index 80071b1..cf78c4c 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/VectorAsset.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/VectorAsset.kt
@@ -19,29 +19,28 @@
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.ui.core.Px
-import androidx.ui.graphics.vectorgraphics.BrushType
-import androidx.ui.graphics.vectorgraphics.DefaultAlpha
-import androidx.ui.graphics.vectorgraphics.DefaultGroupName
-import androidx.ui.graphics.vectorgraphics.DefaultPathName
-import androidx.ui.graphics.vectorgraphics.DefaultPivotX
-import androidx.ui.graphics.vectorgraphics.DefaultPivotY
-import androidx.ui.graphics.vectorgraphics.DefaultRotation
-import androidx.ui.graphics.vectorgraphics.DefaultScaleX
-import androidx.ui.graphics.vectorgraphics.DefaultScaleY
-import androidx.ui.graphics.vectorgraphics.DefaultStrokeLineCap
-import androidx.ui.graphics.vectorgraphics.DefaultStrokeLineJoin
-import androidx.ui.graphics.vectorgraphics.DefaultStrokeLineMiter
-import androidx.ui.graphics.vectorgraphics.DefaultStrokeLineWidth
-import androidx.ui.graphics.vectorgraphics.DefaultTranslationX
-import androidx.ui.graphics.vectorgraphics.DefaultTranslationY
-import androidx.ui.graphics.vectorgraphics.EmptyBrush
-import androidx.ui.graphics.vectorgraphics.EmptyPath
-import androidx.ui.graphics.vectorgraphics.PathData
+import androidx.ui.graphics.EmptyBrush
 import androidx.ui.painting.StrokeCap
 import androidx.ui.painting.StrokeJoin
+import androidx.ui.vector.BrushType
+import androidx.ui.vector.DefaultAlpha
+import androidx.ui.vector.DefaultGroupName
+import androidx.ui.vector.DefaultPathName
+import androidx.ui.vector.DefaultPivotX
+import androidx.ui.vector.DefaultPivotY
+import androidx.ui.vector.DefaultRotation
+import androidx.ui.vector.DefaultScaleX
+import androidx.ui.vector.DefaultScaleY
+import androidx.ui.vector.DefaultStrokeLineCap
+import androidx.ui.vector.DefaultStrokeLineJoin
+import androidx.ui.vector.DefaultStrokeLineMiter
+import androidx.ui.vector.DefaultStrokeLineWidth
+import androidx.ui.vector.DefaultTranslationX
+import androidx.ui.vector.DefaultTranslationY
+import androidx.ui.vector.EmptyPath
+import androidx.ui.vector.PathData
 import androidx.ui.vector.VectorScope
 import java.util.Stack
-import java.util.function.Consumer
 
 /**
  * Builder used to construct a Vector graphic tree.
@@ -318,7 +317,7 @@
     }
 
     override fun iterator(): Iterator<VectorNode> {
-        return object: Iterator<VectorNode> {
+        return object : Iterator<VectorNode> {
 
             val it = children.iterator()
 
@@ -396,7 +395,8 @@
         viewportWidth = vectorImage.viewportWidth,
         viewportHeight = vectorImage.viewportHeight,
         defaultWidth = vectorImage.defaultWidth,
-        defaultHeight = vectorImage.defaultHeight) {
+        defaultHeight = vectorImage.defaultHeight
+    ) { _, _ ->
         RenderVectorGroup(group = vectorImage.root)
     }
 }
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/VectorCompose.kt b/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/VectorCompose.kt
index 4e36f04..39b15c9 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/VectorCompose.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/VectorCompose.kt
@@ -21,67 +21,108 @@
 import androidx.compose.composer
 import androidx.compose.compositionReference
 import androidx.compose.memo
-import androidx.compose.onDispose
 import androidx.compose.onPreCommit
 import androidx.compose.unaryPlus
-
+import androidx.ui.core.Dp
 import androidx.ui.core.Draw
 import androidx.ui.core.Px
-import androidx.ui.graphics.vectorgraphics.Brush
-import androidx.ui.graphics.vectorgraphics.BrushType
-import androidx.ui.graphics.vectorgraphics.DefaultAlpha
-import androidx.ui.graphics.vectorgraphics.DefaultGroupName
-import androidx.ui.graphics.vectorgraphics.DefaultPathName
-import androidx.ui.graphics.vectorgraphics.DefaultPivotX
-import androidx.ui.graphics.vectorgraphics.DefaultPivotY
-import androidx.ui.graphics.vectorgraphics.DefaultRotation
-import androidx.ui.graphics.vectorgraphics.DefaultScaleX
-import androidx.ui.graphics.vectorgraphics.DefaultScaleY
-import androidx.ui.graphics.vectorgraphics.DefaultStrokeLineCap
-import androidx.ui.graphics.vectorgraphics.DefaultStrokeLineJoin
-import androidx.ui.graphics.vectorgraphics.DefaultStrokeLineMiter
-import androidx.ui.graphics.vectorgraphics.DefaultStrokeLineWidth
-import androidx.ui.graphics.vectorgraphics.DefaultTranslationX
-import androidx.ui.graphics.vectorgraphics.DefaultTranslationY
-import androidx.ui.graphics.vectorgraphics.EmptyBrush
-import androidx.ui.graphics.vectorgraphics.EmptyPath
-import androidx.ui.graphics.vectorgraphics.PathData
-import androidx.ui.graphics.vectorgraphics.VectorComponent
-import androidx.ui.graphics.vectorgraphics.GroupComponent
-import androidx.ui.graphics.vectorgraphics.PathComponent
-import androidx.ui.graphics.vectorgraphics.createPath
-import androidx.ui.graphics.vectorgraphics.obtainBrush
+import androidx.ui.core.withDensity
+import androidx.ui.graphics.Brush
+import androidx.ui.graphics.EmptyBrush
+import androidx.ui.graphics.obtainBrush
 import androidx.ui.painting.StrokeCap
 import androidx.ui.painting.StrokeJoin
+import androidx.ui.vector.BrushType
+import androidx.ui.vector.DefaultAlpha
+import androidx.ui.vector.DefaultGroupName
+import androidx.ui.vector.DefaultPathName
+import androidx.ui.vector.DefaultPivotX
+import androidx.ui.vector.DefaultPivotY
+import androidx.ui.vector.DefaultRotation
+import androidx.ui.vector.DefaultScaleX
+import androidx.ui.vector.DefaultScaleY
+import androidx.ui.vector.DefaultStrokeLineCap
+import androidx.ui.vector.DefaultStrokeLineJoin
+import androidx.ui.vector.DefaultStrokeLineMiter
+import androidx.ui.vector.DefaultStrokeLineWidth
+import androidx.ui.vector.DefaultTranslationX
+import androidx.ui.vector.DefaultTranslationY
+import androidx.ui.vector.EmptyPath
+import androidx.ui.vector.GroupComponent
+import androidx.ui.vector.PathComponent
+import androidx.ui.vector.PathData
+import androidx.ui.vector.VectorComponent
 import androidx.ui.vector.VectorScope
 import androidx.ui.vector.composeVector
+import androidx.ui.vector.createPath
 import androidx.ui.vector.disposeVector
-import java.util.Vector
 
+/**
+ * Sentinel value used to indicate that a dimension is not provided
+ */
+private const val unset: Float = -1.0f
 
+/**
+ * Draw a vector graphic with the provided width, height and viewport dimensions
+ * [defaultWidth] Intrinsic width of the Vector in [Dp]
+ * [defaultHeight] Intrinsic height of hte Vector in [Dp]
+ * [vectorWidth] Width of the viewport space. The viewport is the virtual canvas where paths are drawn on.
+ *  This parameter is optional. Not providing it will use the [defaultWidth] converted to [Px]
+ * [vectorHeight] Height of hte viewport space. The viewport is the virtual canvas where paths are drawn on.
+ *  This parameter is optional. Not providing it will use the [defaultHeight] converted to [Px]
+ */
 @Composable
 fun DrawVector(
-    viewportWidth: Float,
-    viewportHeight: Float,
-    defaultWidth: Px = Px(viewportWidth),
-    defaultHeight: Px = Px(viewportHeight),
+    defaultWidth: Dp,
+    defaultHeight: Dp,
+    viewportWidth: Float = unset,
+    viewportHeight: Float = unset,
     name: String = "",
-    @Children children: @Composable() VectorScope.() -> Unit
+    @Children children: @Composable() VectorScope.(viewportWidth: Float, viewportHeight: Float) -> Unit
 ) {
-    val vector = +memo(name, viewportWidth, viewportHeight) {
-        VectorComponent(
-            name,
-            viewportWidth,
-            viewportHeight,
-            defaultWidth,
-            defaultHeight
-        )
-    }
+    val widthPx = +withDensity { defaultWidth.toPx() }
+    val heightPx = +withDensity { defaultHeight.toPx() }
+
+    val vpWidth = if (viewportWidth == unset) widthPx.value else viewportWidth
+    val vpHeight = if (viewportHeight == unset) heightPx.value else viewportHeight
+    DrawVector(widthPx, heightPx, vpWidth, vpHeight, name, children)
+}
+
+/**
+ * Draw a vector graphic with the provided width, height and viewport dimensions
+ * [defaultWidth] Intrinsic width of the Vector in [Px]
+ * [defaultHeight] Intrinsic height of hte Vector in [Px]
+ * [vectorWidth] Width of the viewport space. The viewport is the virtual canvas where paths are drawn on.
+ *  This parameter is optional. Not providing it will use the [defaultWidth]
+ * [vectorHeight] Height of hte viewport space. The viewport is the virtual canvas where paths are drawn on.
+ *  This parameter is optional. Not providing it will use the [defaultHeight]
+ */
+@Composable
+fun DrawVector(
+    defaultWidth: Px,
+    defaultHeight: Px,
+    viewportWidth: Float = defaultWidth.value,
+    viewportHeight: Float = defaultHeight.value,
+    name: String = "",
+    @Children children: @Composable() VectorScope.(viewportWidth: Float, viewportHeight: Float) -> Unit
+) {
+    val vector =
+        +memo(name, viewportWidth, viewportHeight) {
+            VectorComponent(
+                name,
+                viewportWidth,
+                viewportHeight,
+                defaultWidth,
+                defaultHeight
+            )
+        }
 
     val ref = +compositionReference()
     composeVector(vector, ref, children)
     +onPreCommit(vector) {
-        onDispose { disposeVector(vector, ref) }
+        onDispose {
+            disposeVector(vector, ref)
+        }
     }
 
     Draw { canvas, _ ->
@@ -100,7 +141,7 @@
     translationX: Float = DefaultTranslationX,
     translationY: Float = DefaultTranslationY,
     clipPathData: PathData = EmptyPath,
-    @Children children: @Composable() VectorScope.() -> Unit
+    children: @Composable() VectorScope.() -> Unit
 ) {
 
     val clipPathNodes = +memo(clipPathData) {
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/compat/AndroidVectorResources.kt b/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/compat/AndroidVectorResources.kt
index 7480ef0..7062eb3 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/compat/AndroidVectorResources.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/compat/AndroidVectorResources.kt
@@ -76,7 +76,8 @@
         android.R.attr.strokeMiterLimit,
         android.R.attr.strokeAlpha,
         android.R.attr.fillAlpha,
-        android.R.attr.fillType
+        // android.R.attr.fillType is in API level 24+ use hardcoded value to extract the attribute if it exists
+        0x101051E
     )
     val STYLEABLE_VECTOR_DRAWABLE_PATH_FILL_ALPHA = 12
     val STYLEABLE_VECTOR_DRAWABLE_PATH_FILL_COLOR = 1
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/compat/VectorResource.kt b/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/compat/VectorResource.kt
index a886ad0..01324e6 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/compat/VectorResource.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/compat/VectorResource.kt
@@ -20,8 +20,10 @@
 import android.annotation.SuppressLint
 import android.content.res.Resources
 import android.util.Xml
+import androidx.annotation.CheckResult
 import androidx.compose.Composable
 import androidx.compose.ambient
+import androidx.compose.effectOf
 import androidx.compose.memo
 import androidx.compose.unaryPlus
 import androidx.ui.core.ContextAmbient
@@ -29,21 +31,34 @@
 import androidx.ui.core.vectorgraphics.VectorAsset
 import org.xmlpull.v1.XmlPullParserException
 
+/**
+ * Convenience method to simultaneously load and draw a vector resource
+ */
 @Composable
-fun VectorResource(resId: Int) {
+fun DrawVectorResource(resId: Int) = DrawVector(vectorImage = +vectorResource(resId))
+
+/**
+ * Effect used to load a [VectorAsset] from an Android resource id
+ * This is useful for querying top level properties of the [VectorAsset]
+ * such as it's intrinsic width and height to be able to size components
+ * based off of it's dimensions appropriately
+ */
+@CheckResult(suggest = "+")
+fun vectorResource(resId: Int) = effectOf<VectorAsset> {
     val context = +ambient(ContextAmbient)
     val res = context.resources
     val theme = context.theme
-    val vectorImage = +memo(resId) {
+    +memo(resId) {
         loadVectorResource(theme, res, resId)
     }
-    DrawVector(vectorImage = vectorImage)
 }
 
 @Throws(XmlPullParserException::class)
 @SuppressWarnings("RestrictedApi")
-fun loadVectorResource(theme: Resources.Theme? = null, res: Resources, resId: Int): VectorAsset {
-
+fun loadVectorResource(
+    theme: Resources.Theme? = null,
+    res: Resources, resId: Int
+): VectorAsset {
     @SuppressLint("ResourceType") val parser = res.getXml(resId)
     val attrs = Xml.asAttributeSet(parser)
     val builder = parser.seekToStartTag().createVectorImageBuilder(res, theme, attrs)
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/compat/XmlVectorParser.kt b/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/compat/XmlVectorParser.kt
index 88749ef..4e5e54b 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/compat/XmlVectorParser.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/vectorgraphics/compat/XmlVectorParser.kt
@@ -21,19 +21,21 @@
 import androidx.core.content.res.TypedArrayUtils
 import androidx.ui.core.Px
 import androidx.ui.core.vectorgraphics.VectorAssetBuilder
-import androidx.ui.graphics.vectorgraphics.DefaultPivotX
-import androidx.ui.graphics.vectorgraphics.DefaultPivotY
-import androidx.ui.graphics.vectorgraphics.DefaultRotation
-import androidx.ui.graphics.vectorgraphics.DefaultScaleX
-import androidx.ui.graphics.vectorgraphics.DefaultScaleY
-import androidx.ui.graphics.vectorgraphics.DefaultTranslationX
-import androidx.ui.graphics.vectorgraphics.DefaultTranslationY
-import androidx.ui.graphics.vectorgraphics.EmptyBrush
-import androidx.ui.graphics.vectorgraphics.EmptyPath
+
+import androidx.ui.graphics.EmptyBrush
+
 import androidx.ui.graphics.vectorgraphics.PathNode
-import androidx.ui.graphics.vectorgraphics.addPathNodes
+import androidx.ui.vector.addPathNodes
 import androidx.ui.painting.StrokeCap
 import androidx.ui.painting.StrokeJoin
+import androidx.ui.vector.DefaultPivotX
+import androidx.ui.vector.DefaultPivotY
+import androidx.ui.vector.DefaultRotation
+import androidx.ui.vector.DefaultScaleX
+import androidx.ui.vector.DefaultScaleY
+import androidx.ui.vector.DefaultTranslationX
+import androidx.ui.vector.DefaultTranslationY
+import androidx.ui.vector.EmptyPath
 import org.xmlpull.v1.XmlPullParser
 import org.xmlpull.v1.XmlPullParserException
 
diff --git a/ui/ui-framework/src/main/java/androidx/ui/semantics/Semantics.kt b/ui/ui-framework/src/main/java/androidx/ui/semantics/Semantics.kt
new file mode 100644
index 0000000..e3ba12c
--- /dev/null
+++ b/ui/ui-framework/src/main/java/androidx/ui/semantics/Semantics.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2019 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.ui.semantics
+
+import androidx.compose.Children
+import androidx.compose.Composable
+import androidx.compose.ambient
+import androidx.compose.composer
+import androidx.compose.unaryPlus
+import androidx.ui.core.DefaultTestTag
+import androidx.ui.core.SemanticsComponentNode
+import androidx.ui.core.TestTag
+import androidx.ui.core.TestTagAmbient
+import androidx.ui.core.semantics.SemanticsConfiguration
+import androidx.ui.core.semantics.getOrNull
+
+@Composable
+fun Semantics(
+    /**
+     * If 'container' is true, this component will introduce a new
+     * node in the semantics tree. Otherwise, the semantics will be
+     * merged with the semantics of any ancestors.
+     *
+     * Whether descendants of this component can add their semantic information
+     * to the [SemanticsNode] introduced by this configuration is controlled by
+     * [explicitChildNodes].
+     */
+    container: Boolean = false,
+    /**
+     * Whether descendants of this component are allowed to add semantic
+     * information to the [SemanticsNode] annotated by this widget.
+     *
+     * When set to false descendants are allowed to annotate [SemanticNode]s of
+     * their parent with the semantic information they want to contribute to the
+     * semantic tree.
+     * When set to true the only way for descendants to contribute semantic
+     * information to the semantic tree is to introduce new explicit
+     * [SemanticNode]s to the tree.
+     *
+     * This setting is often used in combination with [isSemanticBoundary] to
+     * create semantic boundaries that are either writable or not for children.
+     */
+    explicitChildNodes: Boolean = false,
+    properties: (SemanticsPropertyReceiver.() -> Unit)? = null,
+    children: @Composable() () -> Unit
+) {
+    val providedTestTag = +ambient(TestTagAmbient)
+    val semanticsConfiguration = SemanticsConfiguration().also {
+        properties?.invoke(it)
+        // TODO(b/138173101): replace with the real thing
+        it.testTag = it.getOrNull(SemanticsProperties.TestTag) ?: providedTestTag
+    }
+
+    <SemanticsComponentNode
+        container
+        explicitChildNodes
+        semanticsConfiguration> TestTag(tag = DefaultTestTag) {
+        children()
+    }
+    </SemanticsComponentNode>
+}
diff --git a/ui/ui-framework/src/main/java/androidx/ui/semantics/SemanticsProperties.kt b/ui/ui-framework/src/main/java/androidx/ui/semantics/SemanticsProperties.kt
new file mode 100644
index 0000000..3df6c88
--- /dev/null
+++ b/ui/ui-framework/src/main/java/androidx/ui/semantics/SemanticsProperties.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2019 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.ui.semantics
+
+import androidx.ui.text.style.TextDirection
+
+object SemanticsProperties {
+    val AccessibilityLabel = object : SemanticsPropertyKey<String>("AccessibilityLabel") {
+        override fun merge(existingValue: String, newValue: String): String {
+            // TODO(b/138173613): Needs TextDirection, probably needs to pass both nodes
+            //  to retrieve it
+            return existingValue + "\n" + newValue
+        }
+    }
+
+    val AccessibilityValue = SemanticsPropertyKey<String>("AccessibilityValue")
+
+    val Enabled = SemanticsPropertyKey<Boolean>("Enabled")
+
+    val Hidden = SemanticsPropertyKey<Boolean>("Hidden")
+
+    val TextDirection = SemanticsPropertyKey<TextDirection>("TextDirection")
+
+    // TODO(b/138172781): Move to FoundationSemanticsProperties
+    val TestTag = SemanticsPropertyKey<String>("TestTag")
+}
+
+class SemanticsActions {
+    companion object {
+        val OnClick = SemanticsPropertyKey<AccessibilityAction<() -> Unit>>("OnClick")
+
+        val CustomActions =
+            SemanticsPropertyKey<List<AccessibilityAction<() -> Unit>>>("CustomActions")
+    }
+}
+
+var SemanticsPropertyReceiver.accessibilityLabel by SemanticsProperties.AccessibilityLabel
+
+var SemanticsPropertyReceiver.accessibilityValue by SemanticsProperties.AccessibilityValue
+
+var SemanticsPropertyReceiver.enabled by SemanticsProperties.Enabled
+
+var SemanticsPropertyReceiver.hidden by SemanticsProperties.Hidden
+
+var SemanticsPropertyReceiver.textDirection by SemanticsProperties.TextDirection
+
+var SemanticsPropertyReceiver.onClick by SemanticsActions.OnClick
+
+fun SemanticsPropertyReceiver.onClick(label: String? = null, action: () -> Unit) {
+    this[SemanticsActions.OnClick] = AccessibilityAction(label, action)
+}
+
+var SemanticsPropertyReceiver.customActions by SemanticsActions.CustomActions
+
+// TODO(b/138172781): Move to FoundationSemanticsProperties.kt
+var SemanticsPropertyReceiver.testTag by SemanticsProperties.TestTag
+
+// TODO(b/138173613): Use this for merging labels
+/*
+private fun concatStrings(
+    thisString: String?,
+    otherString: String?,
+    thisTextDirection: TextDirection?,
+    otherTextDirection: TextDirection?
+): String? {
+    if (otherString.isNullOrEmpty())
+        return thisString
+    var nestedLabel = otherString
+    if (thisTextDirection != otherTextDirection && otherTextDirection != null) {
+        nestedLabel = when (otherTextDirection) {
+            TextDirection.Rtl -> "${Unicode.RLE}$nestedLabel${Unicode.PDF}"
+            TextDirection.Ltr -> "${Unicode.LRE}$nestedLabel${Unicode.PDF}"
+        }
+    }
+    if (thisString.isNullOrEmpty())
+        return nestedLabel
+    return "$thisString\n$nestedLabel"
+}
+*/
diff --git a/ui/ui-framework/src/test/java/androidx/ui/core/PasswordVisualTransformationTest.kt b/ui/ui-framework/src/test/java/androidx/ui/core/PasswordVisualTransformationTest.kt
deleted file mode 100644
index 1284040..0000000
--- a/ui/ui-framework/src/test/java/androidx/ui/core/PasswordVisualTransformationTest.kt
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2019 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.ui.core
-
-import androidx.ui.text.AnnotatedString
-import org.junit.Assert.assertEquals
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@RunWith(JUnit4::class)
-class PasswordVisualTransformationTest {
-    @Test
-    fun check_visual_output_is_masked_with_asterisk() {
-        val transformation = PasswordVisualTransformation(mask = '*')
-        val text = AnnotatedString("12345")
-        val (transformedText, map) = transformation.filter(text)
-
-        assertEquals("*****", transformedText.text)
-        for (i in 0..transformedText.text.length) {
-            assertEquals(i, map.originalToTransformed(i))
-            assertEquals(i, map.transformedToOriginal(i))
-        }
-    }
-
-    @Test
-    fun check_visual_output_is_masked_with_default() {
-        val filter = PasswordVisualTransformation()
-        val text = AnnotatedString("1234567890")
-        val (filtered, map) = filter.filter(text)
-
-        assertEquals("\u2022".repeat(10), filtered.text)
-        for (i in 0..filtered.text.length) {
-            assertEquals(i, map.originalToTransformed(i))
-            assertEquals(i, map.transformedToOriginal(i))
-        }
-    }
-}
\ No newline at end of file
diff --git a/ui/ui-framework/src/test/java/androidx/ui/core/TextFieldDelegateTest.kt b/ui/ui-framework/src/test/java/androidx/ui/core/TextFieldDelegateTest.kt
index 4657c23..89e9a23 100644
--- a/ui/ui-framework/src/test/java/androidx/ui/core/TextFieldDelegateTest.kt
+++ b/ui/ui-framework/src/test/java/androidx/ui/core/TextFieldDelegateTest.kt
@@ -22,14 +22,16 @@
 import androidx.ui.input.EditOperation
 import androidx.ui.input.EditProcessor
 import androidx.ui.input.EditorModel
+import androidx.ui.input.EditorStyle
 import androidx.ui.input.FinishComposingTextEditOp
 import androidx.ui.input.ImeAction
 import androidx.ui.input.KeyboardType
+import androidx.ui.input.OffsetMap
 import androidx.ui.input.SetSelectionEditOp
 import androidx.ui.input.TextInputService
 import androidx.ui.painting.Canvas
 import androidx.ui.text.AnnotatedString
-import androidx.ui.text.TextPainter
+import androidx.ui.text.TextDelegate
 import androidx.ui.text.TextRange
 import androidx.ui.text.TextStyle
 import com.nhaarman.mockitokotlin2.any
@@ -52,7 +54,7 @@
 class TextFieldDelegateTest {
 
     private lateinit var canvas: Canvas
-    private lateinit var painter: TextPainter
+    private lateinit var mDelegate: TextDelegate
     private lateinit var processor: EditProcessor
     private lateinit var onValueChange: (EditorModel) -> Unit
     private lateinit var onEditorActionPerformed: (Any) -> Unit
@@ -92,7 +94,7 @@
 
     @Before
     fun setup() {
-        painter = mock()
+        mDelegate = mock()
         canvas = mock()
         processor = mock()
         onValueChange = mock()
@@ -108,18 +110,18 @@
 
         TextFieldDelegate.draw(
             canvas = canvas,
-            textPainter = painter,
+            textDelegate = mDelegate,
             value = EditorModel(text = "Hello, World", selection = selection),
             editorStyle = EditorStyle(selectionColor = selectionColor),
             hasFocus = true,
             offsetMap = identityOffsetMap
         )
 
-        verify(painter, times(1)).paintBackground(
+        verify(mDelegate, times(1)).paintBackground(
             eq(selection.start), eq(selection.end), eq(selectionColor), eq(canvas))
-        verify(painter, times(1)).paint(eq(canvas))
+        verify(mDelegate, times(1)).paint(eq(canvas))
 
-        verify(painter, never()).paintCursor(any(), any())
+        verify(mDelegate, never()).paintCursor(any(), any())
     }
 
     @Test
@@ -128,16 +130,16 @@
 
         TextFieldDelegate.draw(
             canvas = canvas,
-            textPainter = painter,
+            textDelegate = mDelegate,
             value = EditorModel(text = "Hello, World", selection = cursor),
             editorStyle = EditorStyle(),
             hasFocus = true,
             offsetMap = identityOffsetMap
         )
 
-        verify(painter, times(1)).paintCursor(eq(cursor.start), eq(canvas))
-        verify(painter, times(1)).paint(eq(canvas))
-        verify(painter, never()).paintBackground(any(), any(), any(), any())
+        verify(mDelegate, times(1)).paintCursor(eq(cursor.start), eq(canvas))
+        verify(mDelegate, times(1)).paint(eq(canvas))
+        verify(mDelegate, never()).paintBackground(any(), any(), any(), any())
     }
 
     @Test
@@ -146,16 +148,16 @@
 
         TextFieldDelegate.draw(
             canvas = canvas,
-            textPainter = painter,
+            textDelegate = mDelegate,
             value = EditorModel(text = "Hello, World", selection = cursor),
             editorStyle = EditorStyle(),
             hasFocus = false,
             offsetMap = identityOffsetMap
         )
 
-        verify(painter, never()).paintCursor(any(), any())
-        verify(painter, times(1)).paint(eq(canvas))
-        verify(painter, never()).paintBackground(any(), any(), any(), any())
+        verify(mDelegate, never()).paintCursor(any(), any())
+        verify(mDelegate, times(1)).paint(eq(canvas))
+        verify(mDelegate, never()).paintBackground(any(), any(), any(), any())
     }
 
     @Test
@@ -167,7 +169,7 @@
 
         TextFieldDelegate.draw(
             canvas = canvas,
-            textPainter = painter,
+            textDelegate = mDelegate,
             value = EditorModel(text = "Hello, World", selection = cursor,
                 composition = composition),
             editorStyle = EditorStyle(compositionColor = compositionColor),
@@ -175,10 +177,10 @@
             offsetMap = identityOffsetMap
         )
 
-        verify(painter, times(1)).paintBackground(
+        verify(mDelegate, times(1)).paintBackground(
             eq(composition.start), eq(composition.end), eq(compositionColor), eq(canvas))
-        verify(painter, times(1)).paint(eq(canvas))
-        verify(painter, times(1)).paintCursor(eq(cursor.start), any())
+        verify(mDelegate, times(1)).paint(eq(canvas))
+        verify(mDelegate, times(1)).paintCursor(eq(cursor.start), any())
     }
 
     @Test
@@ -199,7 +201,7 @@
         val offset = 10
         val dummyEditorState = EditorModel(text = "Hello, World", selection = TextRange(1, 1))
 
-        whenever(painter.getOffsetForPosition(position)).thenReturn(offset)
+        whenever(mDelegate.getOffsetForPosition(position)).thenReturn(offset)
 
         val captor = argumentCaptor<List<EditOperation>>()
 
@@ -207,7 +209,7 @@
 
         TextFieldDelegate.onRelease(
             position,
-            painter,
+            mDelegate,
             processor,
             identityOffsetMap,
             onValueChange,
@@ -226,10 +228,10 @@
         val position = PxPosition(100.px, 200.px)
         val offset = 10
 
-        whenever(painter.getOffsetForPosition(position)).thenReturn(offset)
+        whenever(mDelegate.getOffsetForPosition(position)).thenReturn(offset)
         TextFieldDelegate.onRelease(
             position,
-            painter,
+            mDelegate,
             processor,
             identityOffsetMap,
             onValueChange,
@@ -246,7 +248,7 @@
 
         TextFieldDelegate.draw(
             canvas = canvas,
-            textPainter = painter,
+            textDelegate = mDelegate,
             value = EditorModel(
                 text = "Hello, World", selection = TextRange(1, 1),
                 composition = TextRange(1, 3)
@@ -256,9 +258,9 @@
             offsetMap = identityOffsetMap
             )
 
-        inOrder(painter) {
-            verify(painter).paintBackground(eq(1), eq(3), eq(Color.Red), eq(canvas))
-            verify(painter).paintCursor(eq(1), eq(canvas))
+        inOrder(mDelegate) {
+            verify(mDelegate).paintBackground(eq(1), eq(3), eq(Color.Red), eq(canvas))
+            verify(mDelegate).paintCursor(eq(1), eq(canvas))
         }
     }
 
@@ -293,13 +295,13 @@
     @Test
     fun notify_focused_rect() {
         val dummyRect = Rect(0f, 1f, 2f, 3f)
-        whenever(painter.getBoundingBox(any())).thenReturn(dummyRect)
+        whenever(mDelegate.getBoundingBox(any())).thenReturn(dummyRect)
         val dummyPoint = PxPosition(5.px, 6.px)
         whenever(layoutCoordinates.localToRoot(any())).thenReturn(dummyPoint)
         val dummyEditorState = EditorModel(text = "Hello, World", selection = TextRange(1, 1))
         TextFieldDelegate.notifyFocusedRect(
             dummyEditorState,
-            painter,
+            mDelegate,
             layoutCoordinates,
             textInputService,
             true /* hasFocus */,
@@ -313,7 +315,7 @@
         val dummyEditorState = EditorModel(text = "Hello, World", selection = TextRange(1, 1))
         TextFieldDelegate.notifyFocusedRect(
             dummyEditorState,
-            painter,
+            mDelegate,
             layoutCoordinates,
             textInputService,
             false /* hasFocus */,
@@ -325,13 +327,13 @@
     @Test
     fun notify_rect_tail() {
         val dummyRect = Rect(0f, 1f, 2f, 3f)
-        whenever(painter.getBoundingBox(any())).thenReturn(dummyRect)
+        whenever(mDelegate.getBoundingBox(any())).thenReturn(dummyRect)
         val dummyPoint = PxPosition(5.px, 6.px)
         whenever(layoutCoordinates.localToRoot(any())).thenReturn(dummyPoint)
         val dummyEditorState = EditorModel(text = "Hello, World", selection = TextRange(12, 12))
         TextFieldDelegate.notifyFocusedRect(
             dummyEditorState,
-            painter,
+            mDelegate,
             layoutCoordinates,
             textInputService,
             true /* hasFocus */,
@@ -341,25 +343,6 @@
     }
 
     @Test
-    fun notify_rect_empty() {
-        val dummyHeight = 64f
-        whenever(painter.preferredLineHeight).thenReturn(dummyHeight)
-        val dummyPoint = PxPosition(5.px, 6.px)
-        whenever(layoutCoordinates.localToRoot(any())).thenReturn(dummyPoint)
-        val dummyEditorState = EditorModel(text = "", selection = TextRange(0, 0))
-        TextFieldDelegate.notifyFocusedRect(
-            dummyEditorState,
-            painter,
-            layoutCoordinates,
-            textInputService,
-            true, /* hasFocus */
-            identityOffsetMap)
-        val captor = argumentCaptor<Rect>()
-        verify(textInputService).notifyFocusedRect(captor.capture())
-        assertEquals(dummyHeight, captor.firstValue.height)
-    }
-
-    @Test
     fun layout() {
         val constraints = Constraints(
             minWidth = 0.px.round(),
@@ -369,17 +352,17 @@
         )
 
         val dummyText = AnnotatedString(text = "Hello, World")
-        whenever(painter.text).thenReturn(dummyText)
-        whenever(painter.style).thenReturn(TextStyle())
-        whenever(painter.density).thenReturn(Density(1.0f))
-        whenever(painter.resourceLoader).thenReturn(mock())
-        whenever(painter.height).thenReturn(512.0f)
+        whenever(mDelegate.text).thenReturn(dummyText)
+        whenever(mDelegate.style).thenReturn(TextStyle())
+        whenever(mDelegate.density).thenReturn(Density(1.0f))
+        whenever(mDelegate.resourceLoader).thenReturn(mock())
+        whenever(mDelegate.height).thenReturn(512.0f)
 
-        val res = TextFieldDelegate.layout(painter, constraints)
+        val res = TextFieldDelegate.layout(mDelegate, constraints)
         assertEquals(1024.px.round(), res.first)
         assertEquals(512.px.round(), res.second)
 
-        verify(painter, times(1)).layout(constraints)
+        verify(mDelegate, times(1)).layout(constraints)
     }
 
     @Test
@@ -389,7 +372,7 @@
 
         TextFieldDelegate.draw(
             canvas = canvas,
-            textPainter = painter,
+            textDelegate = mDelegate,
             value = EditorModel(text = "Hello, World", selection = selection),
             editorStyle = EditorStyle(selectionColor = selectionColor),
             hasFocus = true,
@@ -399,7 +382,7 @@
         val selectionStartInTransformedText = selection.start * 2
         val selectionEmdInTransformedText = selection.end * 2
 
-        verify(painter, times(1)).paintBackground(
+        verify(mDelegate, times(1)).paintBackground(
             eq(selectionStartInTransformedText),
             eq(selectionEmdInTransformedText),
             eq(selectionColor),
@@ -411,18 +394,18 @@
         val dummyRect = Rect(0f, 1f, 2f, 3f)
         val dummyPoint = PxPosition(5.px, 6.px)
         val dummyEditorState = EditorModel(text = "Hello, World", selection = TextRange(1, 3))
-        whenever(painter.getBoundingBox(any())).thenReturn(dummyRect)
+        whenever(mDelegate.getBoundingBox(any())).thenReturn(dummyRect)
         whenever(layoutCoordinates.localToRoot(any())).thenReturn(dummyPoint)
 
         TextFieldDelegate.notifyFocusedRect(
             dummyEditorState,
-            painter,
+            mDelegate,
             layoutCoordinates,
             textInputService,
             true /* hasFocus */,
             skippingOffsetMap
         )
-        verify(painter).getBoundingBox(6)
+        verify(mDelegate).getBoundingBox(6)
         verify(textInputService).notifyFocusedRect(any())
     }
 
@@ -432,7 +415,7 @@
         val offset = 10
         val dummyEditorState = EditorModel(text = "Hello, World", selection = TextRange(1, 1))
 
-        whenever(painter.getOffsetForPosition(position)).thenReturn(offset)
+        whenever(mDelegate.getOffsetForPosition(position)).thenReturn(offset)
 
         val captor = argumentCaptor<List<EditOperation>>()
 
@@ -440,7 +423,7 @@
 
         TextFieldDelegate.onRelease(
             position,
-            painter,
+            mDelegate,
             processor,
             skippingOffsetMap,
             onValueChange,
diff --git a/ui/ui-framework/src/test/java/androidx/ui/core/gesture/DoubleTapGestureDetectorTest.kt b/ui/ui-framework/src/test/java/androidx/ui/core/gesture/DoubleTapGestureDetectorTest.kt
index 1890b9f..b9bdc27 100644
--- a/ui/ui-framework/src/test/java/androidx/ui/core/gesture/DoubleTapGestureDetectorTest.kt
+++ b/ui/ui-framework/src/test/java/androidx/ui/core/gesture/DoubleTapGestureDetectorTest.kt
@@ -54,7 +54,8 @@
 
     @Before
     fun setup() {
-        mRecognizer = DoubleTapGestureRecognizer(onDoubleTap, testContext)
+        mRecognizer = DoubleTapGestureRecognizer(testContext)
+        mRecognizer.onDoubleTap = onDoubleTap
         mRecognizer.doubleTapTimeout = DoubleTapTimeoutMillis
     }
 
diff --git a/ui/ui-framework/src/test/java/androidx/ui/core/gesture/DragGestureDetectorTest.kt b/ui/ui-framework/src/test/java/androidx/ui/core/gesture/DragGestureDetectorTest.kt
deleted file mode 100644
index 2f0ec59..0000000
--- a/ui/ui-framework/src/test/java/androidx/ui/core/gesture/DragGestureDetectorTest.kt
+++ /dev/null
@@ -1,990 +0,0 @@
-/*
- * Copyright 2019 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.ui.core.gesture
-
-import androidx.ui.core.Direction
-import androidx.ui.core.Duration
-import androidx.ui.core.PointerEventPass
-import androidx.ui.core.PxPosition
-import androidx.ui.core.anyPositionChangeConsumed
-import androidx.ui.core.consumeDownChange
-import androidx.ui.core.consumePositionChange
-import androidx.ui.core.ipx
-import androidx.ui.core.milliseconds
-import androidx.ui.core.millisecondsToTimestamp
-import androidx.ui.core.px
-import androidx.ui.testutils.consume
-import androidx.ui.testutils.down
-import androidx.ui.testutils.invokeOverAllPasses
-import androidx.ui.testutils.moveBy
-import androidx.ui.testutils.moveTo
-import androidx.ui.testutils.up
-import com.google.common.truth.Truth.assertThat
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-// TODO(shepshapard): Write the following tests.
-// Verify correct shape of slop area (should it be a square or circle)?
-// Test for cases with more than one pointer
-// Test for cases where things are reset when last pointer goes up
-// Verify all methods called during onPostUp
-// Verify default behavior when no callback provided for recognizer or canDrag
-
-// Changing this value will break tests that expect the value to be 10.
-private const val TestTouchSlop = 10
-
-@RunWith(JUnit4::class)
-class DragGestureDetectorTest {
-
-    private lateinit var recognizer: DragGestureRecognizer
-    private lateinit var canDragMockTrue: MockCanDrag
-    private lateinit var log: MutableList<LogItem>
-
-    @Before
-    fun setup() {
-        log = mutableListOf()
-        recognizer = DragGestureRecognizer()
-        recognizer.touchSlop = TestTouchSlop.ipx
-        canDragMockTrue = MockCanDrag(Direction.values(), log)
-    }
-
-    // Verify the circumstances under which canDrag should not be called.
-
-    @Test
-    fun pointerInputHandler_down_canDragNotCalled() {
-        recognizer.canDrag = canDragMockTrue
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down()))
-        assertThat(log).isEmpty()
-    }
-
-    @Test
-    fun pointerInputHandler_downMoveFullyConsumed_canDragNotCalled() {
-        recognizer.canDrag = canDragMockTrue
-
-        val down = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(
-            listOf(down.moveBy(Duration(milliseconds = 10), 3f, 5f).consume(3f, 5f))
-        )
-
-        assertThat(log).isEmpty()
-    }
-
-    // Verify the circumstances under which canDrag should be called.
-
-    @Test
-    fun pointerInputHandler_downMove1Dimension_canDragCalledOnce() {
-        recognizer.canDrag = canDragMockTrue
-
-        val down = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(
-            listOf(down.moveBy(Duration(milliseconds = 10), 3f, 0f))
-        )
-
-        // Twice because while under touch slop, DragGestureDetector checks during PostUp and
-        // PostDown
-        assertThat(log.filter { it.methodName == "canDrag" }).hasSize(2)
-    }
-
-    @Test
-    fun pointerInputHandler_downMove2Dimensions_canDragCalledTwice() {
-        recognizer.canDrag = canDragMockTrue
-
-        val down = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(
-            listOf(down.moveBy(Duration(milliseconds = 10), 3f, 5f))
-        )
-
-        // 4 times because while under touch slop, DragGestureDetector checks during PostUp and
-        // PostDown
-        assertThat(log.filter { it.methodName == "canDrag" }).hasSize(4)
-    }
-
-    @Test
-    fun pointerInputHandler_downMoveOneDimensionPartiallyConsumed_canDragCalledOnce() {
-        recognizer.canDrag = canDragMockTrue
-
-        val down = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(
-            listOf(down.moveBy(Duration(milliseconds = 10), 0f, 5f).consume(0f, 4f))
-        )
-
-        // Twice because while under touch slop, DragGestureDetector checks during PostUp and
-        // PostDown
-        assertThat(log.filter { it.methodName == "canDrag" }).hasSize(2)
-    }
-
-    @Test
-    fun pointerInputHandler_downMoveTwoDimensionPartiallyConsumed_canDragCalledTwice() {
-        recognizer.canDrag = canDragMockTrue
-        val down = down()
-
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(
-            listOf(down.moveBy(Duration(milliseconds = 10), 3f, 5f).consume(2f, 4f))
-        )
-
-        // 4 times because while under touch slop, DragGestureDetector checks during PostUp and
-        // PostDown
-        assertThat(log.filter { it.methodName == "canDrag" }).hasSize(4)
-    }
-
-    @Test
-    fun pointerInputHandler_dragPastTouchSlopOneDimensionAndDrag3MoreTimes_canDragCalledOnce() {
-        val justBeyondSlop = (TestTouchSlop + 1).toFloat()
-        recognizer.canDrag = canDragMockTrue
-
-        val down = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        var move = down.moveTo(10L.millisecondsToTimestamp(), 0f, justBeyondSlop)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(move))
-        repeat(3) {
-            move = move.moveBy(Duration(milliseconds = 10), 0f, 1f)
-            recognizer.pointerInputHandler.invokeOverAllPasses(listOf(move))
-        }
-
-        // Once because although DragGestureDetector checks during PostUp and PostDown, slop is
-        // surpassed during PostUp, and thus isn't checked again.
-        assertThat(log.filter { it.methodName == "canDrag" }).hasSize(1)
-    }
-
-    @Test
-    fun pointerInputHandler_downMoveUnderSlop3Times_canDragCalled3Times() {
-        val thirdSlop = TestTouchSlop.toFloat() / 3
-        recognizer.canDrag = canDragMockTrue
-
-        var event = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(event))
-        repeat(3) {
-            event = event.moveBy(Duration(milliseconds = 10), 0f, thirdSlop)
-            recognizer.pointerInputHandler.invokeOverAllPasses(listOf(event))
-        }
-
-        // 6 times because while under touch slop, DragGestureDetector checks during PostUp and
-        // PostDown
-        assertThat(log.filter { it.methodName == "canDrag" }).hasSize(6)
-    }
-
-    @Test
-    fun pointerInputHandler_moveBeyondSlopThenIntoTouchSlopAreaAndOutAgain_canDragCalledOnce() {
-        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
-        recognizer.canDrag = canDragMockTrue
-
-        var event = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(event))
-        // Out of touch slop region
-        event = event.moveBy(Duration(milliseconds = 10), 0f, beyondTouchSlop)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(event))
-        // Back into touch slop region
-        event = event.moveBy(Duration(milliseconds = 10), 0f, -beyondTouchSlop)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(event))
-        // Out of touch slop region again
-        event = event.moveBy(Duration(milliseconds = 10), 0f, beyondTouchSlop)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(event))
-
-        // Once because although DragGestureDetector checks during PostUp and PostDown, slop is
-        // surpassed during PostUp, and thus isn't checked again.
-        assertThat(log.filter { it.methodName == "canDrag" }).hasSize(1)
-    }
-
-    // Verification of correctness of values passed to canDrag.
-
-    @Test
-    fun pointerInputHandler_canDragCalledWithCorrectDirection() {
-        pointerInputHandler_canDragCalledWithCorrectDirection(-1f, 0f, arrayOf(Direction.LEFT))
-        pointerInputHandler_canDragCalledWithCorrectDirection(0f, -1f, arrayOf(Direction.UP))
-        pointerInputHandler_canDragCalledWithCorrectDirection(1f, 0f, arrayOf(Direction.RIGHT))
-        pointerInputHandler_canDragCalledWithCorrectDirection(0f, 1f, arrayOf(Direction.DOWN))
-
-        pointerInputHandler_canDragCalledWithCorrectDirection(
-            -1f,
-            -1f,
-            arrayOf(Direction.LEFT, Direction.UP)
-        )
-        pointerInputHandler_canDragCalledWithCorrectDirection(
-            -1f,
-            1f,
-            arrayOf(Direction.LEFT, Direction.DOWN)
-        )
-        pointerInputHandler_canDragCalledWithCorrectDirection(
-            1f,
-            -1f,
-            arrayOf(Direction.RIGHT, Direction.UP)
-        )
-        pointerInputHandler_canDragCalledWithCorrectDirection(
-            1f,
-            1f,
-            arrayOf(Direction.RIGHT, Direction.DOWN)
-        )
-    }
-
-    private fun pointerInputHandler_canDragCalledWithCorrectDirection(
-        dx: Float,
-        dy: Float,
-        expectedDirections: Array<Direction>
-    ) {
-        log.clear()
-        recognizer.canDrag = canDragMockTrue
-
-        val down = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(
-            listOf(down.moveBy(Duration(milliseconds = 10), dx, dy))
-        )
-
-        // Everything here is twice because DragGestureDetector checks during PostUp and PostDown.
-        assertThat(log).hasSize(expectedDirections.size * 2)
-        expectedDirections.forEach { direction ->
-            assertThat(log.count { it == LogItem("canDrag", direction = direction) })
-                .isEqualTo(2)
-        }
-    }
-
-    // Verify the circumstances under which onStart/OnDrag should not be called.
-
-    // TODO(b/129701831): This test assumes that if a pointer moves by slop in both x and y, we are
-    // still under slop even though sqrt(slop^2 + slop^2) > slop.  This may be inaccurate and this
-    // test may therefore need to be updated.
-    @Test
-    fun pointerInputHandler_downMoveWithinSlop_onStartAndOnDragNotCalled() {
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-
-        val down = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(
-            listOf(
-                down.moveBy(
-                    Duration(milliseconds = 10),
-                    TestTouchSlop.toFloat(),
-                    TestTouchSlop.toFloat()
-                )
-            )
-        )
-
-        assertThat(log.filter { it.methodName == "onStart" }).hasSize(0)
-        assertThat(log.filter { it.methodName == "onDrag" }).hasSize(0)
-    }
-
-    @Test
-    fun pointerInputHandler_moveBeyondSlopInUnsupportedDirection_onStartAndOnDragNotCalled() {
-        val beyondSlop = (TestTouchSlop + 1).toFloat()
-        recognizer.canDrag = MockCanDrag(arrayOf(), log)
-        recognizer.dragObserver = MockDragObserver(log)
-
-        val down = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(
-            listOf(
-                down.moveBy(
-                    Duration(milliseconds = 10),
-                    beyondSlop,
-                    beyondSlop
-                )
-            )
-        )
-
-        assertThat(log.filter { it.methodName == "onStart" }).hasSize(0)
-        assertThat(log.filter { it.methodName == "onDrag" }).hasSize(0)
-    }
-
-    // TODO(b/129701831): This test assumes that if a pointer moves by slop in both x and y, we are
-    // still under slop even though sqrt(slop^2 + slop^2) > slop.  This may be inaccurate and this
-    // test may therefore need to be updated.
-    @Test
-    fun pointerInputHandler_moveAroundWithinSlop_onStartAndOnDragNotCalled() {
-        val slop = TestTouchSlop.toFloat()
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-
-        var change = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        // Go around the border of the touch slop area
-
-        // To top left
-        change = change.moveTo(10L.millisecondsToTimestamp(), -slop, -slop)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        // To bottom left
-        change = change.moveTo(20L.millisecondsToTimestamp(), -slop, slop)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        // To bottom right
-        change = change.moveTo(30L.millisecondsToTimestamp(), slop, slop)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        // To top right
-        change = change.moveTo(40L.millisecondsToTimestamp(), slop, -slop)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        // Jump from corner to opposite corner and back
-
-        // To bottom left
-        change = change.moveTo(50L.millisecondsToTimestamp(), -slop, slop)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        // To top right
-        change = change.moveTo(60L.millisecondsToTimestamp(), slop, -slop)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        // Move the other diagonal
-
-        // To top left
-        change = change.moveTo(70L.millisecondsToTimestamp(), -slop, -slop)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        // Jump from corner to opposite corner and back
-
-        // To bottom right
-        change = change.moveTo(80L.millisecondsToTimestamp(), slop, slop)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        // To top left
-        change = change.moveTo(90L.millisecondsToTimestamp(), -slop, -slop)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        assertThat(log.filter { it.methodName == "onStart" }).hasSize(0)
-        assertThat(log.filter { it.methodName == "onDrag" }).hasSize(0)
-    }
-
-    // Verify the circumstances under which onStart and OnDrag should be called.
-
-    @Test
-    fun pointerInputHandler_movePassedSlop_onStartCalledOnceAndOnDragAtLeastOnce() {
-        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-        val down = down()
-
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(
-            listOf(
-                down.moveBy(
-                    Duration(milliseconds = 100),
-                    beyondTouchSlop,
-                    0f
-                )
-            )
-        )
-
-        assertThat(log.filter { it.methodName == "onStart" }).hasSize(1)
-        assertThat(log.filter { it.methodName == "onDrag" }).isNotEmpty()
-    }
-
-    @Test
-    fun pointerInputHandler_passSlopThenInSlopAreaThenOut_onStartCalledOnceAndOnDragAtLeastOnce() {
-        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-
-        var event = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(event))
-        // Out of touch slop region
-        event = event.moveBy(Duration(milliseconds = 10), 0f, beyondTouchSlop)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(event))
-        // Back into touch slop region
-        event = event.moveBy(Duration(milliseconds = 10), 0f, -beyondTouchSlop)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(event))
-        // Out of touch slop region again
-        event = event.moveBy(Duration(milliseconds = 10), 0f, beyondTouchSlop)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(event))
-
-        assertThat(log.filter { it.methodName == "onStart" }).hasSize(1)
-        assertThat(log.filter { it.methodName == "onDrag" }).isNotEmpty()
-    }
-
-    @Test
-    fun pointerInputHandler_downConsumedMovePassedSlop_onStartCalled1AndOnDragCalledAtLeast1() {
-        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-        val down = down().consumeDownChange()
-
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(
-            listOf(
-                down.moveBy(
-                    Duration(milliseconds = 100),
-                    beyondTouchSlop,
-                    0f
-                )
-            )
-        )
-
-        assertThat(log.filter { it.methodName == "onStart" }).hasSize(1)
-        assertThat(log.filter { it.methodName == "onDrag" }).isNotEmpty()
-    }
-
-    @Test
-    fun pointerInputHandler_beyondInUnsupportThenBeyondInSupport_onStart1AndOnDragAtLeast1() {
-        val doubleTouchSlop = (TestTouchSlop * 2).toFloat()
-        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
-        recognizer.canDrag = MockCanDrag(arrayOf(Direction.UP), log)
-        recognizer.dragObserver = MockDragObserver(log)
-
-        var change = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveBy(
-            Duration(milliseconds = 10),
-            0f,
-            doubleTouchSlop
-        )
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveBy(
-            Duration(milliseconds = 10),
-            0f,
-            -beyondTouchSlop
-        )
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        assertThat(log.filter { it.methodName == "onStart" }).hasSize(1)
-        assertThat(log.filter { it.methodName == "onDrag" }).isNotEmpty()
-    }
-
-    // Verify the circumstances under which onStart should be called, but onDrag shouldn't.
-
-    @Test
-    fun pointerInputHandler_moveBeyondSlopInOppositDirections_onStartCalled1AndOnDragNotCalled() {
-        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-        val down1 = down()
-        val down2 = down()
-
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down1, down2))
-        recognizer.pointerInputHandler.invokeOverAllPasses(
-            listOf(
-                down1.moveBy(
-                    Duration(milliseconds = 100),
-                    beyondTouchSlop,
-                    0f
-                ),
-                down2.moveBy(
-                    Duration(milliseconds = 100),
-                    -beyondTouchSlop,
-                    0f
-                )
-            )
-        )
-
-        assertThat(log.filter { it.methodName == "onStart" }).hasSize(1)
-        assertThat(log.filter { it.methodName == "onDrag" }).isEmpty()
-    }
-
-    // onDrag not called when movement averages to 0 in x and y.
-
-    @Test
-    fun pointerInputHandler_2PointsMoveInOpposite_onDragNotCalled() {
-
-        // Arrange
-
-        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-
-        var pointer1 = down()
-        var pointer2 = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer1, pointer2))
-        pointer1 = pointer1.moveBy(
-            Duration(milliseconds = 100),
-            beyondTouchSlop,
-            0f
-        )
-        pointer2 = pointer2.moveBy(
-            Duration(milliseconds = 100),
-            beyondTouchSlop,
-            0f
-        )
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer1, pointer2))
-
-        log.clear()
-
-        // Act
-
-        pointer1 = pointer1.moveBy(
-            Duration(milliseconds = 100),
-            1f,
-            1f
-        )
-        pointer2 = pointer2.moveBy(
-            Duration(milliseconds = 100),
-            -1f,
-            -1f
-        )
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer1, pointer2))
-
-        assertThat(log.filter { it.methodName == "onDrag" }).isEmpty()
-    }
-
-    @Test
-    fun pointerInputHandler_3PointsMoveAverage0_onDragNotCalled() {
-
-        // Arrange
-
-        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-
-        val pointers = arrayListOf(down(), down(), down())
-        recognizer.pointerInputHandler.invokeOverAllPasses(pointers)
-
-        pointers.forEachIndexed { index, pointerInputChange ->
-            pointers[index] =
-                pointerInputChange.moveBy(
-                    Duration(milliseconds = 100),
-                    beyondTouchSlop,
-                    0f
-                )
-        }
-        recognizer.pointerInputHandler.invokeOverAllPasses(pointers)
-        log.clear()
-
-        // Act
-
-        // These movements average to no movement.
-        pointers[0] =
-            pointers[0].moveBy(
-                Duration(milliseconds = 100),
-                -1f,
-                -1f
-            )
-        pointers[1] =
-            pointers[1].moveBy(
-                Duration(milliseconds = 100),
-                1f,
-                -1f
-            )
-        pointers[2] =
-            pointers[2].moveBy(
-                Duration(milliseconds = 100),
-                0f,
-                2f
-            )
-        recognizer.pointerInputHandler.invokeOverAllPasses(pointers)
-
-        // Assert
-
-        assertThat(log.filter { it.methodName == "onDrag" }).isEmpty()
-    }
-
-    // onDrag called with correct values verification
-
-    @Test
-    fun pointerInputHandler_justPassedSlop_onDragCalledWithTotalDistance() {
-        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-
-        var change = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveBy(
-            Duration(milliseconds = 100),
-            beyondTouchSlop,
-            0f
-        )
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        assertThat(log).contains(LogItem("onDrag", pxPosition = PxPosition(11.px, 0.px)))
-    }
-
-    @Test
-    fun pointerInputHandler_moveAndMoveConsumed_onDragCalledWithCorrectDistance() {
-        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-
-        var change = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveBy(Duration(milliseconds = 100), beyondTouchSlop, 0f)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveBy(Duration(milliseconds = 100), 3f, -5f)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveBy(Duration(milliseconds = 100), -3f, 7f)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveBy(Duration(milliseconds = 100), 11f, 13f)
-            .consumePositionChange(5.px, 3.px)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveBy(Duration(milliseconds = 100), -13f, -11f)
-            .consumePositionChange(-3.px, -5.px)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        val onDragLog = log.filter { it.methodName == "onDrag" }
-        // 2 onDrags per event because DragGestureDetector calls onDrag on both PostUp and PostDown.
-        assertThat(onDragLog).hasSize(10)
-        assertThat(onDragLog[0].pxPosition).isEqualTo(PxPosition(11.px, 0.px))
-        assertThat(onDragLog[1].pxPosition).isEqualTo(PxPosition(11.px, 0.px))
-        assertThat(onDragLog[2].pxPosition).isEqualTo(PxPosition(3.px, -5.px))
-        assertThat(onDragLog[3].pxPosition).isEqualTo(PxPosition(3.px, -5.px))
-        assertThat(onDragLog[4].pxPosition).isEqualTo(PxPosition(-3.px, 7.px))
-        assertThat(onDragLog[5].pxPosition).isEqualTo(PxPosition(-3.px, 7.px))
-        assertThat(onDragLog[6].pxPosition).isEqualTo(PxPosition(6.px, 10.px))
-        assertThat(onDragLog[7].pxPosition).isEqualTo(PxPosition(6.px, 10.px))
-        assertThat(onDragLog[8].pxPosition).isEqualTo(PxPosition((-10).px, -6.px))
-        assertThat(onDragLog[9].pxPosition).isEqualTo(PxPosition((-10).px, -6.px))
-    }
-
-    @Test
-    fun pointerInputHandler_3Down1Moves_onDragCalledWith3rdOfDistance() {
-
-        // Arrange
-
-        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
-        val thirdDistance1 = beyondTouchSlop
-        val thirdDistance2 = beyondTouchSlop * 2
-        val distance1 = thirdDistance1 * 3
-        val distance2 = thirdDistance2 * 3
-
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-
-        var pointer1 = down()
-        val pointer2 = down()
-        val pointer3 = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer1, pointer2, pointer3))
-
-        pointer1 = pointer1.moveBy(100.milliseconds, distance1, distance2)
-
-        // Act
-
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer1, pointer2, pointer3))
-
-        // Assert
-
-        val onDragLog = log.filter { it.methodName == "onDrag" }
-        assertThat(onDragLog).hasSize(2)
-        // 2 onDrags because DragGestureDetector calls onDrag on both PostUp and PostDown.
-        assertThat(onDragLog[0].pxPosition).isEqualTo(
-            PxPosition(
-                thirdDistance1.px,
-                thirdDistance2.px
-            )
-        )
-        assertThat(onDragLog[1].pxPosition).isEqualTo(
-            PxPosition(
-                thirdDistance1.px,
-                thirdDistance2.px
-            )
-        )
-    }
-
-    // onStop not called verification
-
-    @Test
-    fun pointerInputHandler_downMoveWithinSlopUp_onStopNotCalled() {
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-
-        var change = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveTo(
-            10L.millisecondsToTimestamp(),
-            TestTouchSlop.toFloat(),
-            TestTouchSlop.toFloat()
-        )
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.up(20L.millisecondsToTimestamp())
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        assertThat(log.filter { it.methodName == "onStop" }).hasSize(0)
-    }
-
-    @Test
-    fun pointerInputHandler_downMoveBeyondSlop_onStopNotCalled() {
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-
-        var change = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveTo(
-            10L.millisecondsToTimestamp(),
-            TestTouchSlop.toFloat() + 1,
-            TestTouchSlop.toFloat()
-        )
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        assertThat(log.filter { it.methodName == "onStop" }).hasSize(0)
-    }
-
-    // onStop called verification
-
-    @Test
-    fun pointerInputHandler_downMoveBeyondSlopUp_onStopCalledOnce() {
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-
-        var change = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveTo(
-            10L.millisecondsToTimestamp(),
-            TestTouchSlop.toFloat() + 1,
-            TestTouchSlop.toFloat()
-        )
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.up(20L.millisecondsToTimestamp())
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        assertThat(log.filter { it.methodName == "onStop" }).hasSize(1)
-    }
-
-    // onStop called with correct values verification
-
-    @Test
-    fun pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity() {
-        pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(0f, 1f, 0f, 100f)
-        pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(0f, -1f, 0f, -100f)
-        pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(1f, 0f, 100f, 0f)
-        pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(-1f, 0f, -100f, 0f)
-
-        pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(1f, 1f, 100f, 100f)
-        pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(-1f, 1f, -100f, 100f)
-        pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(1f, -1f, 100f, -100f)
-        pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(-1f, -1f, -100f, -100f)
-    }
-
-    private fun pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(
-        incrementPerMilliX: Float,
-        incrementPerMilliY: Float,
-        expectedPxPerSecondDx: Float,
-        expectedPxPerSecondDy: Float
-    ) {
-        log = mutableListOf()
-        recognizer = DragGestureRecognizer()
-        recognizer.touchSlop = TestTouchSlop.ipx
-        recognizer.canDrag = MockCanDrag(Direction.values(), log)
-        recognizer.dragObserver = MockDragObserver(log)
-
-        var change = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        repeat(11) {
-            change = change.moveBy(
-                Duration(milliseconds = 10),
-                incrementPerMilliX,
-                incrementPerMilliY
-            )
-            recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        }
-
-        change = change.up(20L.millisecondsToTimestamp())
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        val velocity = log.find { it.methodName == "onStop" }!!.pxPosition!!
-        assertThat(velocity.x.value).isWithin(.01f).of(expectedPxPerSecondDx)
-        assertThat(velocity.y.value).isWithin(.01f).of(expectedPxPerSecondDy)
-    }
-
-    // Verification that callbacks occur in the correct order
-
-    @Test
-    fun pointerInputHandler_downMoveBeyondSlopUp_callBacksOccurInCorrectOrder() {
-        recognizer.canDrag = MockCanDrag(arrayOf(Direction.DOWN), log)
-        recognizer.dragObserver = MockDragObserver(log)
-
-        var change = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveTo(
-            10L.millisecondsToTimestamp(),
-            TestTouchSlop.toFloat(),
-            TestTouchSlop.toFloat() + 1
-        )
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.up(20L.millisecondsToTimestamp())
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        assertThat(log).hasSize(6)
-        assertThat(log[0].methodName).isEqualTo("canDrag")
-        assertThat(log[1].methodName).isEqualTo("canDrag")
-        assertThat(log[2].methodName).isEqualTo("onStart")
-        // 2 onDrags because DragGestureDetector calls onDrag on both PostUp and PostDown.
-        assertThat(log[3].methodName).isEqualTo("onDrag")
-        assertThat(log[4].methodName).isEqualTo("onDrag")
-        assertThat(log[5].methodName).isEqualTo("onStop")
-    }
-
-    // Verification about what events are, or aren't consumed.
-
-    @Test
-    fun pointerInputHandler_down_downNotConsumed() {
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-
-        val result = recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down()))
-
-        assertThat(result.first().consumed.downChange).isFalse()
-    }
-
-    @Test
-    fun pointerInputHandler_downMoveWithinTouchSlop_distanceChangeNotConsumed() {
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-
-        var change = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveTo(
-            10L.millisecondsToTimestamp(),
-            TestTouchSlop.toFloat(),
-            TestTouchSlop.toFloat()
-        )
-        val result = recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        assertThat(result.first().anyPositionChangeConsumed()).isFalse()
-    }
-
-    @Test
-    fun pointerInputHandler_downMoveBeyondSlopInUnsupportedDirection_distanceChangeNotConsumed() {
-        recognizer.canDrag = MockCanDrag(arrayOf(), log)
-        recognizer.dragObserver = MockDragObserver(log)
-
-        var change = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveTo(
-            10L.millisecondsToTimestamp(),
-            TestTouchSlop.toFloat() + 1,
-            TestTouchSlop.toFloat() + 1
-        )
-        val result = recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        assertThat(result.first().anyPositionChangeConsumed()).isFalse()
-    }
-
-    @Test
-    fun pointerInputHandler_doneMoveCallBackDoesNotConsume_distanceChangeNotConsumed() {
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-
-        var change = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveTo(
-            10L.millisecondsToTimestamp(),
-            TestTouchSlop.toFloat() + 1,
-            TestTouchSlop.toFloat() + 1
-        )
-        val result = recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        assertThat(result.first().anyPositionChangeConsumed()).isFalse()
-    }
-
-    @Test
-    fun pointerInputHandler_moveOccursObserverDoesNotOverrideOnDrag_distanceChangeNotConsumed() {
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = object : DragObserver {}
-
-        var change = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveTo(
-            10L.millisecondsToTimestamp(),
-            TestTouchSlop.toFloat() + 1,
-            TestTouchSlop.toFloat() + 1
-        )
-        val result = recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        assertThat(result.first().anyPositionChangeConsumed()).isFalse()
-    }
-
-    @Test
-    fun pointerInputHandler_moveOccursObserverNotSet_distanceChangeNotConsumed() {
-        recognizer.canDrag = canDragMockTrue
-
-        var change = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveTo(
-            10L.millisecondsToTimestamp(),
-            TestTouchSlop.toFloat() + 1,
-            TestTouchSlop.toFloat() + 1
-        )
-        val result = recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        assertThat(result.first().anyPositionChangeConsumed()).isFalse()
-    }
-
-    @Test
-    fun pointerInputHandler_moveCallBackConsumes_changeDistanceConsumedByCorrectAmount() {
-        val thirdTouchSlop = TestTouchSlop.toFloat() / 3
-        val quarterTouchSlop = TestTouchSlop.toFloat() / 4
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver =
-            MockDragObserver(log, PxPosition(thirdTouchSlop.px, quarterTouchSlop.px))
-
-        var change = down()
-        recognizer.pointerInputHandler.invoke(listOf(change), PointerEventPass.PostUp)
-        change = change.moveTo(
-            10L.millisecondsToTimestamp(),
-            TestTouchSlop.toFloat() + 1,
-            TestTouchSlop.toFloat() + 1
-        )
-        val result = recognizer.pointerInputHandler.invoke(listOf(change), PointerEventPass.PostUp)
-
-        assertThat(result.first().consumed.positionChange.x.value).isEqualTo(thirdTouchSlop)
-        assertThat(result.first().consumed.positionChange.y.value).isEqualTo(quarterTouchSlop)
-    }
-
-    @Test
-    fun pointerInputHandler_onStopConsumesUp() {
-        recognizer.canDrag = canDragMockTrue
-        recognizer.dragObserver = MockDragObserver(log)
-
-        var change = down()
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.moveTo(
-            10L.millisecondsToTimestamp(),
-            TestTouchSlop.toFloat() + 1,
-            TestTouchSlop.toFloat()
-        )
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-        change = change.up(20L.millisecondsToTimestamp())
-        val result = recognizer.pointerInputHandler.invokeOverAllPasses(listOf(change))
-
-        assertThat(result.first().consumed.downChange).isTrue()
-    }
-
-    class MockCanDrag(
-        private val directionsToReturnTrue: Array<Direction>,
-        private val log: MutableList<LogItem>
-    ) :
-            (Direction) -> Boolean {
-        override fun invoke(direction: Direction): Boolean {
-            log.add(LogItem("canDrag", direction = direction))
-            return directionsToReturnTrue.contains(direction)
-        }
-    }
-
-    data class LogItem(
-        val methodName: String,
-        val direction: Direction? = null,
-        val pxPosition: PxPosition? = null
-    )
-
-    class MockDragObserver(
-        private val log: MutableList<LogItem>,
-        private var dragConsume: PxPosition = PxPosition.Origin
-    ) : DragObserver {
-        override fun onStart() {
-            log.add(LogItem("onStart"))
-            super.onStart()
-        }
-
-        override fun onDrag(dragDistance: PxPosition): PxPosition {
-            log.add(LogItem("onDrag", pxPosition = dragDistance))
-            return dragConsume
-        }
-
-        override fun onStop(velocity: PxPosition) {
-            log.add(LogItem("onStop", pxPosition = velocity))
-            super.onStop(velocity)
-        }
-    }
-}
\ No newline at end of file
diff --git a/ui/ui-framework/src/test/java/androidx/ui/core/gesture/LongPressGestureDetectorTest.kt b/ui/ui-framework/src/test/java/androidx/ui/core/gesture/LongPressGestureDetectorTest.kt
index 45c5d9f..ff0deb3 100644
--- a/ui/ui-framework/src/test/java/androidx/ui/core/gesture/LongPressGestureDetectorTest.kt
+++ b/ui/ui-framework/src/test/java/androidx/ui/core/gesture/LongPressGestureDetectorTest.kt
@@ -47,12 +47,13 @@
 
     private val LongPressTimeoutMillis = 100.milliseconds
     private val testContext = TestCoroutineContext()
-    private val listener: (PxPosition) -> Unit = mock()
+    private val onLongPress: (PxPosition) -> Unit = mock()
     private lateinit var mRecognizer: LongPressGestureRecognizer
 
     @Before
     fun setup() {
-        mRecognizer = LongPressGestureRecognizer(listener, testContext)
+        mRecognizer = LongPressGestureRecognizer(testContext)
+        mRecognizer.onLongPress = onLongPress
         mRecognizer.longPressTimeout = LongPressTimeoutMillis
     }
 
@@ -61,14 +62,14 @@
     @Test
     fun pointerInputHandler_down_onLongPressNotCalled() {
         mRecognizer.pointerInputHandler.invokeOverAllPasses(listOf(down()))
-        verify(mRecognizer.onLongPress, never()).invoke(any())
+        verify(onLongPress, never()).invoke(any())
     }
 
     @Test
     fun pointerInputHandler_downWithinTimeout_onLongPressNotCalled() {
         mRecognizer.pointerInputHandler.invokeOverAllPasses(listOf(down()))
         testContext.advanceTimeBy(99, TimeUnit.MILLISECONDS)
-        verify(mRecognizer.onLongPress, never()).invoke(any())
+        verify(onLongPress, never()).invoke(any())
     }
 
     @Test
@@ -81,7 +82,7 @@
         mRecognizer.pointerInputHandler.invokeOverAllPasses(listOf(move))
         testContext.advanceTimeBy(50, TimeUnit.MILLISECONDS)
 
-        verify(mRecognizer.onLongPress, never()).invoke(any())
+        verify(onLongPress, never()).invoke(any())
     }
 
     @Test
@@ -96,7 +97,7 @@
         mRecognizer.pointerInputHandler.invokeOverAllPasses(listOf(move0, move1))
         testContext.advanceTimeBy(50, TimeUnit.MILLISECONDS)
 
-        verify(mRecognizer.onLongPress, never()).invoke(any())
+        verify(onLongPress, never()).invoke(any())
     }
 
     @Test
@@ -109,7 +110,7 @@
         mRecognizer.pointerInputHandler.invokeOverAllPasses(listOf(up))
         testContext.advanceTimeBy(50, TimeUnit.MILLISECONDS)
 
-        verify(mRecognizer.onLongPress, never()).invoke(any())
+        verify(onLongPress, never()).invoke(any())
     }
 
     @Test
@@ -122,7 +123,7 @@
         mRecognizer.pointerInputHandler.invokeOverAllPasses(listOf(up))
         testContext.advanceTimeBy(50, TimeUnit.MILLISECONDS)
 
-        verify(mRecognizer.onLongPress, never()).invoke(any())
+        verify(onLongPress, never()).invoke(any())
     }
 
     @Test
@@ -156,7 +157,7 @@
 
         // Assert
 
-        verify(mRecognizer.onLongPress, never()).invoke(any())
+        verify(onLongPress, never()).invoke(any())
     }
 
     // Tests that verify conditions under which onLongPress will be called.
@@ -165,14 +166,14 @@
     fun pointerInputHandler_downBeyondTimeout_onLongPressCalled() {
         mRecognizer.pointerInputHandler.invokeOverAllPasses(listOf(down()))
         testContext.advanceTimeBy(100, TimeUnit.MILLISECONDS)
-        verify(mRecognizer.onLongPress).invoke(any())
+        verify(onLongPress).invoke(any())
     }
 
     @Test
     fun pointerInputHandler_2DownBeyondTimeout_onLongPressCalled() {
         mRecognizer.pointerInputHandler.invokeOverAllPasses(listOf(down(0), down(1)))
         testContext.advanceTimeBy(100, TimeUnit.MILLISECONDS)
-        verify(mRecognizer.onLongPress).invoke(any())
+        verify(onLongPress).invoke(any())
     }
 
     @Test
@@ -208,7 +209,7 @@
 
         // Assert
 
-        verify(mRecognizer.onLongPress).invoke(any())
+        verify(onLongPress).invoke(any())
     }
 
     @Test
@@ -221,7 +222,7 @@
         mRecognizer.pointerInputHandler.invokeOverAllPasses(listOf(move))
         testContext.advanceTimeBy(50, TimeUnit.MILLISECONDS)
 
-        verify(mRecognizer.onLongPress).invoke(any())
+        verify(onLongPress).invoke(any())
     }
 
     // Tests that verify correctness of PxPosition value passed to onLongPress
@@ -233,7 +234,7 @@
         mRecognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
         testContext.advanceTimeBy(100, TimeUnit.MILLISECONDS)
 
-        verify(mRecognizer.onLongPress).invoke(PxPosition(13.px, 17.px))
+        verify(onLongPress).invoke(PxPosition(13.px, 17.px))
     }
 
     @Test
@@ -246,7 +247,7 @@
         mRecognizer.pointerInputHandler.invokeOverAllPasses(listOf(move))
         testContext.advanceTimeBy(50, TimeUnit.MILLISECONDS)
 
-        verify(mRecognizer.onLongPress).invoke(PxPosition((-7).px, 5.px))
+        verify(onLongPress).invoke(PxPosition((-7).px, 5.px))
     }
 
     @Test
@@ -261,7 +262,7 @@
         mRecognizer.pointerInputHandler.invokeOverAllPasses(listOf(move0, down1))
         testContext.advanceTimeBy(50, TimeUnit.MILLISECONDS)
 
-        verify(mRecognizer.onLongPress).invoke(PxPosition(13.px, 17.px))
+        verify(onLongPress).invoke(PxPosition(13.px, 17.px))
     }
 
     @Test
@@ -281,7 +282,7 @@
         mRecognizer.pointerInputHandler.invokeOverAllPasses(listOf(up0, move1))
         testContext.advanceTimeBy(25, TimeUnit.MILLISECONDS)
 
-        verify(mRecognizer.onLongPress).invoke(PxPosition(11.px, 19.px))
+        verify(onLongPress).invoke(PxPosition(11.px, 19.px))
     }
 
     @Test
@@ -296,7 +297,7 @@
         mRecognizer.pointerInputHandler.invokeOverAllPasses(listOf(move0, down1))
         testContext.advanceTimeBy(50, TimeUnit.MILLISECONDS)
 
-        verify(mRecognizer.onLongPress).invoke(PxPosition(27.px, 29.px))
+        verify(onLongPress).invoke(PxPosition(27.px, 29.px))
     }
 
     @Test
@@ -316,7 +317,7 @@
         mRecognizer.pointerInputHandler.invokeOverAllPasses(listOf(up0, move1))
         testContext.advanceTimeBy(50, TimeUnit.MILLISECONDS)
 
-        verify(mRecognizer.onLongPress).invoke(PxPosition(27.px, 23.px))
+        verify(onLongPress).invoke(PxPosition(27.px, 23.px))
     }
 
     // Tests that verify that consumption behavior
diff --git a/ui/ui-framework/src/test/java/androidx/ui/core/gesture/PressIndicatorGestureDetectorTest.kt b/ui/ui-framework/src/test/java/androidx/ui/core/gesture/PressIndicatorGestureDetectorTest.kt
index 7b0d0fb..9330cd9 100644
--- a/ui/ui-framework/src/test/java/androidx/ui/core/gesture/PressIndicatorGestureDetectorTest.kt
+++ b/ui/ui-framework/src/test/java/androidx/ui/core/gesture/PressIndicatorGestureDetectorTest.kt
@@ -19,12 +19,14 @@
 import androidx.ui.core.PointerEventPass
 import androidx.ui.core.PxPosition
 import androidx.ui.core.consumeDownChange
+import androidx.ui.core.milliseconds
 import androidx.ui.core.millisecondsToTimestamp
 import androidx.ui.core.px
 import androidx.ui.testutils.consume
 import androidx.ui.testutils.down
 import androidx.ui.testutils.invokeOverAllPasses
 import androidx.ui.testutils.invokeOverPasses
+import androidx.ui.testutils.moveBy
 import androidx.ui.testutils.moveTo
 import androidx.ui.testutils.up
 import com.nhaarman.mockitokotlin2.any
@@ -38,17 +40,12 @@
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
 
+// TODO(shepshapard): Write tests that verify consumption behavior that blocks ancestors and descendants.
+
 @RunWith(JUnit4::class)
 class PressIndicatorGestureDetectorTest {
 
     private lateinit var recognizer: PressIndicatorGestureRecognizer
-    private val down = down(0)
-    private val downConsumed = down.consumeDownChange()
-    private val move = down.moveTo(100L.millisecondsToTimestamp(), x = 100f)
-    private val moveConsumed = move.consume(dx = 1f)
-    private val up = down.up(100L.millisecondsToTimestamp())
-    private val upConsumed = up.consumeDownChange()
-    private val upAfterMove = move.up(200L.millisecondsToTimestamp())
 
     @Before
     fun setup() {
@@ -58,192 +55,242 @@
         recognizer.onCancel = mock()
     }
 
+    // Verification of scenarios where onStart should not be called.
+
+    @Test
+    fun pointerInputHandler_downConsumed_onStartNotCalled() {
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down().consumeDownChange()))
+        verify(recognizer.onStart!!, never()).invoke(any())
+    }
+
+    // Verification of scenarios where onStart should be called once.
+
     @Test
     fun pointerInputHandler_down_onStartCalledOnce() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down()))
         verify(recognizer.onStart!!).invoke(any())
     }
 
     @Test
     fun pointerInputHandler_downDown_onStartCalledOnce() {
-        val down0 = down(0)
-        val down1 = down(1)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down0))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down1))
+        var pointer0 = down(0)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer0))
+        pointer0 = pointer0.moveTo(timestamp = 1L.millisecondsToTimestamp())
+        val pointer1 = down(1, timestamp = 1L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer0, pointer1))
+
         verify(recognizer.onStart!!).invoke(any())
     }
 
     @Test
-    fun pointerInputHandler_downDownUpDown_onStartCalledOnce() {
-        val down0 = down(0)
-        val down1 = down(1)
-        val up0 = down1.up(100L.millisecondsToTimestamp())
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down0))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down1))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(up0))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down0))
+    fun pointerInputHandler_2Down1Up1Down_onStartCalledOnce() {
+        var pointer0 = down(0)
+        var pointer1 = down(1)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer0, pointer1))
+        pointer0 = pointer0.up(100L.millisecondsToTimestamp())
+        pointer1 = pointer1.moveTo(100L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer0, pointer1))
+        pointer0 = down(0, 200L.millisecondsToTimestamp())
+        pointer1 = pointer1.moveTo(200L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer0, pointer1))
+
         verify(recognizer.onStart!!).invoke(any())
     }
 
-    @Test
-    fun pointerInputHandler_downChangeConsumedDuringPostUp() {
-        var pointerEventChange = down
-        pointerEventChange = recognizer.pointerInputHandler.invokeOverPasses(
-            listOf(pointerEventChange),
-            PointerEventPass.InitialDown,
-            PointerEventPass.PreUp,
-            PointerEventPass.PreDown).first()
-        assertThat(pointerEventChange.consumed.downChange, `is`(false))
-
-        pointerEventChange = recognizer.pointerInputHandler.invoke(
-            listOf(pointerEventChange),
-            PointerEventPass.PostUp).first()
-        assertThat(pointerEventChange.consumed.downChange, `is`(true))
-    }
-
-    @Test
-    fun pointerInputHandler_downConsumed_onStartNotCalled() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down.consumeDownChange()))
-        verify(recognizer.onStart!!, never()).invoke(any())
-    }
-
-    @Test
-    fun pointerInputHandler_downUp_onStopCalledOnce() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(up))
-        verify(recognizer.onStop!!).invoke()
-    }
-
-    @Test
-    fun pointerInputHandler_downUpConsumed_onStopCalledOnce() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(upConsumed))
-        verify(recognizer.onStop!!).invoke()
-    }
-
-    @Test
-    fun pointerInputHandler_downMoveUp_onStopCalledOnce() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(move))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(upAfterMove))
-        verify(recognizer.onStop!!).invoke()
-    }
-
-    @Test
-    fun pointerInputHandler_downDownUpUp_onStopCalledOnce() {
-        val down0 = down(0)
-        val down1 = down(1)
-        val up0 = down0.up(100L.millisecondsToTimestamp())
-        val up1 = down1.up(100L.millisecondsToTimestamp())
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down0))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down1))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(up0))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(up1))
-        verify(recognizer.onStop!!).invoke()
-    }
+    // Verification of scenarios where onStop should not be called.
 
     @Test
     fun pointerInputHandler_downMoveConsumedUp_onStopNotCalled() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(moveConsumed))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(upAfterMove))
+        var pointer = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.moveTo(100L.millisecondsToTimestamp(), 5f).consume(1f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.up(200L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+
         verify(recognizer.onStop!!, never()).invoke()
     }
 
     @Test
     fun pointerInputHandler_downConsumedUp_onStopNotCalled() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(downConsumed))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(up))
+        var pointer = down().consumeDownChange()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.up(100L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+
         verify(recognizer.onStop!!, never()).invoke()
     }
 
     @Test
-    fun pointerInputHandler_downConsumedMoveConsumed_onStopNotCalled() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(downConsumed))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(moveConsumed))
+    fun pointerInputHandler_2DownUp_onStopNotCalled() {
+        var pointer0 = down(0)
+        var pointer1 = down(1)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer0, pointer1))
+        pointer0 = pointer0.moveTo(100L.millisecondsToTimestamp())
+        pointer1 = pointer1.up(100L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer0, pointer1))
+
         verify(recognizer.onStop!!, never()).invoke()
     }
 
+    // Verification of scenarios where onStop should be called once.
+
     @Test
-    fun pointerInputHandler_downDownUp_onStopNotCalled() {
-        val down0 = down(0)
-        val down1 = down(1)
-        val up0 = down0.up(100L.millisecondsToTimestamp())
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down0))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down1))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(up0))
-        verify(recognizer.onStop!!, never()).invoke()
+    fun pointerInputHandler_downUp_onStopCalledOnce() {
+        var pointer = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.up(100L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+
+        verify(recognizer.onStop!!).invoke()
     }
 
     @Test
-    fun pointerInputHandler_downMoveConsumed_onCancelCalledOnce() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(moveConsumed))
-        verify(recognizer.onCancel!!).invoke()
+    fun pointerInputHandler_downUpConsumed_onStopCalledOnce() {
+        var pointer = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.up(100L.millisecondsToTimestamp()).consumeDownChange()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+
+        verify(recognizer.onStop!!).invoke()
     }
 
     @Test
-    fun pointerInputHandler_downMoveConsumedMoveConsumed_onCancelCalledOnce() {
-        val down = down(x = 0f)
-        val move1 = down.moveTo(timestamp = 100L.millisecondsToTimestamp(), x = 5f)
-        val move2 = move1.moveTo(timestamp = 200L.millisecondsToTimestamp(), x = 10f)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(move1.consume(dx = 1f)))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(move2.consume(dx = 1f)))
-        verify(recognizer.onCancel!!).invoke()
+    fun pointerInputHandler_downMoveUp_onStopCalledOnce() {
+        var pointer = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.moveTo(100L.millisecondsToTimestamp(), 5f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.up(200L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+
+        verify(recognizer.onStop!!).invoke()
     }
 
     @Test
-    fun pointerInputHandler_downDownMoveConsumedMoveConsumed_onCancelCalledOnce() {
-        val down1 = down(x = 0f)
-        val down2 = down(x = 100f)
-        val move1 = down1.moveTo(timestamp = 100L.millisecondsToTimestamp(), x = 5f)
-        val move2 = down2.moveTo(timestamp = 100L.millisecondsToTimestamp(), x = 105f)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down1))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down2))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(move1.consume(dx = 1f)))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(move2.consume(dx = 1f)))
-        verify(recognizer.onCancel!!).invoke()
+    fun pointerInputHandler_2Down2Up_onStopCalledOnce() {
+        var pointer1 = down(0)
+        var pointer2 = down(1)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer1, pointer2))
+        pointer1 = pointer1.up(100L.millisecondsToTimestamp())
+        pointer2 = pointer2.up(100L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer1, pointer2))
+
+        verify(recognizer.onStop!!).invoke()
     }
 
-    @Test
-    fun pointerInputHandler_downDownMoveMoveConsumed_onCancelCalledOnce() {
-        val down1 = down(x = 0f)
-        val down2 = down(x = 100f)
-        val move1 = down1.moveTo(timestamp = 100L.millisecondsToTimestamp(), x = 5f)
-        val move2 = down2.moveTo(timestamp = 100L.millisecondsToTimestamp(), x = 105f)
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down1))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down2))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(move1))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(move2.consume(dx = 1f)))
-        verify(recognizer.onCancel!!).invoke()
-    }
+    // Verification of scenarios where onCancel should not be called.
 
     @Test
     fun pointerInputHandler_downConsumedMoveConsumed_onCancelNotCalled() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(downConsumed))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(moveConsumed))
+        var pointer = down().consumeDownChange()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.moveBy(100.milliseconds, 5f).consume(1f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+
         verify(recognizer.onCancel!!, never()).invoke()
     }
 
     @Test
     fun pointerInputHandler_downUp_onCancelNotCalled() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(up))
+        var pointer = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.up(100L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+
         verify(recognizer.onCancel!!, never()).invoke()
     }
 
     @Test
     fun pointerInputHandler_downMoveUp_onCancelNotCalled() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(move))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(upAfterMove))
+        var pointer = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.moveTo(100L.millisecondsToTimestamp(), 5f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.up(100L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+
         verify(recognizer.onCancel!!, never()).invoke()
     }
 
+    // Verification of scenarios where onCancel should be called once.
+
+    @Test
+    fun pointerInputHandler_downMoveConsumed_onCancelCalledOnce() {
+        var pointer = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.moveBy(100.milliseconds, 5f).consume(1f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+
+        verify(recognizer.onCancel!!).invoke()
+    }
+
+    @Test
+    fun pointerInputHandler_downMoveConsumedMoveConsumed_onCancelCalledOnce() {
+        var pointer = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.moveBy(100.milliseconds, 5f).consume(1f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.moveBy(100.milliseconds, 5f).consume(1f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+
+        verify(recognizer.onCancel!!).invoke()
+    }
+
+    @Test
+    fun pointerInputHandler_2Down2MoveConsumed_onCancelCalledOnce() {
+        var pointer0 = down(0)
+        var pointer1 = down(1)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer0, pointer1))
+        pointer0 = pointer0.moveBy(100.milliseconds, 5f).consume(1f)
+        pointer1 = pointer1.moveBy(100.milliseconds, 5f).consume(1f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer0, pointer1))
+
+        verify(recognizer.onCancel!!).invoke()
+    }
+
+    @Test
+    fun pointerInputHandler_2Down1MoveConsumedTheOtherMoveConsume_onCancelCalledOnce() {
+        var pointer0 = down(0)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer0))
+        pointer0 = pointer0.moveTo(100L.millisecondsToTimestamp())
+        var pointer1 = down(1, 100L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer0, pointer1))
+        pointer0 = pointer0.moveBy(100L.milliseconds, 5f).consume(5f)
+        pointer1 = pointer1.moveBy(100L.milliseconds)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer0, pointer1))
+        pointer0 = pointer0.moveBy(100L.milliseconds)
+        pointer1 = pointer1.moveBy(100L.milliseconds, 5f).consume(5f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer0, pointer1))
+
+        verify(recognizer.onCancel!!).invoke()
+    }
+
+    // Verification of correct position returned by onStart.
+
     @Test
     fun pointerInputHandler_down_downPositionIsCorrect() {
         recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down(x = 13f, y = 17f)))
         verify(recognizer.onStart!!).invoke(PxPosition(13.px, 17f.px))
     }
+
+    // Verification of correct consumption behavior.
+
+    @Test
+    fun pointerInputHandler_downChangeConsumedDuringPostUp() {
+        var pointer = down()
+        pointer = recognizer.pointerInputHandler.invokeOverPasses(
+            listOf(pointer),
+            PointerEventPass.InitialDown,
+            PointerEventPass.PreUp,
+            PointerEventPass.PreDown
+        ).first()
+        assertThat(pointer.consumed.downChange, `is`(false))
+
+        pointer = recognizer.pointerInputHandler.invoke(
+            listOf(pointer),
+            PointerEventPass.PostUp
+        ).first()
+        assertThat(pointer.consumed.downChange, `is`(true))
+    }
 }
\ No newline at end of file
diff --git a/ui/ui-framework/src/test/java/androidx/ui/core/gesture/PressReleasedGestureDetectorTest.kt b/ui/ui-framework/src/test/java/androidx/ui/core/gesture/PressReleasedGestureDetectorTest.kt
index d68a73f..d31814b 100644
--- a/ui/ui-framework/src/test/java/androidx/ui/core/gesture/PressReleasedGestureDetectorTest.kt
+++ b/ui/ui-framework/src/test/java/androidx/ui/core/gesture/PressReleasedGestureDetectorTest.kt
@@ -39,13 +39,6 @@
 class PressReleasedGestureDetectorTest {
 
     private lateinit var recognizer: PressReleaseGestureRecognizer
-    private val down = down(0)
-    private val downConsumed = down.consumeDownChange()
-    private val move = down.moveTo(timestamp = 100L.millisecondsToTimestamp(), x = 100f)
-    private val moveConsumed = move.consume(dx = 1f)
-    private val up = down.up(100L.millisecondsToTimestamp())
-    private val upConsumed = up.consumeDownChange()
-    private val upAfterMove = move.up(200L.millisecondsToTimestamp())
 
     @Before
     fun setup() {
@@ -55,97 +48,121 @@
 
     @Test
     fun pointerInputHandler_down_onReleaseNotCalled() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down()))
         verify(recognizer.onRelease!!, never()).invoke()
     }
 
     @Test
     fun pointerInputHandler_downConsumedUp_onReleaseNotCalled() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(downConsumed))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(up))
+        var pointer = down().consumeDownChange()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.up(100L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+
         verify(recognizer.onRelease!!, never()).invoke()
     }
 
     @Test
     fun pointerInputHandler_downMoveConsumedUp_onReleaseNotCalled() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(moveConsumed))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(upAfterMove))
+        var pointer = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.moveTo(100L.millisecondsToTimestamp(), 5f).consume(5f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.up(200L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+
         verify(recognizer.onRelease!!, never()).invoke()
     }
 
     @Test
     fun pointerInputHandler_downUpConsumed_onReleaseNotCalled() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(upConsumed))
+        var pointer = down().consumeDownChange()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.up(100L.millisecondsToTimestamp()).consumeDownChange()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+
         verify(recognizer.onRelease!!, never()).invoke()
     }
 
     @Test
     fun pointerInputHandler_downUp_onReleaseCalledOnce() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(up))
+        var pointer = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.up(100L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+
         verify(recognizer.onRelease!!).invoke()
     }
 
     @Test
     fun pointerInputHandler_downMoveUp_onReleaseCalledOnce() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(move))
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(upAfterMove))
+        var pointer = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.moveTo(100L.millisecondsToTimestamp(), 5f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.up(200L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+
         verify(recognizer.onRelease!!).invoke()
     }
 
     @Test
     fun pointerInputHandler_consumeDownOnStartIsDefault_downChangeConsumed() {
-        val pointerEventChange = recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
+        val pointerEventChange = recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down()))
         assertThat(pointerEventChange.first().consumed.downChange, `is`(true))
     }
 
     @Test
     fun pointerInputHandler_consumeDownOnStartIsFalse_downChangeNotConsumed() {
         recognizer.consumeDownOnStart = false
-        val pointerEventChange = recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
+        val pointerEventChange = recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down()))
         assertThat(pointerEventChange.first().consumed.downChange, `is`(false))
     }
 
     @Test
     fun pointerInputHandler_upChangeConsumed() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        val pointerEventChange = recognizer.pointerInputHandler.invokeOverAllPasses(listOf(up))
+        var pointer = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        pointer = pointer.up(100L.millisecondsToTimestamp())
+        val pointerEventChange = recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
         assertThat(pointerEventChange.first().consumed.downChange, `is`(true))
     }
 
     @Test
     fun pointerInputHandler_downChangeConsumedDuringPostUp() {
-        var pointerEventChange = listOf(down)
+        var pointerEventChange = listOf(down())
         pointerEventChange = recognizer.pointerInputHandler.invokeOverPasses(
             pointerEventChange,
             PointerEventPass.InitialDown,
             PointerEventPass.PreUp,
-            PointerEventPass.PreDown)
+            PointerEventPass.PreDown
+        )
         assertThat(pointerEventChange.first().consumed.downChange, `is`(false))
 
         pointerEventChange = recognizer.pointerInputHandler.invoke(
             pointerEventChange,
-            PointerEventPass.PostUp)
+            PointerEventPass.PostUp
+        )
         assertThat(pointerEventChange.first().consumed.downChange, `is`(true))
     }
 
     @Test
     fun pointerInputHandler_upChangeConsumedDuringPostUp() {
-        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(down))
-        var pointerEventChange = listOf(up)
+        val pointer = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(listOf(pointer))
+        var pointerEventChange = listOf(pointer.up(100L.millisecondsToTimestamp()))
         pointerEventChange = recognizer.pointerInputHandler.invokeOverPasses(
             pointerEventChange,
             PointerEventPass.InitialDown,
             PointerEventPass.PreUp,
-            PointerEventPass.PreDown)
+            PointerEventPass.PreDown
+        )
         assertThat(pointerEventChange.first().consumed.downChange, `is`(false))
 
         pointerEventChange = recognizer.pointerInputHandler.invoke(
             pointerEventChange,
-            PointerEventPass.PostUp)
+            PointerEventPass.PostUp
+        )
         assertThat(pointerEventChange.first().consumed.downChange, `is`(true))
     }
 }
\ No newline at end of file
diff --git a/ui/ui-framework/src/test/java/androidx/ui/core/gesture/RawDragGestureDetectorTest.kt b/ui/ui-framework/src/test/java/androidx/ui/core/gesture/RawDragGestureDetectorTest.kt
new file mode 100644
index 0000000..ec59cce
--- /dev/null
+++ b/ui/ui-framework/src/test/java/androidx/ui/core/gesture/RawDragGestureDetectorTest.kt
@@ -0,0 +1,559 @@
+/*
+ * Copyright 2019 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.ui.core.gesture
+
+import androidx.ui.core.Direction
+import androidx.ui.core.Duration
+import androidx.ui.core.PointerEventPass
+import androidx.ui.core.PxPosition
+import androidx.ui.core.anyPositionChangeConsumed
+import androidx.ui.core.consumePositionChange
+import androidx.ui.core.ipx
+import androidx.ui.core.milliseconds
+import androidx.ui.core.millisecondsToTimestamp
+import androidx.ui.core.px
+import androidx.ui.testutils.consume
+import androidx.ui.testutils.down
+import androidx.ui.testutils.invokeOverAllPasses
+import androidx.ui.testutils.moveBy
+import androidx.ui.testutils.moveTo
+import androidx.ui.testutils.up
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+// TODO(shepshapard): Write the following tests.
+// Test for cases where things are reset when last pointer goes up
+// Verify methods called during PostUp and PostDown
+// Verify correct behavior when distance is consumed at different moments between passes.
+// Verify that canStartDragging is only called when it needs to be.
+// Verify correct behavior with no DragBlocker
+
+@RunWith(JUnit4::class)
+class RawDragGestureDetectorTest {
+
+    private lateinit var recognizer: RawDragGestureRecognizer
+    private lateinit var dragObserver: MockDragObserver
+    private lateinit var log: MutableList<LogItem>
+    private var dragStartBlocked = true
+
+    @Before
+    fun setup() {
+        log = mutableListOf()
+        dragObserver = MockDragObserver(log)
+        recognizer = RawDragGestureRecognizer()
+        recognizer.canStartDragging = { !dragStartBlocked }
+        recognizer.dragObserver = dragObserver
+    }
+
+    // Verify the circumstances under which onStart/OnDrag should not be called.
+
+    @Test
+    fun pointerInputHandler_blockedAndMove_onStartAndOnDragNotCalled() {
+
+        val down = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(down)
+        val move = down.moveBy(Duration(milliseconds = 10), 1f, 0f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(move)
+
+        assertThat(log.filter { it.methodName == "onStart" }).isEmpty()
+        assertThat(log.filter { it.methodName == "onDrag" }).isEmpty()
+    }
+
+    @Test
+    fun pointerInputHandler_unblockedNoMove_onStartAndOnDragNotCalled() {
+        val down = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(down)
+        dragStartBlocked = false
+
+        val move = down.moveBy(Duration(milliseconds = 10), 0f, 0f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(move)
+
+        assertThat(log.filter { it.methodName == "onStart" }).isEmpty()
+        assertThat(log.filter { it.methodName == "onDrag" }).isEmpty()
+    }
+
+    @Test
+    fun pointerInputHandler_unblockedMovementConsumed_onStartAndOnDragNotCalled() {
+
+        val down1 = down(1)
+        recognizer.pointerInputHandler.invokeOverAllPasses(down1)
+        dragStartBlocked = false
+
+        val move1 = down1.moveBy(10.milliseconds, 1f, 1f).consume(dx = 1f, dy = 1f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(move1)
+
+        assertThat(log.filter { it.methodName == "onStart" }).isEmpty()
+        assertThat(log.filter { it.methodName == "onDrag" }).isEmpty()
+    }
+
+    @Test
+    fun pointerInputHandler_unblockedMovementIsInOppositeDirections_onStartAndOnDragNotCalled() {
+
+        val down1 = down(1)
+        val down2 = down(2)
+        recognizer.pointerInputHandler.invokeOverAllPasses(down1, down2)
+        dragStartBlocked = false
+
+        val move1 = down1.moveBy(10.milliseconds, 1f, 1f)
+        val move2 = down2.moveBy(10.milliseconds, -1f, -1f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(move1, move2)
+
+        assertThat(log.filter { it.methodName == "onStart" }).isEmpty()
+        assertThat(log.filter { it.methodName == "onDrag" }).isEmpty()
+    }
+
+    @Test
+    fun pointerInputHandler_3PointsMoveAverage0_onStartAndOnDragNotCalled() {
+
+        // Arrange
+
+        val pointers = arrayListOf(down(0), down(1), down(2))
+        recognizer.pointerInputHandler.invokeOverAllPasses(pointers)
+        dragStartBlocked = false
+
+        // Act
+
+        // These movements average to no movement.
+        pointers[0] =
+            pointers[0].moveBy(
+                Duration(milliseconds = 100),
+                -1f,
+                -1f
+            )
+        pointers[1] =
+            pointers[1].moveBy(
+                Duration(milliseconds = 100),
+                1f,
+                -1f
+            )
+        pointers[2] =
+            pointers[2].moveBy(
+                Duration(milliseconds = 100),
+                0f,
+                2f
+            )
+        recognizer.pointerInputHandler.invokeOverAllPasses(pointers)
+
+        // Assert
+        assertThat(log.filter { it.methodName == "onStart" }).isEmpty()
+        assertThat(log.filter { it.methodName == "onDrag" }).isEmpty()
+    }
+
+    // Verify the circumstances under which onStart/OnDrag should be called.
+
+    @Test
+    fun pointerInputHandler_unblockedAndMoveOnX_onStartAndOnDragCalledOnce() {
+
+        val down = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(down)
+        dragStartBlocked = false
+
+        val move = down.moveBy(Duration(milliseconds = 10), 1f, 0f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(move)
+
+        assertThat(log.filter { it.methodName == "onStart" }).hasSize(1)
+        // onDrag get's called twice because it is called during PostUp and PostDown and nothing
+        // consumed the drag distance.
+        assertThat(log.filter { it.methodName == "onDrag" }).hasSize(2)
+    }
+
+    @Test
+    fun pointerInputHandler_unblockedAndMoveOnY_oonStartAndOnDragCalledOnce() {
+
+        val down = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(down)
+        dragStartBlocked = false
+
+        val move = down.moveBy(Duration(milliseconds = 10), 0f, 1f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(move)
+
+        assertThat(log.filter { it.methodName == "onStart" }).hasSize(1)
+        // onDrag get's called twice because it is called during PostUp and PostDown and nothing
+        // consumed the drag distance.
+        assertThat(log.filter { it.methodName == "onDrag" }).hasSize(2)
+    }
+
+    @Test
+    fun pointerInputHandler_unblockedAndMoveConsumedBeyond0_onStartAndOnDragCalledOnce() {
+
+        val down = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(down)
+        dragStartBlocked = false
+
+        val move = down.moveBy(Duration(milliseconds = 10), 1f, 0f).consume(dx = 2f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(move)
+
+        assertThat(log.filter { it.methodName == "onStart" }).hasSize(1)
+        // onDrag get's called twice because it is called during PostUp and PostDown and nothing
+        // consumed the drag distance.
+        assertThat(log.filter { it.methodName == "onDrag" }).hasSize(2)
+    }
+
+    // onDrag called with correct values verification.
+
+    @Test
+    fun pointerInputHandler_unblockedMove_onDragCalledWithTotalDistanceDuringPostUp() {
+        var change = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        dragStartBlocked = false
+
+        change = change.moveBy(100.milliseconds, 5f, -2f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+
+        val onDragLog = log.filter { it.methodName == "onDrag" }
+        assertThat(onDragLog).hasSize(2)
+        // OnDrags get's called twice each time because DragGestureDetector calls it on both PostUp
+        // and PostDown and the distance is not consumed by PostUp.
+        assertThat(onDragLog[0].pxPosition).isEqualTo(PxPosition(5.px, (-2).px))
+        assertThat(onDragLog[1].pxPosition).isEqualTo(PxPosition(5.px, (-2).px))
+    }
+
+    @Test
+    fun pointerInputHandler_unblockedMoveAndMoveConsumed_onDragCalledWithCorrectDistance() {
+
+        // Arrange
+
+        var change = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        dragStartBlocked = false
+
+        // Act
+
+        change = change.moveBy(Duration(milliseconds = 100), 3f, -5f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        change = change.moveBy(Duration(milliseconds = 100), -3f, 7f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        change = change.moveBy(Duration(milliseconds = 100), 11f, 13f)
+            .consumePositionChange(5.px, 3.px)
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        change = change.moveBy(Duration(milliseconds = 100), -13f, -11f)
+            .consumePositionChange((-3).px, (-5).px)
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+
+        // Assert
+
+        val onDragLog = log.filter { it.methodName == "onDrag" }
+        assertThat(onDragLog).hasSize(8)
+        // OnDrags get's called twice each time because DragGestureDetector calls it on both PostUp
+        // and PostDown and the distance is not consumed by PostUp.
+        assertThat(onDragLog[0].pxPosition).isEqualTo(PxPosition(3.px, (-5).px))
+        assertThat(onDragLog[1].pxPosition).isEqualTo(PxPosition(3.px, (-5).px))
+        assertThat(onDragLog[2].pxPosition).isEqualTo(PxPosition((-3).px, 7.px))
+        assertThat(onDragLog[3].pxPosition).isEqualTo(PxPosition((-3).px, 7.px))
+        assertThat(onDragLog[4].pxPosition).isEqualTo(PxPosition(6.px, 10.px))
+        assertThat(onDragLog[5].pxPosition).isEqualTo(PxPosition(6.px, 10.px))
+        assertThat(onDragLog[6].pxPosition).isEqualTo(PxPosition((-10).px, (-6).px))
+        assertThat(onDragLog[7].pxPosition).isEqualTo(PxPosition((-10).px, (-6).px))
+    }
+
+    @Test
+    fun pointerInputHandler_3Down1Moves_onDragCalledWith3rdOfDistance() {
+
+        // Arrange
+
+        var pointer1 = down()
+        var pointer2 = down()
+        var pointer3 = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(pointer1, pointer2, pointer3)
+        dragStartBlocked = false
+
+        pointer1 = pointer1.moveBy(100.milliseconds, 9f, -12f)
+        pointer2 = pointer2.moveBy(100.milliseconds, 0f, 0f)
+        pointer3 = pointer3.moveBy(100.milliseconds, 0f, 0f)
+
+        // Act
+
+        recognizer.pointerInputHandler.invokeOverAllPasses(pointer1, pointer2, pointer3)
+
+        // Assert
+
+        val onDragLog = log.filter { it.methodName == "onDrag" }
+        assertThat(onDragLog).hasSize(2)
+        // 2 onDrags because DragGestureDetector calls onDrag on both PostUp and PostDown and the
+        // distance is never consumed.
+        assertThat(onDragLog[0].pxPosition).isEqualTo(
+            PxPosition(
+                3.px,
+                (-4).px
+            )
+        )
+        assertThat(onDragLog[1].pxPosition).isEqualTo(
+            PxPosition(
+                3.px,
+                (-4).px
+            )
+        )
+    }
+
+    // onStop not called verification
+
+    @Test
+    fun pointerInputHandler_blockedDownMoveUp_onStopNotCalled() {
+        var change = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        change = change.moveTo(10L.millisecondsToTimestamp(), 1f, 1f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        change = change.up(20L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+
+        assertThat(log.filter { it.methodName == "onStop" }).hasSize(0)
+    }
+
+    @Test
+    fun pointerInputHandler_unBlockedDownUp_onStopNotCalled() {
+        var change = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        dragStartBlocked = false
+        change = change.up(20L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+
+        assertThat(log.filter { it.methodName == "onStop" }).hasSize(0)
+    }
+
+    @Test
+    fun pointerInputHandler_unBlockedDownMoveAverage0Up_onStopNotCalled() {
+        var change1 = down(1)
+        var change2 = down(2)
+        recognizer.pointerInputHandler.invokeOverAllPasses(change1, change2)
+        dragStartBlocked = false
+        change1 = change1.moveBy(10.milliseconds, 1f, 1f)
+        change2 = change2.moveBy(10.milliseconds, -1f, -1f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(change1, change2)
+        change1 = change1.up(20L.millisecondsToTimestamp())
+        change2 = change2.up(20L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(change1, change2)
+        assertThat(log.filter { it.methodName == "onStop" }).isEmpty()
+    }
+
+    // onStop called verification
+
+    @Test
+    fun pointerInputHandler_unblockedDownMoveUp_onStopCalledOnce() {
+        var change = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        dragStartBlocked = false
+        change = change.moveTo(10L.millisecondsToTimestamp(), 1f, 1f)
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        change = change.up(20L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+
+        assertThat(log.filter { it.methodName == "onStop" }).hasSize(1)
+    }
+
+    // onStop called with correct values verification
+
+    @Test
+    fun pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity() {
+        pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(0f, 1f, 0f, 100f)
+        pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(0f, -1f, 0f, -100f)
+        pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(1f, 0f, 100f, 0f)
+        pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(-1f, 0f, -100f, 0f)
+
+        pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(1f, 1f, 100f, 100f)
+        pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(-1f, 1f, -100f, 100f)
+        pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(1f, -1f, 100f, -100f)
+        pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(-1f, -1f, -100f, -100f)
+    }
+
+    private fun pointerInputHandler_flingBeyondSlop_onStopCalledWithCorrectVelocity(
+        incrementPerMilliX: Float,
+        incrementPerMilliY: Float,
+        expectedPxPerSecondDx: Float,
+        expectedPxPerSecondDy: Float
+    ) {
+        log.clear()
+
+        var change = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        dragStartBlocked = false
+
+        repeat(11) {
+            change = change.moveBy(
+                Duration(milliseconds = 10),
+                incrementPerMilliX,
+                incrementPerMilliY
+            )
+            recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        }
+
+        change = change.up(20L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+
+        val loggedStops = log.filter { it.methodName == "onStop" }
+        assertThat(loggedStops).hasSize(1)
+        val velocity = loggedStops[0].pxPosition!!
+        assertThat(velocity.x.value).isWithin(.01f).of(expectedPxPerSecondDx)
+        assertThat(velocity.y.value).isWithin(.01f).of(expectedPxPerSecondDy)
+    }
+
+    // Verification that callbacks occur in the correct order
+
+    @Test
+    fun pointerInputHandler_unblockDownMoveUp_callBacksOccurInCorrectOrder() {
+        var change = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        dragStartBlocked = false
+
+        change = change.moveTo(
+            10L.millisecondsToTimestamp(),
+            0f,
+            1f
+        )
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        change = change.up(20L.millisecondsToTimestamp())
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+
+        assertThat(log).hasSize(4)
+        assertThat(log[0].methodName).isEqualTo("onStart")
+        // 2 onDrags because DragGestureDetector calls onDrag on both PostUp and PostDown and the
+        // distance is never consumed.
+        assertThat(log[1].methodName).isEqualTo("onDrag")
+        assertThat(log[2].methodName).isEqualTo("onDrag")
+        assertThat(log[3].methodName).isEqualTo("onStop")
+    }
+
+    // Verification about what events are, or aren't consumed.
+
+    @Test
+    fun pointerInputHandler_down_downNotConsumed() {
+        val result = recognizer.pointerInputHandler.invokeOverAllPasses(down())
+        assertThat(result.first().consumed.downChange).isFalse()
+    }
+
+    @Test
+    fun pointerInputHandler_blockedDownMove_distanceChangeNotConsumed() {
+
+        var change = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        change = change.moveTo(
+            10L.millisecondsToTimestamp(),
+            1f,
+            0f
+        )
+        val result = recognizer.pointerInputHandler.invokeOverAllPasses(change)
+
+        assertThat(result.first().anyPositionChangeConsumed()).isFalse()
+    }
+
+    @Test
+    fun pointerInputHandler_unblockedDownMoveCallBackDoesNotConsume_distanceChangeNotConsumed() {
+        dragObserver.dragConsume = PxPosition.Origin
+
+        var change = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        dragStartBlocked = false
+
+        change = change.moveTo(
+            10L.millisecondsToTimestamp(),
+            1f,
+            1f
+        )
+        val result = recognizer.pointerInputHandler.invokeOverAllPasses(change)
+
+        assertThat(result.first().anyPositionChangeConsumed()).isFalse()
+    }
+
+    @Test
+    fun pointerInputHandler_unblockedMoveOccursDefaultOnDrag_distanceChangeNotConsumed() {
+        dragObserver.dragConsume = null
+
+        var change = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        dragStartBlocked = false
+
+        change = change.moveTo(
+            10L.millisecondsToTimestamp(),
+            1f,
+            1f
+        )
+        val result = recognizer.pointerInputHandler.invokeOverAllPasses(change)
+
+        assertThat(result.first().anyPositionChangeConsumed()).isFalse()
+    }
+
+    @Test
+    fun pointerInputHandler_moveCallBackConsumes_changeDistanceConsumedByCorrectAmount() {
+        dragObserver.dragConsume = PxPosition(7.ipx, (-11).ipx)
+
+        var change = down()
+        recognizer.pointerInputHandler.invoke(listOf(change), PointerEventPass.PostUp)
+        dragStartBlocked = false
+
+        change = change.moveTo(
+            10L.millisecondsToTimestamp(),
+            3f,
+            -5f
+        )
+        val result = recognizer.pointerInputHandler.invoke(listOf(change), PointerEventPass.PostUp)
+
+        assertThat(result.first().consumed.positionChange.x.value).isEqualTo(7f)
+        assertThat(result.first().consumed.positionChange.y.value).isEqualTo(-11f)
+    }
+
+    @Test
+    fun pointerInputHandler_onStopConsumesUp() {
+        var change = down()
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        dragStartBlocked = false
+
+        change = change.moveTo(
+            10L.millisecondsToTimestamp(),
+            1f,
+            0f
+        )
+        recognizer.pointerInputHandler.invokeOverAllPasses(change)
+        change = change.up(20L.millisecondsToTimestamp())
+        val result = recognizer.pointerInputHandler.invokeOverAllPasses(change)
+
+        assertThat(result.first().consumed.downChange).isTrue()
+    }
+
+    data class LogItem(
+        val methodName: String,
+        val direction: Direction? = null,
+        val pxPosition: PxPosition? = null
+    )
+
+    class MockDragObserver(
+        private val log: MutableList<LogItem>,
+        var dragConsume: PxPosition? = null
+    ) : DragObserver {
+
+        override fun onStart() {
+            log.add(LogItem("onStart"))
+            super.onStart()
+        }
+
+        override fun onDrag(dragDistance: PxPosition): PxPosition {
+            log.add(LogItem("onDrag", pxPosition = dragDistance))
+            val internalDragConsume = dragConsume
+            if (internalDragConsume == null) {
+                return super.onDrag(dragDistance)
+            } else {
+                return internalDragConsume
+            }
+        }
+
+        override fun onStop(velocity: PxPosition) {
+            log.add(LogItem("onStop", pxPosition = velocity))
+            super.onStop(velocity)
+        }
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-framework/src/test/java/androidx/ui/core/gesture/TouchSlopExceededGestureDetectorTest.kt b/ui/ui-framework/src/test/java/androidx/ui/core/gesture/TouchSlopExceededGestureDetectorTest.kt
new file mode 100644
index 0000000..63704ff
--- /dev/null
+++ b/ui/ui-framework/src/test/java/androidx/ui/core/gesture/TouchSlopExceededGestureDetectorTest.kt
@@ -0,0 +1,801 @@
+/*
+ * Copyright 2019 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.ui.core.gesture
+
+import androidx.ui.core.Direction
+import androidx.ui.core.Duration
+import androidx.ui.core.PointerEventPass
+import androidx.ui.core.consumeDownChange
+import androidx.ui.core.ipx
+import androidx.ui.core.milliseconds
+import androidx.ui.core.millisecondsToTimestamp
+import androidx.ui.core.px
+import androidx.ui.testutils.consume
+import androidx.ui.testutils.down
+import androidx.ui.testutils.invokeOverAllPasses
+import androidx.ui.testutils.invokeOverPasses
+import androidx.ui.testutils.moveBy
+import androidx.ui.testutils.moveTo
+import androidx.ui.testutils.up
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+// TODO(shepshapard): Write the following tests.
+// Verify correct shape of slop area (should it be a square or circle)?
+// Test for cases with more than one pointer
+// Test for cases where things are reset when last pointer goes up
+// Verify all methods called during onPostUp
+// Verify default behavior when no callback provided for recognizer or canDrag
+
+// Changing this value will break tests that expect the value to be 10.
+private const val TestTouchSlop = 10
+
+@RunWith(JUnit4::class)
+class TouchSlopExceededGestureDetectorTest {
+
+    private val onTouchSlopExceeded: () -> Unit = { onTouchSlopExceededCallCount++ }
+    private val canDrag: (Direction) -> Boolean = { direction ->
+        canDragDirections.add(direction)
+        canDragReturn
+    }
+    private var onTouchSlopExceededCallCount: Int = 0
+    private var canDragReturn = false
+    private var canDragDirections: MutableList<Direction> = mutableListOf()
+    private lateinit var mRecognizer: TouchSlopExceededGestureRecognizer
+
+    @Before
+    fun setup() {
+        onTouchSlopExceededCallCount = 0
+        canDragReturn = true
+        canDragDirections.clear()
+        mRecognizer =
+            TouchSlopExceededGestureRecognizer(TestTouchSlop.ipx)
+        mRecognizer.canDrag = canDrag
+        mRecognizer.onTouchSlopExceeded = onTouchSlopExceeded
+    }
+
+    // Verify the circumstances under which canDrag should not be called.
+
+    @Test
+    fun onPointerInputChanges_down_canDragNotCalled() {
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down())
+        assertThat(canDragDirections).isEmpty()
+    }
+
+    @Test
+    fun onPointerInputChanges_downUp_canDragNotCalled() {
+        val down = down(timestamp = 0L.millisecondsToTimestamp())
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down())
+        val up = down.up(10L.millisecondsToTimestamp())
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(up)
+
+        assertThat(canDragDirections).isEmpty()
+    }
+
+    @Test
+    fun onPointerInputChanges_downMoveFullyConsumed_canDragNotCalled() {
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+        val move = down.moveBy(Duration(milliseconds = 10), 3f, 5f).consume(3f, 5f)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+
+        assertThat(canDragDirections).isEmpty()
+    }
+
+    // Verify the circumstances under which canDrag should be called.
+
+    @Test
+    fun onPointerInputChanges_downMove1Dimension_canDragCalledOnce() {
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+        val move = down.moveBy(Duration(milliseconds = 10), 3f, 0f)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+
+        // Twice because while under touch slop, TouchSlopExceededGestureDetector checks during PostUp and PostDown
+        assertThat(canDragDirections).hasSize(2)
+    }
+
+    @Test
+    fun onPointerInputChanges_downMove2Dimensions_canDragCalledTwice() {
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+        val move = down.moveBy(Duration(milliseconds = 10), 3f, 5f)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+
+        // 4 times because while under touch slop, TouchSlopExceededGestureDetector checks during PostUp and
+        // PostDown
+        assertThat(canDragDirections).hasSize(4)
+    }
+
+    @Test
+    fun onPointerInputChanges_downMoveOneDimensionPartiallyConsumed_canDragCalledOnce() {
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+        val move = down.moveBy(Duration(milliseconds = 10), 0f, 5f).consume(0f, 4f)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+
+        // Twice because while under touch slop, DragGestureDetector checks during PostUp and
+        // PostDown
+        assertThat(canDragDirections).hasSize(2)
+    }
+
+    @Test
+    fun onPointerInputChanges_downMoveTwoDimensionPartiallyConsumed_canDragCalledTwice() {
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+        val move = down.moveBy(Duration(milliseconds = 10), 3f, 5f).consume(2f, 4f)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+
+        // 4 times because while under touch slop, DragGestureDetector checks during PostUp and
+        // PostDown
+        assertThat(canDragDirections).hasSize(4)
+    }
+
+    @Test
+    fun onPointerInputChanges_dragPastTouchSlopOneDimensionAndDrag3MoreTimes_canDragCalledOnce() {
+        val justBeyondSlop = (TestTouchSlop + 1).toFloat()
+
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+        var move = down.moveTo(10L.millisecondsToTimestamp(), 0f, justBeyondSlop)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+        repeat(3) {
+            move = move.moveBy(Duration(milliseconds = 10), 0f, 1f)
+            mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+        }
+
+        // Once because although DragGestureDetector checks during PostUp and PostDown, slop is
+        // surpassed during PostUp, and thus isn't checked again.
+        assertThat(canDragDirections).hasSize(1)
+    }
+
+    @Test
+    fun onPointerInputChanges_downMoveUnderSlop3Times_canDragCalled3Times() {
+        val thirdSlop = TestTouchSlop.toFloat() / 3
+
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+        var move = down
+        repeat(3) {
+            move = move.moveBy(Duration(milliseconds = 10), 0f, thirdSlop)
+            mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+        }
+
+        // 6 times because while under touch slop, DragGestureDetector checks during PostUp and
+        // PostDown
+        assertThat(canDragDirections).hasSize(6)
+    }
+
+    @Test
+    fun onPointerInputChanges_moveBeyondSlopThenIntoTouchSlopAreaAndOutAgain_canDragCalledOnce() {
+        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
+
+        var event = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(event)
+        // Out of touch slop region
+        event = event.moveBy(Duration(milliseconds = 10), 0f, beyondTouchSlop)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(event)
+        // Back into touch slop region
+        event = event.moveBy(Duration(milliseconds = 10), 0f, -beyondTouchSlop)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(event)
+        // Out of touch slop region again
+        event = event.moveBy(Duration(milliseconds = 10), 0f, beyondTouchSlop)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(event)
+
+        // Once because although DragGestureDetector checks during PostUp and PostDown, slop is
+        // surpassed during PostUp, and thus isn't checked again.
+        assertThat(canDragDirections).hasSize(1)
+    }
+
+    // Verification of correctness of values passed to canDrag.
+
+    @Test
+    fun onPointerInputChanges_canDragCalledWithCorrectDirection() {
+        onPointerInputChanges_canDragCalledWithCorrectDirection(
+            -1f, 0f, arrayOf(Direction.LEFT)
+        )
+        onPointerInputChanges_canDragCalledWithCorrectDirection(
+            0f, -1f, arrayOf(Direction.UP)
+        )
+        onPointerInputChanges_canDragCalledWithCorrectDirection(
+            1f, 0f, arrayOf(Direction.RIGHT)
+        )
+        onPointerInputChanges_canDragCalledWithCorrectDirection(
+            0f, 1f, arrayOf(Direction.DOWN)
+        )
+        onPointerInputChanges_canDragCalledWithCorrectDirection(
+            -1f, -1f, arrayOf(Direction.LEFT, Direction.UP)
+        )
+        onPointerInputChanges_canDragCalledWithCorrectDirection(
+            -1f, 1f, arrayOf(Direction.LEFT, Direction.DOWN)
+        )
+        onPointerInputChanges_canDragCalledWithCorrectDirection(
+            1f, -1f, arrayOf(Direction.RIGHT, Direction.UP)
+        )
+        onPointerInputChanges_canDragCalledWithCorrectDirection(
+            1f, 1f, arrayOf(Direction.RIGHT, Direction.DOWN)
+        )
+    }
+
+    private fun onPointerInputChanges_canDragCalledWithCorrectDirection(
+        dx: Float,
+        dy: Float,
+        expectedDirections: Array<Direction>
+    ) {
+        canDragDirections.clear()
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+        val move = down.moveBy(Duration(milliseconds = 10), dx, dy)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+
+        // Everything here is twice because DragGestureDetector checks during PostUp and PostDown.
+        assertThat(canDragDirections).hasSize(expectedDirections.size * 2)
+        expectedDirections.forEach { direction ->
+            assertThat(canDragDirections.count { it == direction })
+                .isEqualTo(2)
+        }
+    }
+
+    // Verify the circumstances under which onTouchSlopExceeded should not be called.
+
+    // TODO(b/129701831): This test assumes that if a pointer moves by slop in both x and y, we are
+    // still under slop even though sqrt(slop^2 + slop^2) > slop.  This may be inaccurate and this
+    // test may therefore need to be updated.
+    @Test
+    fun onPointerInputChanges_downMoveWithinSlop_onTouchSlopExceededNotCalled() {
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+        val move = down.moveBy(
+            Duration(milliseconds = 10),
+            TestTouchSlop.toFloat(),
+            TestTouchSlop.toFloat()
+        )
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(0)
+    }
+
+    @Test
+    fun onPointerInputChanges_moveBeyondSlopInUnsupportedDirection_onTouchSlopExceededNotCalled() {
+        val beyondSlop = (TestTouchSlop + 1).toFloat()
+        canDragReturn = false
+
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+        val move = down.moveBy(
+            Duration(milliseconds = 10),
+            beyondSlop,
+            beyondSlop
+        )
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(0)
+    }
+
+    @Test
+    fun onPointerInputChanges_moveBeyondSlopButConsumeUnder_onTouchSlopExceededNotCalled() {
+
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+
+        val move = down().moveBy(10.milliseconds, TestTouchSlop + 1f, 0f).consume(dx = 1f)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+
+        // Assert
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(0)
+    }
+
+    @Test
+    fun onPointerInputChanges_moveUnderToPostUpThenModOverInOppDir_onTouchSlopExceededNotCalled() {
+
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+
+        val move = down().moveBy(10.milliseconds, TestTouchSlop.toFloat(), 0f)
+        mRecognizer::onPointerInputChanges.invokeOverPasses(
+            listOf(move),
+            PointerEventPass.InitialDown,
+            PointerEventPass.PreUp,
+            PointerEventPass.PreDown,
+            PointerEventPass.PostUp
+        )
+        val move2 = move.consume(dx = (TestTouchSlop * 2f + 1))
+        mRecognizer::onPointerInputChanges.invokeOverPasses(
+            listOf(move2),
+            PointerEventPass.PostDown
+        )
+
+        // Assert
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(1)
+    }
+
+    // TODO(b/129701831): This test assumes that if a pointer moves by slop in both x and y, we are
+    // still under slop even though sqrt(slop^2 + slop^2) > slop.  This may be inaccurate and this
+    // test may therefore need to be updated.
+    @Test
+    fun onPointerInputChanges_moveAroundWithinSlop_onTouchSlopExceededNotCalled() {
+        val slop = TestTouchSlop.toFloat()
+
+        var change = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(change)
+
+        // Go around the border of the touch slop area
+
+        // To top left
+        change = change.moveTo(10L.millisecondsToTimestamp(), -slop, -slop)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(change)
+        // To bottom left
+        change = change.moveTo(20L.millisecondsToTimestamp(), -slop, slop)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(change)
+        // To bottom right
+        change = change.moveTo(30L.millisecondsToTimestamp(), slop, slop)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(change)
+        // To top right
+        change = change.moveTo(40L.millisecondsToTimestamp(), slop, -slop)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(change)
+
+        // Jump from corner to opposite corner and back
+
+        // To bottom left
+        change = change.moveTo(50L.millisecondsToTimestamp(), -slop, slop)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(change)
+        // To top right
+        change = change.moveTo(60L.millisecondsToTimestamp(), slop, -slop)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(change)
+
+        // Move the other diagonal
+
+        // To top left
+        change = change.moveTo(70L.millisecondsToTimestamp(), -slop, -slop)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(change)
+
+        // Jump from corner to opposite corner and back
+
+        // To bottom right
+        change = change.moveTo(80L.millisecondsToTimestamp(), slop, slop)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(change)
+        // To top left
+        change = change.moveTo(90L.millisecondsToTimestamp(), -slop, -slop)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(change)
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(0)
+    }
+
+    // Verify the circumstances under which onTouchSlopExceeded should be called.
+
+    @Test
+    fun onPointerInputChanges_movePassedSlop_onTouchSlopExceededCallOnce() {
+        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
+
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+        val move = down.moveBy(
+            Duration(milliseconds = 100),
+            beyondTouchSlop,
+            0f
+        )
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(1)
+    }
+
+    @Test
+    fun onPointerInputChanges_movePassedSlopIn2Events_onTouchSlopExceededCallOnce() {
+
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+        val move = down.moveBy(
+            Duration(milliseconds = 100),
+            TestTouchSlop.toFloat(),
+            0f
+        )
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+        val move2 = down.moveBy(
+            Duration(milliseconds = 100),
+            1f,
+            0f
+        )
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(move2)
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(1)
+    }
+
+    @Test
+    fun onPointerInputChanges_passSlopThenInSlopAreaThenOut_onTouchSlopExceededCallOnce() {
+        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
+
+        var event = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(event)
+        // Out of touch slop region
+        event = event.moveBy(Duration(milliseconds = 10), 0f, beyondTouchSlop)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(event)
+        // Back into touch slop region
+        event = event.moveBy(Duration(milliseconds = 10), 0f, -beyondTouchSlop)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(event)
+        // Out of touch slop region again
+        event = event.moveBy(Duration(milliseconds = 10), 0f, beyondTouchSlop)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(event)
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(1)
+    }
+
+    @Test
+    fun onPointerInputChanges_downConsumedMovePassedSlop_onTouchSlopExceededCallOnce() {
+        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
+
+        val down = down().consumeDownChange()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+        val move = down.moveBy(Duration(milliseconds = 100), beyondTouchSlop, 0f)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(1)
+    }
+
+    @Test
+    fun onPointerInputChanges_beyondInUnsupportThenBeyondInSupport_onTouchSlopExceededCallOnce() {
+        val doubleTouchSlop = (TestTouchSlop * 2).toFloat()
+        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
+
+        var change = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(change)
+        canDragReturn = false
+        change = change.moveBy(
+            Duration(milliseconds = 10),
+            0f,
+            doubleTouchSlop
+        )
+        // Sanity check that onTouchSlopExceeded has not been called.
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(0)
+
+        canDragReturn = true
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(change)
+        change = change.moveBy(
+            Duration(milliseconds = 10),
+            0f,
+            -beyondTouchSlop
+        )
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(change)
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(1)
+    }
+
+    @Test
+    fun onPointerInputChanges_2PointsMoveInOpposite_onTouchSlopExceededCallOnce() {
+
+        // Arrange
+
+        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
+
+        var pointer1 = down(1)
+        var pointer2 = down(2)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(pointer1, pointer2)
+
+        // Act
+
+        pointer1 = pointer1.moveBy(
+            Duration(milliseconds = 100),
+            beyondTouchSlop,
+            0f
+        )
+        pointer2 = pointer2.moveBy(
+            Duration(milliseconds = 100),
+            -beyondTouchSlop,
+            0f
+        )
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(pointer1, pointer2)
+
+        // Assert
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(1)
+    }
+
+    @Test
+    fun onPointerInputChanges_3PointsMoveAverage0_onTouchSlopExceededCallOnce() {
+
+        // Arrange
+
+        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
+
+        val pointers = arrayListOf(down(0), down(1), down(2))
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(pointers)
+
+        // Act
+
+        // These movements average to no movement.
+        pointers[0] =
+            pointers[0].moveBy(
+                Duration(milliseconds = 100),
+                beyondTouchSlop * -1,
+                beyondTouchSlop * -1
+            )
+        pointers[1] =
+            pointers[1].moveBy(
+                Duration(milliseconds = 100),
+                beyondTouchSlop * 1,
+                beyondTouchSlop * -1
+            )
+        pointers[2] =
+            pointers[2].moveBy(
+                Duration(milliseconds = 100),
+                0f,
+                beyondTouchSlop * 2
+            )
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(pointers)
+
+        // Assert
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(1)
+    }
+
+    @Test
+    fun onPointerInputChanges_5Points1MoveBeyondSlop_onTouchSlopExceededCallOnce() {
+
+        // Arrange
+
+        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
+
+        val pointers = arrayListOf(down(0), down(1), down(2), down(3), down(4))
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(pointers)
+
+        // Act
+
+        // These movements average to no movement.
+        for (i in 0..3) {
+            pointers[i] = pointers[i].moveBy(
+                Duration(milliseconds = 100),
+                0f,
+                0f
+            )
+        }
+        pointers[4] =
+            pointers[4].moveBy(
+                Duration(milliseconds = 100),
+                beyondTouchSlop * -1,
+                0f
+            )
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(pointers)
+
+        // Assert
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(1)
+    }
+
+    @Test
+    fun onPointerInputChanges_1PointMovesBeyondSlopAndThenManyTimes_onTouchSlopExceededCallOnce() {
+
+        // Arrange
+
+        val beyondTouchSlop = (TestTouchSlop + 1).toFloat()
+
+        var pointer = down(0)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(pointer)
+
+        // Act
+
+        repeat(5) {
+            pointer = pointer.moveBy(100.milliseconds, beyondTouchSlop, beyondTouchSlop)
+            mRecognizer::onPointerInputChanges.invokeOverAllPasses(pointer)
+        }
+
+        // Assert
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(1)
+    }
+
+    @Test
+    fun onPointerInputChanges_1ModifiedToMoveBeyondSlopBeforePostUp_onTouchSlopExceededCallOnce() {
+
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+
+        val move = down().moveBy(10.milliseconds, 0f, 0f).consume(dx = TestTouchSlop + 1f)
+        mRecognizer::onPointerInputChanges.invokeOverPasses(
+            listOf(move),
+            PointerEventPass.InitialDown,
+            PointerEventPass.PreUp,
+            PointerEventPass.PreDown,
+            PointerEventPass.PostUp
+        )
+
+        // Assert
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(1)
+    }
+
+    @Test
+    fun onPointerInputChanges_1ModedToMoveBeyondSlopBeforePostDown_onTouchSlopExceededCallOnce() {
+
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+
+        val move = down().moveBy(10.milliseconds, 0f, 0f)
+        mRecognizer::onPointerInputChanges.invokeOverPasses(
+            listOf(move),
+            PointerEventPass.InitialDown,
+            PointerEventPass.PreUp,
+            PointerEventPass.PreDown,
+            PointerEventPass.PostUp
+        )
+
+        val moveConsumed = move.consume(dx = TestTouchSlop + 1f)
+        mRecognizer::onPointerInputChanges.invokeOverPasses(
+            listOf(moveConsumed),
+            PointerEventPass.PostDown
+        )
+
+        // Assert
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(1)
+    }
+
+    @Test
+    fun onPointerInputChanges_moveUnderToPostUpThenModOverToPostDown_onTouchSlopExceededCallOnce() {
+
+        val halfSlop = TestTouchSlop / 2
+        val restOfSlopAndBeyond = TestTouchSlop - halfSlop + 1
+
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+
+        val move = down().moveBy(10.milliseconds, halfSlop.toFloat(), 0f)
+        mRecognizer::onPointerInputChanges.invokeOverPasses(
+            listOf(move),
+            PointerEventPass.InitialDown,
+            PointerEventPass.PreUp,
+            PointerEventPass.PreDown,
+            PointerEventPass.PostUp
+        )
+
+        val moveConsumed = move.consume(dx = -restOfSlopAndBeyond.toFloat())
+        mRecognizer::onPointerInputChanges.invokeOverPasses(
+            listOf(moveConsumed),
+            PointerEventPass.PostDown
+        )
+
+        // Assert
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(1)
+    }
+
+    @Test
+    fun onPointerInputChanges_moveBeyondSlopAllPassesUpToPostUp_onTouchSlopExceededCallOnce() {
+
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+
+        val move = down().moveBy(10.milliseconds, TestTouchSlop + 1f, 0f)
+        mRecognizer::onPointerInputChanges.invokeOverPasses(
+            listOf(move),
+            PointerEventPass.InitialDown,
+            PointerEventPass.PreUp,
+            PointerEventPass.PreDown,
+            PointerEventPass.PostUp
+        )
+
+        // Assert
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(1)
+    }
+
+    // Verification that TouchSlopExceededGestureDetector does not consume any changes.
+
+    @Test
+    fun onPointerInputChanges_1Down_nothingConsumed() {
+
+        val result = mRecognizer::onPointerInputChanges.invokeOverAllPasses(down())
+
+        // Assert
+
+        assertThat(result[0].consumed.downChange).isFalse()
+        assertThat(result[0].consumed.positionChange.x).isEqualTo(0.px)
+        assertThat(result[0].consumed.positionChange.y).isEqualTo(0.px)
+    }
+
+    @Test
+    fun onPointerInputChanges_1MoveUnderSlop_nothingConsumed() {
+
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+
+        val move = down().moveBy(10.milliseconds, TestTouchSlop.toFloat(), TestTouchSlop.toFloat())
+        val result = mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+
+        // Assert
+
+        assertThat(result[0].consumed.downChange).isFalse()
+        assertThat(result[0].consumed.positionChange.x).isEqualTo(0.px)
+        assertThat(result[0].consumed.positionChange.y).isEqualTo(0.px)
+    }
+
+    @Test
+    fun onPointerInputChanges_1MoveUnderSlopThenUp_nothingConsumed() {
+
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+
+        val move = down().moveBy(10.milliseconds, TestTouchSlop.toFloat(), TestTouchSlop.toFloat())
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+
+        val up = move.up(20L.millisecondsToTimestamp())
+        val result = mRecognizer::onPointerInputChanges.invokeOverAllPasses(up)
+
+        // Assert
+
+        assertThat(result[0].consumed.downChange).isFalse()
+        assertThat(result[0].consumed.positionChange.x).isEqualTo(0.px)
+        assertThat(result[0].consumed.positionChange.y).isEqualTo(0.px)
+    }
+
+    @Test
+    fun onPointerInputChanges_1MoveOverSlop_nothingConsumed() {
+
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+
+        val move = down().moveBy(10.milliseconds, TestTouchSlop + 1f, TestTouchSlop + 1f)
+        val result = mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+
+        // Assert
+
+        assertThat(result[0].consumed.downChange).isFalse()
+        assertThat(result[0].consumed.positionChange.x).isEqualTo(0.px)
+        assertThat(result[0].consumed.positionChange.y).isEqualTo(0.px)
+    }
+
+    @Test
+    fun onPointerInputChanges_1MoveOverSlopThenUp_nothingConsumed() {
+
+        val down = down()
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+
+        val move = down().moveBy(10.milliseconds, TestTouchSlop + 1f, TestTouchSlop + 1f)
+        mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+
+        val up = move.up(20L.millisecondsToTimestamp())
+        val result = mRecognizer::onPointerInputChanges.invokeOverAllPasses(up)
+
+        // Assert
+
+        assertThat(result[0].consumed.downChange).isFalse()
+        assertThat(result[0].consumed.positionChange.x).isEqualTo(0.px)
+        assertThat(result[0].consumed.positionChange.y).isEqualTo(0.px)
+    }
+
+    // Verification that TouchSlopExceededGestureDetector resets after up correctly.
+
+    @Test
+    fun onPointerInputChanges_MoveBeyondUpDownMoveBeyond_onTouchSlopExceededCalledTwice() {
+
+        repeat(2) {
+            val down = down()
+            mRecognizer::onPointerInputChanges.invokeOverAllPasses(down)
+
+            val move = down().moveBy(10.milliseconds, TestTouchSlop + 1f, 0f)
+            mRecognizer::onPointerInputChanges.invokeOverAllPasses(move)
+
+            val up = move.up(20L.millisecondsToTimestamp())
+            mRecognizer::onPointerInputChanges.invokeOverAllPasses(up)
+        }
+
+        assertThat(onTouchSlopExceededCallCount).isEqualTo(2)
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-layout/api/1.0.0-alpha01.txt b/ui/ui-layout/api/1.0.0-alpha01.txt
index fe4723d..76dd60f 100644
--- a/ui/ui-layout/api/1.0.0-alpha01.txt
+++ b/ui/ui-layout/api/1.0.0-alpha01.txt
@@ -144,6 +144,9 @@
 
   public final class ScrollerKt {
     ctor public ScrollerKt();
+    method public static void HorizontalScroller(androidx.ui.layout.ScrollerPosition scrollerPosition = +memo({ 
+    <init>()
+}), kotlin.jvm.functions.Function2<? super androidx.ui.core.Px,? super androidx.ui.core.Px,kotlin.Unit> onScrollChanged = { position, _ -> scrollerPosition.position = position }, kotlin.jvm.functions.Function0<kotlin.Unit> child);
     method public static void VerticalScroller(androidx.ui.layout.ScrollerPosition scrollerPosition = +memo({ 
     <init>()
 }), kotlin.jvm.functions.Function2<? super androidx.ui.core.Px,? super androidx.ui.core.Px,kotlin.Unit> onScrollChanged = { position, _ -> scrollerPosition.position = position }, kotlin.jvm.functions.Function0<kotlin.Unit> child);
@@ -176,7 +179,8 @@
   }
 
   public final class TableChildren {
-    method public void tableRow(kotlin.jvm.functions.Function0<kotlin.Unit> children);
+    method public void addDecoration(kotlin.jvm.functions.Function2<? super androidx.ui.core.IntPx[],? super androidx.ui.core.IntPx[],kotlin.Unit> decoration);
+    method public void tableRow(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> children);
   }
 
   public abstract sealed class TableColumnWidth {
@@ -216,7 +220,7 @@
 
   public final class TableKt {
     ctor public TableKt();
-    method public static void Table(androidx.ui.layout.Alignment childAlignment = Alignment.TopLeft, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends androidx.ui.layout.TableColumnWidth> columnWidth = { TableColumnWidth.<init>(1.0) }, kotlin.jvm.functions.Function1<? super androidx.ui.layout.TableChildren,kotlin.Unit> block);
+    method public static void Table(int columnCount, androidx.ui.layout.Alignment childAlignment = Alignment.TopLeft, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends androidx.ui.layout.TableColumnWidth> columnWidth = { TableColumnWidth.<init>(1.0) }, kotlin.jvm.functions.Function1<? super androidx.ui.layout.TableChildren,kotlin.Unit> block);
   }
 
   public final class WrapKt {
diff --git a/ui/ui-layout/api/api_lint.ignore b/ui/ui-layout/api/api_lint.ignore
index e1bb2f7..058fd5d 100644
--- a/ui/ui-layout/api/api_lint.ignore
+++ b/ui/ui-layout/api/api_lint.ignore
@@ -3,5 +3,9 @@
     Method FlexChildren.expanded appears to be throwing java.lang.IllegalArgumentException; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
 DocumentExceptions: androidx.ui.layout.FlexChildren#flexible(float, kotlin.jvm.functions.Function0<kotlin.Unit>):
     Method FlexChildren.flexible appears to be throwing java.lang.IllegalArgumentException; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
-DocumentExceptions: androidx.ui.layout.ScrollerKt#VerticalScroller(androidx.ui.layout.ScrollerPosition, kotlin.jvm.functions.Function2<? super androidx.ui.core.Px,? super androidx.ui.core.Px,kotlin.Unit>, kotlin.jvm.functions.Function0<kotlin.Unit>):
-    Method ScrollerKt.VerticalScroller appears to be throwing java.lang.IllegalStateException; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
+
+
+MissingNullability: androidx.ui.layout.DpConstraints#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.layout.DpConstraints`
+MissingNullability: androidx.ui.layout.TableColumnWidth.Inflexible.Wrap#INSTANCE:
+    Missing nullability on field `INSTANCE` in class `class androidx.ui.layout.TableColumnWidth.Inflexible.Wrap`
diff --git a/ui/ui-layout/api/current.txt b/ui/ui-layout/api/current.txt
index fe4723d..76dd60f 100644
--- a/ui/ui-layout/api/current.txt
+++ b/ui/ui-layout/api/current.txt
@@ -144,6 +144,9 @@
 
   public final class ScrollerKt {
     ctor public ScrollerKt();
+    method public static void HorizontalScroller(androidx.ui.layout.ScrollerPosition scrollerPosition = +memo({ 
+    <init>()
+}), kotlin.jvm.functions.Function2<? super androidx.ui.core.Px,? super androidx.ui.core.Px,kotlin.Unit> onScrollChanged = { position, _ -> scrollerPosition.position = position }, kotlin.jvm.functions.Function0<kotlin.Unit> child);
     method public static void VerticalScroller(androidx.ui.layout.ScrollerPosition scrollerPosition = +memo({ 
     <init>()
 }), kotlin.jvm.functions.Function2<? super androidx.ui.core.Px,? super androidx.ui.core.Px,kotlin.Unit> onScrollChanged = { position, _ -> scrollerPosition.position = position }, kotlin.jvm.functions.Function0<kotlin.Unit> child);
@@ -176,7 +179,8 @@
   }
 
   public final class TableChildren {
-    method public void tableRow(kotlin.jvm.functions.Function0<kotlin.Unit> children);
+    method public void addDecoration(kotlin.jvm.functions.Function2<? super androidx.ui.core.IntPx[],? super androidx.ui.core.IntPx[],kotlin.Unit> decoration);
+    method public void tableRow(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> children);
   }
 
   public abstract sealed class TableColumnWidth {
@@ -216,7 +220,7 @@
 
   public final class TableKt {
     ctor public TableKt();
-    method public static void Table(androidx.ui.layout.Alignment childAlignment = Alignment.TopLeft, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends androidx.ui.layout.TableColumnWidth> columnWidth = { TableColumnWidth.<init>(1.0) }, kotlin.jvm.functions.Function1<? super androidx.ui.layout.TableChildren,kotlin.Unit> block);
+    method public static void Table(int columnCount, androidx.ui.layout.Alignment childAlignment = Alignment.TopLeft, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends androidx.ui.layout.TableColumnWidth> columnWidth = { TableColumnWidth.<init>(1.0) }, kotlin.jvm.functions.Function1<? super androidx.ui.layout.TableChildren,kotlin.Unit> block);
   }
 
   public final class WrapKt {
diff --git a/ui/ui-layout/api/restricted_1.0.0-alpha01.txt b/ui/ui-layout/api/restricted_1.0.0-alpha01.txt
index fe4723d..76dd60f 100644
--- a/ui/ui-layout/api/restricted_1.0.0-alpha01.txt
+++ b/ui/ui-layout/api/restricted_1.0.0-alpha01.txt
@@ -144,6 +144,9 @@
 
   public final class ScrollerKt {
     ctor public ScrollerKt();
+    method public static void HorizontalScroller(androidx.ui.layout.ScrollerPosition scrollerPosition = +memo({ 
+    <init>()
+}), kotlin.jvm.functions.Function2<? super androidx.ui.core.Px,? super androidx.ui.core.Px,kotlin.Unit> onScrollChanged = { position, _ -> scrollerPosition.position = position }, kotlin.jvm.functions.Function0<kotlin.Unit> child);
     method public static void VerticalScroller(androidx.ui.layout.ScrollerPosition scrollerPosition = +memo({ 
     <init>()
 }), kotlin.jvm.functions.Function2<? super androidx.ui.core.Px,? super androidx.ui.core.Px,kotlin.Unit> onScrollChanged = { position, _ -> scrollerPosition.position = position }, kotlin.jvm.functions.Function0<kotlin.Unit> child);
@@ -176,7 +179,8 @@
   }
 
   public final class TableChildren {
-    method public void tableRow(kotlin.jvm.functions.Function0<kotlin.Unit> children);
+    method public void addDecoration(kotlin.jvm.functions.Function2<? super androidx.ui.core.IntPx[],? super androidx.ui.core.IntPx[],kotlin.Unit> decoration);
+    method public void tableRow(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> children);
   }
 
   public abstract sealed class TableColumnWidth {
@@ -216,7 +220,7 @@
 
   public final class TableKt {
     ctor public TableKt();
-    method public static void Table(androidx.ui.layout.Alignment childAlignment = Alignment.TopLeft, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends androidx.ui.layout.TableColumnWidth> columnWidth = { TableColumnWidth.<init>(1.0) }, kotlin.jvm.functions.Function1<? super androidx.ui.layout.TableChildren,kotlin.Unit> block);
+    method public static void Table(int columnCount, androidx.ui.layout.Alignment childAlignment = Alignment.TopLeft, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends androidx.ui.layout.TableColumnWidth> columnWidth = { TableColumnWidth.<init>(1.0) }, kotlin.jvm.functions.Function1<? super androidx.ui.layout.TableChildren,kotlin.Unit> block);
   }
 
   public final class WrapKt {
diff --git a/ui/ui-layout/api/restricted_current.txt b/ui/ui-layout/api/restricted_current.txt
index fe4723d..76dd60f 100644
--- a/ui/ui-layout/api/restricted_current.txt
+++ b/ui/ui-layout/api/restricted_current.txt
@@ -144,6 +144,9 @@
 
   public final class ScrollerKt {
     ctor public ScrollerKt();
+    method public static void HorizontalScroller(androidx.ui.layout.ScrollerPosition scrollerPosition = +memo({ 
+    <init>()
+}), kotlin.jvm.functions.Function2<? super androidx.ui.core.Px,? super androidx.ui.core.Px,kotlin.Unit> onScrollChanged = { position, _ -> scrollerPosition.position = position }, kotlin.jvm.functions.Function0<kotlin.Unit> child);
     method public static void VerticalScroller(androidx.ui.layout.ScrollerPosition scrollerPosition = +memo({ 
     <init>()
 }), kotlin.jvm.functions.Function2<? super androidx.ui.core.Px,? super androidx.ui.core.Px,kotlin.Unit> onScrollChanged = { position, _ -> scrollerPosition.position = position }, kotlin.jvm.functions.Function0<kotlin.Unit> child);
@@ -176,7 +179,8 @@
   }
 
   public final class TableChildren {
-    method public void tableRow(kotlin.jvm.functions.Function0<kotlin.Unit> children);
+    method public void addDecoration(kotlin.jvm.functions.Function2<? super androidx.ui.core.IntPx[],? super androidx.ui.core.IntPx[],kotlin.Unit> decoration);
+    method public void tableRow(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> children);
   }
 
   public abstract sealed class TableColumnWidth {
@@ -216,7 +220,7 @@
 
   public final class TableKt {
     ctor public TableKt();
-    method public static void Table(androidx.ui.layout.Alignment childAlignment = Alignment.TopLeft, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends androidx.ui.layout.TableColumnWidth> columnWidth = { TableColumnWidth.<init>(1.0) }, kotlin.jvm.functions.Function1<? super androidx.ui.layout.TableChildren,kotlin.Unit> block);
+    method public static void Table(int columnCount, androidx.ui.layout.Alignment childAlignment = Alignment.TopLeft, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends androidx.ui.layout.TableColumnWidth> columnWidth = { TableColumnWidth.<init>(1.0) }, kotlin.jvm.functions.Function1<? super androidx.ui.layout.TableChildren,kotlin.Unit> block);
   }
 
   public final class WrapKt {
diff --git a/ui/ui-layout/build.gradle b/ui/ui-layout/build.gradle
index 2af0b7e..3336d84 100644
--- a/ui/ui-layout/build.gradle
+++ b/ui/ui-layout/build.gradle
@@ -27,7 +27,6 @@
     id("com.android.library")
     id("AndroidXUiPlugin")
     id("org.jetbrains.kotlin.android")
-    id("androidx.benchmark")
 }
 
 dependencies {
@@ -45,7 +44,6 @@
     testImplementation(ANDROIDX_TEST_RUNNER)
     testImplementation(JUNIT)
 
-    androidTestImplementation project(":benchmark:benchmark-junit4")
     androidTestImplementation project(":ui:ui-platform")
 
     androidTestImplementation(ANDROIDX_TEST_RULES)
diff --git a/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/ComplexLayoutDemos.kt b/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/ComplexLayoutDemos.kt
index 568e0a2..3e957be 100644
--- a/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/ComplexLayoutDemos.kt
+++ b/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/ComplexLayoutDemos.kt
@@ -42,7 +42,6 @@
 import androidx.ui.layout.Stack
 import androidx.ui.graphics.Color
 import androidx.ui.painting.Paint
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.Model
 import androidx.compose.composer
@@ -59,9 +58,9 @@
  * A widget that forces its only child to be as wide as its min intrinsic width.
  */
 @Composable
-fun IntrinsicWidth(@Children() children: @Composable() () -> Unit) {
-    ComplexLayout(children = children, block = {
-        layout { measurables, constraints ->
+fun IntrinsicWidth(children: @Composable() () -> Unit) {
+    ComplexLayout(children) {
+        measure { measurables, constraints ->
             // Force child be as wide as its min intrinsic width.
             val width = measurables.first().minIntrinsicWidth(constraints.minHeight)
             val childConstraints = Constraints(
@@ -71,7 +70,7 @@
                 constraints.maxHeight
             )
             val childPlaceable = measurables.first().measure(childConstraints)
-            layoutResult(childPlaceable.width, childPlaceable.height) {
+            layout(childPlaceable.width, childPlaceable.height) {
                 childPlaceable.place(IntPx.Zero, IntPx.Zero)
             }
         }
@@ -87,7 +86,7 @@
         maxIntrinsicHeight { measurables, w ->
             measurables.first().maxIntrinsicHeight(w)
         }
-    })
+    }
 }
 
 /**
@@ -96,8 +95,8 @@
 @Composable
 fun RectangleWithIntrinsics(color: Color) {
     ComplexLayout(children = { DrawRectangle(color = color) }, block = {
-        layout { _, _ ->
-            layoutResult(80.ipx, 80.ipx) {}
+        measure { _, _ ->
+            layout(80.ipx, 80.ipx) {}
         }
         minIntrinsicWidth { _, _ -> 30.ipx }
         maxIntrinsicWidth { _, _ -> 150.ipx }
@@ -228,7 +227,7 @@
 
 @Composable
 fun SingleCompositionRow(children: @Composable() () -> Unit) {
-    Layout(layoutBlock = { measurables, constraints ->
+    Layout(children) { measurables, constraints ->
         val placeables = measurables.map {
             it.measure(constraints.copy(minWidth = 0.ipx, maxWidth = IntPx.Infinity))
         }
@@ -242,12 +241,12 @@
                 left += placeable.width
             }
         }
-    }, children = children)
+    }
 }
 
 @Composable
 fun SingleCompositionColumn(children: @Composable() () -> Unit) {
-    Layout(layoutBlock = { measurables, constraints ->
+    Layout(children) { measurables, constraints ->
         val placeables = measurables.map {
             it.measure(constraints.copy(minHeight = 0.ipx, maxHeight = IntPx.Infinity))
         }
@@ -261,7 +260,7 @@
                 top += placeable.height
             }
         }
-    }, children = children)
+    }
 }
 
 @Composable
@@ -272,13 +271,10 @@
             canvas.drawRect(parentSize.toRect(), paint)
         }
     }
-    Layout(
-        layoutBlock = { _, constraints ->
-            val size = constraints.constrain(IntPxSize(30.ipx, 30.ipx))
-            layout(size.width, size.height) { }
-        },
-        children = Rectangle
-    )
+    Layout(Rectangle) { _, constraints ->
+        val size = constraints.constrain(IntPxSize(30.ipx, 30.ipx))
+        layout(size.width, size.height) { }
+    }
 }
 
 @Model
@@ -295,8 +291,8 @@
         }
     }
     ComplexLayout(children = Rectangle, block = {
-        layout { _, _ ->
-            layoutResult(50.ipx, 50.ipx) {}
+        measure { _, _ ->
+            layout(50.ipx, 50.ipx) {}
         }
         minIntrinsicWidth { _, _ -> 50.ipx }
         maxIntrinsicWidth { _, _ -> 50.ipx }
@@ -308,7 +304,7 @@
 @Composable
 fun SingleCompositionRowWithIntrinsics(children: @Composable() () -> Unit) {
     ComplexLayout(children = children, block = {
-        layout { measurables, constraints ->
+        measure { measurables, constraints ->
             val placeables = measurables.map { measurable ->
                 val childWidth = measurable.maxIntrinsicWidth(constraints.maxHeight)
                 measurable.measure(
@@ -320,7 +316,7 @@
             val width = placeables.map { it.width }.sum()
             val height = placeables.map { it.height }.max()
 
-            layoutResult(width, height) {
+            layout(width, height) {
                 var left = 0.ipx
                 placeables.forEach { placeable ->
                     placeable.place(left, 0.ipx)
diff --git a/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/TableActivity.kt b/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/TableActivity.kt
index c40ff86..1c0f807 100644
--- a/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/TableActivity.kt
+++ b/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/TableActivity.kt
@@ -20,6 +20,7 @@
 import android.os.Bundle
 import androidx.compose.composer
 import androidx.ui.core.setContent
+import androidx.ui.layout.samples.SimpleTable
 import androidx.ui.layout.samples.TableWithDifferentColumnWidths
 
 class TableActivity : Activity() {
@@ -27,7 +28,7 @@
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContent {
-            TableWithDifferentColumnWidths()
+            SimpleTable()
         }
     }
 }
\ No newline at end of file
diff --git a/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/StackSamples.kt b/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/StackSamples.kt
index e816b27..23346d3 100644
--- a/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/StackSamples.kt
+++ b/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/StackSamples.kt
@@ -35,13 +35,11 @@
  */
 @Composable
 fun SizedRectangle(color: Color, width: Dp? = null, height: Dp? = null) {
-    Layout(
-        children = { DrawRectangle(color = color) },
-        layoutBlock = { _, constraints ->
-            val widthPx = width?.toIntPx() ?: constraints.maxWidth
-            val heightPx = height?.toIntPx() ?: constraints.maxHeight
-            layout(widthPx, heightPx) {}
-        })
+    Layout(children = { DrawRectangle(color = color) }) { _, constraints ->
+        val widthPx = width?.toIntPx() ?: constraints.maxWidth
+        val heightPx = height?.toIntPx() ?: constraints.maxHeight
+        layout(widthPx, heightPx) {}
+    }
 }
 
 @Composable
diff --git a/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/TableSamples.kt b/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/TableSamples.kt
index fc5c908..30f28cf 100644
--- a/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/TableSamples.kt
+++ b/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/TableSamples.kt
@@ -29,13 +29,11 @@
 @Composable
 fun SimpleTable() {
     Padding(2.dp) {
-        Table {
+        Table(columnCount = 8) {
             for (i in 0 until 8) {
                 tableRow {
-                    for (j in 0 until 8) {
-                        Padding(2.dp) {
-                            SizedRectangle(color = Color.Fuchsia, height = 50.dp)
-                        }
+                    Padding(2.dp) {
+                        SizedRectangle(color = Color.Fuchsia, height = 50.dp)
                     }
                 }
             }
@@ -48,6 +46,7 @@
 fun TableWithDifferentColumnWidths() {
     Padding(2.dp) {
         Table(
+            columnCount = 5,
             columnWidth = { columnIndex ->
                 when (columnIndex) {
                     0 -> TableColumnWidth.Inflexible.Wrap
@@ -59,12 +58,11 @@
             }
         ) {
             for (i in 0 until 8) {
-                tableRow {
+                tableRow { j ->
                     Padding(2.dp) {
-                        SizedRectangle(color = Color.Fuchsia, width = 25.dp, height = 25.dp)
-                    }
-                    for (j in 1 until 5) {
-                        Padding(2.dp) {
+                        if (j == 0) {
+                            SizedRectangle(color = Color.Fuchsia, width = 25.dp, height = 25.dp)
+                        } else {
                             SizedRectangle(color = Color.Fuchsia, height = 25.dp)
                         }
                     }
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AlignTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AlignTest.kt
index d4cab2b..64fd740 100644
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AlignTest.kt
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AlignTest.kt
@@ -113,7 +113,7 @@
                         }
                     }
                 },
-                layoutBlock = { measurables, constraints ->
+                measureBlock = { measurables, constraints ->
                     val placeable = measurables.first().measure(Constraints())
                     layout(constraints.maxWidth, constraints.maxHeight) {
                         placeable.place(0.ipx, 0.ipx)
@@ -236,7 +236,7 @@
                             }
                         }
                     }
-                }, layoutBlock = { measurables, constraints ->
+                }, measureBlock = { measurables, constraints ->
                     val placeable = measurables.first().measure(Constraints())
                     layout(constraints.maxWidth, constraints.maxHeight) {
                         placeable.place(0.ipx, 0.ipx)
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ContainerTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ContainerTest.kt
index 8a68a98..6ffd748 100644
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ContainerTest.kt
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ContainerTest.kt
@@ -352,11 +352,11 @@
 
     @Composable
     fun EmptyBox(width: Dp, height: Dp) {
-        Layout(layoutBlock = { _, constraints ->
+        Layout(children = { }) { _, constraints ->
             layout(
                 width.toIntPx().coerceIn(constraints.minWidth, constraints.maxWidth),
                 height.toIntPx().coerceIn(constraints.minHeight, constraints.maxHeight)
             ) {}
-        }, children = { })
+        }
     }
 }
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/IntrinsicTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/IntrinsicTest.kt
index 556d6b4..6c62f1e 100644
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/IntrinsicTest.kt
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/IntrinsicTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.ui.layout.test
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.test.filters.SmallTest
@@ -499,12 +498,13 @@
     width: Dp,
     maxIntrinsicWidth: Dp,
     minIntrinsicHeight: Dp,
-    height: Dp, maxIntrinsicHeight: Dp,
+    height: Dp,
+    maxIntrinsicHeight: Dp,
     children: @Composable() () -> Unit
 ) {
     ComplexLayout(children) {
-        layout { _, constraints ->
-            layoutResult(
+        measure { _, constraints ->
+            layout(
                 width.toIntPx().coerceIn(constraints.minWidth, constraints.maxWidth),
                 height.toIntPx().coerceIn(constraints.minHeight, constraints.maxHeight)
             ) { }
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/LayoutTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/LayoutTest.kt
index ea2810b..6b940fb 100644
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/LayoutTest.kt
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/LayoutTest.kt
@@ -29,7 +29,6 @@
 import androidx.ui.core.PxSize
 import androidx.ui.core.Ref
 import androidx.ui.core.px
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.ui.core.ComplexLayout
@@ -140,7 +139,7 @@
             val layoutLatch = CountDownLatch(1)
             show {
                 ComplexLayout(layout) {
-                    layout { measurables, _ ->
+                    measure { measurables, _ ->
                         val measurable = measurables.first()
                         test(
                             { h -> measurable.minIntrinsicWidth(h) },
@@ -149,6 +148,7 @@
                             { w -> measurable.maxIntrinsicHeight(w) }
                         )
                         layoutLatch.countDown()
+                        layout(0.ipx, 0.ipx) {}
                     }
                     minIntrinsicWidth { _, _ -> 0.ipx }
                     maxIntrinsicWidth { _, _ -> 0.ipx }
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ScrollerPerformance.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ScrollerPerformance.kt
deleted file mode 100644
index 652694d..0000000
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ScrollerPerformance.kt
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright 2019 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.ui.layout.test
-
-import android.view.View
-import androidx.benchmark.junit4.BenchmarkRule
-import androidx.benchmark.junit4.measureRepeated
-import androidx.compose.Composable
-import androidx.compose.CompositionContext
-import androidx.compose.FrameManager
-import androidx.compose.composer
-import androidx.compose.memo
-import androidx.compose.unaryPlus
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.LargeTest
-import androidx.ui.core.Draw
-import androidx.ui.core.dp
-import androidx.ui.core.px
-import androidx.ui.core.setContent
-import androidx.ui.core.toRect
-import androidx.ui.core.withDensity
-import androidx.ui.graphics.Color
-import androidx.ui.layout.Column
-import androidx.ui.layout.Container
-import androidx.ui.layout.CrossAxisAlignment
-import androidx.ui.layout.ScrollerPosition
-import androidx.ui.layout.VerticalScroller
-import androidx.ui.painting.Paint
-import androidx.ui.painting.PaintingStyle
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@LargeTest
-@RunWith(JUnit4::class)
-class ScrollerPerformance : LayoutTest() {
-    @get:Rule
-    val benchmarkRule = BenchmarkRule()
-
-    @Test
-    @FlakyTest
-    fun benchmarkScrollLayout() {
-        val scrollerPosition = ScrollerPosition()
-        val compositionContext =
-            composeScroller(scrollerPosition = scrollerPosition)
-
-        val view = findAndroidCraneView()
-
-        activityTestRule.runOnUiThread(object : Runnable {
-            override fun run() {
-                val widthSpec =
-                    View.MeasureSpec.makeMeasureSpec(view.measuredWidth, View.MeasureSpec.EXACTLY)
-                val heightSpec =
-                    View.MeasureSpec.makeMeasureSpec(view.measuredHeight, View.MeasureSpec.EXACTLY)
-                compositionContext.compose()
-                view.measure(widthSpec, heightSpec)
-                view.layout(view.left, view.top, view.right, view.bottom)
-
-                val exec: BenchmarkRule.Scope.() -> Unit = {
-                    runWithTimingDisabled {
-                        if (scrollerPosition.position == 0.px) {
-                            scrollerPosition.position = 10.px
-                        } else {
-                            scrollerPosition.position = 0.px
-                        }
-                        FrameManager.nextFrame()
-                        compositionContext.recomposeSync()
-                        view.requestLayout()
-                    }
-                    view.measure(widthSpec, heightSpec)
-                    view.layout(view.left, view.top, view.right, view.bottom)
-                }
-                benchmarkRule.measureRepeated(exec)
-            }
-        })
-    }
-
-    @Test
-    @FlakyTest
-    fun benchmarkScrollComposition() {
-        val scrollerPosition = ScrollerPosition()
-        val compositionContext =
-            composeScroller(scrollerPosition = scrollerPosition)
-
-        activityTestRule.runOnUiThread(object : Runnable {
-            override fun run() {
-                compositionContext.compose()
-                val exec: BenchmarkRule.Scope.() -> Unit = {
-                    runWithTimingDisabled {
-                        if (scrollerPosition.position == 0.px) {
-                            scrollerPosition.position = 10.px
-                        } else {
-                            scrollerPosition.position = 0.px
-                        }
-                        FrameManager.nextFrame()
-                    }
-                    compositionContext.recomposeSync()
-                }
-                benchmarkRule.measureRepeated(exec)
-            }
-        })
-    }
-
-    @Test
-    @FlakyTest
-    fun benchmarkLargeComposition() {
-        val scrollerPosition = ScrollerPosition()
-        val compositionContext =
-            composeScroller(scrollerPosition = scrollerPosition)
-
-        activityTestRule.runOnUiThread(object : Runnable {
-            override fun run() {
-                compositionContext.compose()
-                val exec: BenchmarkRule.Scope.() -> Unit = {
-                    runWithTimingDisabled {
-                        if (scrollerPosition.position == 0.px) {
-                            scrollerPosition.position = 10.px
-                        } else {
-                            scrollerPosition.position = 0.px
-                        }
-                        FrameManager.nextFrame()
-                    }
-                    compositionContext.compose()
-                }
-                benchmarkRule.measureRepeated(exec)
-            }
-        })
-    }
-
-    fun composeScroller(
-        scrollerPosition: ScrollerPosition = ScrollerPosition()
-    ): CompositionContext {
-        var compositionContext: CompositionContext? = null
-        // We assume that the height of the device is more than 45 px
-        withDensity(density) {
-            val runnable: Runnable = object : Runnable {
-                override fun run() {
-                    compositionContext = activity.setContent {
-                        VerticalScroller(
-                            scrollerPosition = scrollerPosition
-                        ) {
-                            Column(crossAxisAlignment = CrossAxisAlignment.Start) {
-                                for (green in 0..0xFF) {
-                                    ColorStripe(0xFF, green, 0)
-                                }
-                                for (red in 0xFF downTo 0) {
-                                    ColorStripe(red, 0xFF, 0)
-                                }
-                                for (blue in 0..0xFF) {
-                                    ColorStripe(0, 0xFF, blue)
-                                }
-                                for (green in 0xFF downTo 0) {
-                                    ColorStripe(0, green, 0xFF)
-                                }
-                                for (red in 0..0xFF) {
-                                    ColorStripe(red, 0, 0xFF)
-                                }
-                                for (blue in 0xFF downTo 0) {
-                                    ColorStripe(0xFF, 0, blue)
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            activityTestRule.runOnUiThread(runnable)
-        }
-        return compositionContext!!
-    }
-}
-
-@Composable
-fun ColorStripe(red: Int, green: Int, blue: Int) {
-    val paint = +memo { Paint() }
-    Container(height = 5.dp, width = 45.dp) {
-        Draw { canvas, parentSize ->
-            paint.color = Color(red = red, green = green, blue = blue)
-            paint.style = PaintingStyle.fill
-            canvas.drawRect(parentSize.toRect(), paint)
-        }
-    }
-}
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ScrollerTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ScrollerTest.kt
index d68cb50..b15be36 100644
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ScrollerTest.kt
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ScrollerTest.kt
@@ -42,6 +42,8 @@
 import androidx.compose.composer
 import androidx.test.filters.SdkSuppress
 import androidx.ui.core.setContent
+import androidx.ui.layout.HorizontalScroller
+import androidx.ui.layout.Row
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertNotEquals
 import org.junit.Assert.assertTrue
@@ -76,17 +78,17 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun verticalScroller_SmallContent() {
-        composeScroller()
+        composeVerticalScroller()
 
-        validateScroller(0, 40)
+        validateVerticalScroller(0, 40)
     }
 
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun verticalScroller_LargeContent_NoScroll() {
-        composeScroller(height = 30.ipx)
+        composeVerticalScroller(height = 30.ipx)
 
-        validateScroller(0, 30)
+        validateVerticalScroller(0, 30)
     }
 
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
@@ -95,11 +97,11 @@
         val scrollerPosition = ScrollerPosition()
 
         val changeListener = ScrollerChangeListener(scrollerPosition)
-        composeScroller(scrollerPosition, changeListener, height = 30.ipx)
+        composeVerticalScroller(scrollerPosition, changeListener, height = 30.ipx)
 
         changeListener.waitForChange()
 
-        validateScroller(0, 30)
+        validateVerticalScroller(0, 30)
 
         // The 'draw' method will no longer be called because only the position
         // changes during scrolling. Therefore, we should just wait until the draw stage
@@ -119,10 +121,59 @@
         runOnUiThread {
             activity.window.decorView.viewTreeObserver.removeOnDrawListener(onDrawListener)
         }
-        validateScroller(10, 30)
+        validateVerticalScroller(10, 30)
     }
 
-    private fun composeScroller(
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun horizontalScroller_SmallContent() {
+        composeHorizontalScroller()
+
+        validateHorizontalScroller(0, 40)
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun horizontalScroller_LargeContent_NoScroll() {
+        composeHorizontalScroller(width = 30.ipx)
+
+        validateHorizontalScroller(0, 30)
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun horizontalScroller_LargeContent_ScrollToEnd() {
+        val scrollerPosition = ScrollerPosition()
+
+        val changeListener = ScrollerChangeListener(scrollerPosition)
+        composeHorizontalScroller(scrollerPosition, changeListener, width = 30.ipx)
+
+        changeListener.waitForChange()
+
+        validateHorizontalScroller(0, 30)
+
+        // The 'draw' method will no longer be called because only the position
+        // changes during scrolling. Therefore, we should just wait until the draw stage
+        // completes and the scrolling will be finished by then.
+        val latch = CountDownLatch(1)
+        val onDrawListener = object : ViewTreeObserver.OnDrawListener {
+            override fun onDraw() {
+                latch.countDown()
+            }
+        }
+        runOnUiThread {
+            activity.window.decorView.viewTreeObserver.addOnDrawListener(onDrawListener)
+            assertEquals(10.px, changeListener.maxPosition)
+            scrollerPosition.position = 10.px
+        }
+        assertTrue(latch.await(1, TimeUnit.SECONDS))
+        runOnUiThread {
+            activity.window.decorView.viewTreeObserver.removeOnDrawListener(onDrawListener)
+        }
+        validateHorizontalScroller(10, 30)
+    }
+
+    private fun composeVerticalScroller(
         scrollerPosition: ScrollerPosition = ScrollerPosition(),
         onScrollChanged: (position: Px, maxPosition: Px) -> Unit = { position, _ ->
             scrollerPosition.position = position
@@ -169,7 +220,54 @@
         }
     }
 
-    private fun validateScroller(
+    private fun composeHorizontalScroller(
+        scrollerPosition: ScrollerPosition = ScrollerPosition(),
+        onScrollChanged: (position: Px, maxPosition: Px) -> Unit = { position, _ ->
+            scrollerPosition.position = position
+        },
+        width: IntPx = 40.ipx
+    ) {
+        // We assume that the height of the device is more than 45 px
+        withDensity(density) {
+            val constraints = DpConstraints.tightConstraints(width.toDp(), 45.px.toDp())
+            val runnable: Runnable = object : Runnable {
+                override fun run() {
+                    activity.setContent {
+                        Align(alignment = Alignment.TopLeft) {
+                            ConstrainedBox(constraints = constraints) {
+                                HorizontalScroller(
+                                    scrollerPosition = scrollerPosition,
+                                    onScrollChanged = onScrollChanged
+                                ) {
+                                    Row(crossAxisAlignment = CrossAxisAlignment.Start) {
+                                        colors.forEach { color ->
+                                            Container(
+                                                width = 5.px.toDp(),
+                                                height = 45.px.toDp()
+                                            ) {
+                                                Draw { canvas, parentSize ->
+                                                    val paint = Paint()
+                                                    paint.color = color
+                                                    paint.style = PaintingStyle.fill
+                                                    canvas.drawRect(parentSize.toRect(), paint)
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                                Draw { _, _ ->
+                                    drawLatch.countDown()
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            activityTestRule.runOnUiThread(runnable)
+        }
+    }
+
+    private fun validateVerticalScroller(
         offset: Int,
         height: Int,
         width: Int = 45
@@ -193,6 +291,30 @@
         }
     }
 
+    private fun validateHorizontalScroller(
+        offset: Int,
+        width: Int,
+        height: Int = 45
+    ) {
+        assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
+
+        val bitmap = waitAndScreenShot()
+        assertTrue(bitmap.height >= 45)
+        assertTrue(bitmap.width >= width)
+        for (x in 0 until width) {
+            val colorIndex = (offset + x) / 5
+            val expectedColor = colors[colorIndex]
+
+            for (y in 0 until height) {
+                val pixel = bitmap.getPixel(x, y)
+                assertEquals(
+                    "Expected $expectedColor, but got ${Color(pixel)} at $x, $y",
+                    expectedColor.toArgb(), pixel
+                )
+            }
+        }
+    }
+
     // We only need this because IR compiler doesn't like converting lambdas to Runnables
     private fun runOnUiThread(block: () -> Unit) {
         @Suppress("ObjectLiteralToLambda") val runnable: Runnable = object : Runnable {
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/TableTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/TableTest.kt
index 889d4c9..2775d74 100644
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/TableTest.kt
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/TableTest.kt
@@ -18,6 +18,7 @@
 
 import androidx.compose.composer
 import androidx.test.filters.SmallTest
+import androidx.ui.core.IntPx
 import androidx.ui.core.OnChildPositioned
 import androidx.ui.core.PxPosition
 import androidx.ui.core.PxSize
@@ -33,7 +34,6 @@
 import androidx.ui.layout.DpConstraints
 import androidx.ui.layout.Table
 import androidx.ui.layout.TableColumnWidth
-import androidx.ui.layout.sum
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
@@ -67,17 +67,15 @@
                         tableSize.value = coordinates.size
                         positionedLatch.countDown()
                     }) {
-                        Table {
+                        Table(columnCount = columns) {
                             for (i in 0 until rows) {
-                                tableRow {
-                                    for (j in 0 until columns) {
-                                        Container(height = sizeDp, expanded = true) {
-                                            SaveLayoutInfo(
-                                                size = childSize[i][j],
-                                                position = childPosition[i][j],
-                                                positionedLatch = positionedLatch
-                                            )
-                                        }
+                                tableRow { j ->
+                                    Container(height = sizeDp, expanded = true) {
+                                        SaveLayoutInfo(
+                                            size = childSize[i][j],
+                                            position = childPosition[i][j],
+                                            positionedLatch = positionedLatch
+                                        )
                                     }
                                 }
                             }
@@ -131,20 +129,18 @@
                         tableSize.value = coordinates.size
                         positionedLatch.countDown()
                     }) {
-                        Table {
+                        Table(columnCount = columns) {
                             for (i in 0 until rows) {
-                                tableRow {
-                                    for (j in 0 until columns) {
-                                        Container(
-                                            height = if (j % 2 == 0) sizeDp else halfSizeDp,
-                                            expanded = true
-                                        ) {
-                                            SaveLayoutInfo(
-                                                size = childSize[i][j],
-                                                position = childPosition[i][j],
-                                                positionedLatch = positionedLatch
-                                            )
-                                        }
+                                tableRow { j ->
+                                    Container(
+                                        height = if (j % 2 == 0) sizeDp else halfSizeDp,
+                                        expanded = true
+                                    ) {
+                                        SaveLayoutInfo(
+                                            size = childSize[i][j],
+                                            position = childPosition[i][j],
+                                            positionedLatch = positionedLatch
+                                        )
                                     }
                                 }
                             }
@@ -199,19 +195,17 @@
                         tableSize.value = coordinates.size
                         positionedLatch.countDown()
                     }) {
-                        Table(columnWidth = { j ->
+                        Table(columnCount = columns, columnWidth = { j ->
                             TableColumnWidth.Flexible(flex = flexes[j])
                         }) {
                             for (i in 0 until rows) {
-                                tableRow {
-                                    for (j in 0 until columns) {
-                                        Container(height = sizeDp, expanded = true) {
-                                            SaveLayoutInfo(
-                                                size = childSize[i][j],
-                                                position = childPosition[i][j],
-                                                positionedLatch = positionedLatch
-                                            )
-                                        }
+                                tableRow { j ->
+                                    Container(height = sizeDp, expanded = true) {
+                                        SaveLayoutInfo(
+                                            size = childSize[i][j],
+                                            position = childPosition[i][j],
+                                            positionedLatch = positionedLatch
+                                        )
                                     }
                                 }
                             }
@@ -260,17 +254,18 @@
                     tableSize.value = coordinates.size
                     positionedLatch.countDown()
                 }) {
-                    Table(columnWidth = { TableColumnWidth.Inflexible.Wrap }) {
+                    Table(
+                        columnCount = columns,
+                        columnWidth = { TableColumnWidth.Inflexible.Wrap }
+                    ) {
                         for (i in 0 until rows) {
-                            tableRow {
-                                for (j in 0 until columns) {
-                                    Container(width = sizeDp, height = sizeDp) {
-                                        SaveLayoutInfo(
-                                            size = childSize[i][j],
-                                            position = childPosition[i][j],
-                                            positionedLatch = positionedLatch
-                                        )
-                                    }
+                            tableRow { j ->
+                                Container(width = sizeDp, height = sizeDp) {
+                                    SaveLayoutInfo(
+                                        size = childSize[i][j],
+                                        position = childPosition[i][j],
+                                        positionedLatch = positionedLatch
+                                    )
                                 }
                             }
                         }
@@ -318,17 +313,18 @@
                     tableSize.value = coordinates.size
                     positionedLatch.countDown()
                 }) {
-                    Table(columnWidth = { TableColumnWidth.Inflexible.Fixed(width = sizeDp) }) {
+                    Table(
+                        columnCount = columns,
+                        columnWidth = { TableColumnWidth.Inflexible.Fixed(width = sizeDp) }
+                    ) {
                         for (i in 0 until rows) {
-                            tableRow {
-                                for (j in 0 until columns) {
-                                    Container(height = sizeDp, expanded = true) {
-                                        SaveLayoutInfo(
-                                            size = childSize[i][j],
-                                            position = childPosition[i][j],
-                                            positionedLatch = positionedLatch
-                                        )
-                                    }
+                            tableRow { j ->
+                                Container(height = sizeDp, expanded = true) {
+                                    SaveLayoutInfo(
+                                        size = childSize[i][j],
+                                        position = childPosition[i][j],
+                                        positionedLatch = positionedLatch
+                                    )
                                 }
                             }
                         }
@@ -381,19 +377,17 @@
                         tableSize.value = coordinates.size
                         positionedLatch.countDown()
                     }) {
-                        Table(columnWidth = { j ->
+                        Table(columnCount = columns, columnWidth = { j ->
                             TableColumnWidth.Inflexible.Fraction(fraction = fractions[j])
                         }) {
                             for (i in 0 until rows) {
-                                tableRow {
-                                    for (j in 0 until columns) {
-                                        Container(height = sizeDp, expanded = true) {
-                                            SaveLayoutInfo(
-                                                size = childSize[i][j],
-                                                position = childPosition[i][j],
-                                                positionedLatch = positionedLatch
-                                            )
-                                        }
+                                tableRow { j ->
+                                    Container(height = sizeDp, expanded = true) {
+                                        SaveLayoutInfo(
+                                            size = childSize[i][j],
+                                            position = childPosition[i][j],
+                                            positionedLatch = positionedLatch
+                                        )
                                     }
                                 }
                             }
@@ -447,7 +441,7 @@
                         tableSize.value = coordinates.size
                         positionedLatch.countDown()
                     }) {
-                        Table(columnWidth = { j ->
+                        Table(columnCount = columns, columnWidth = { j ->
                             TableColumnWidth.Inflexible.Min(
                                 a = TableColumnWidth.Inflexible.Fixed(width = minWidthDp),
                                 b = TableColumnWidth.Inflexible.Fraction(
@@ -456,15 +450,13 @@
                             )
                         }) {
                             for (i in 0 until rows) {
-                                tableRow {
-                                    for (j in 0 until columns) {
-                                        Container(height = sizeDp, expanded = true) {
-                                            SaveLayoutInfo(
-                                                size = childSize[i][j],
-                                                position = childPosition[i][j],
-                                                positionedLatch = positionedLatch
-                                            )
-                                        }
+                                tableRow { j ->
+                                    Container(height = sizeDp, expanded = true) {
+                                        SaveLayoutInfo(
+                                            size = childSize[i][j],
+                                            position = childPosition[i][j],
+                                            positionedLatch = positionedLatch
+                                        )
                                     }
                                 }
                             }
@@ -522,7 +514,7 @@
                         tableSize.value = coordinates.size
                         positionedLatch.countDown()
                     }) {
-                        Table(columnWidth = { j ->
+                        Table(columnCount = columns, columnWidth = { j ->
                             TableColumnWidth.Inflexible.Max(
                                 a = TableColumnWidth.Inflexible.Fixed(width = maxWidthDp),
                                 b = TableColumnWidth.Inflexible.Fraction(
@@ -531,15 +523,13 @@
                             )
                         }) {
                             for (i in 0 until rows) {
-                                tableRow {
-                                    for (j in 0 until columns) {
-                                        Container(height = sizeDp, expanded = true) {
-                                            SaveLayoutInfo(
-                                                size = childSize[i][j],
-                                                position = childPosition[i][j],
-                                                positionedLatch = positionedLatch
-                                            )
-                                        }
+                                tableRow { j ->
+                                    Container(height = sizeDp, expanded = true) {
+                                        SaveLayoutInfo(
+                                            size = childSize[i][j],
+                                            position = childPosition[i][j],
+                                            positionedLatch = positionedLatch
+                                        )
                                     }
                                 }
                             }
@@ -594,20 +584,23 @@
                     tableSize.value = coordinates.size
                     positionedLatch.countDown()
                 }) {
-                    Table(columnWidth = { TableColumnWidth.Inflexible.Min(
-                        a = TableColumnWidth.Inflexible.Wrap,
-                        b = TableColumnWidth.Inflexible.Fixed(width = sizeDp)
-                    ) }) {
+                    Table(
+                        columnCount = columns,
+                        columnWidth = {
+                            TableColumnWidth.Inflexible.Min(
+                                a = TableColumnWidth.Inflexible.Wrap,
+                                b = TableColumnWidth.Inflexible.Fixed(width = sizeDp)
+                            )
+                        }
+                    ) {
                         for (i in 0 until rows) {
-                            tableRow {
-                                for (j in 0 until columns) {
-                                    Container(width = halfSizeDp, height = sizeDp) {
-                                        SaveLayoutInfo(
-                                            size = childSize[i][j],
-                                            position = childPosition[i][j],
-                                            positionedLatch = positionedLatch
-                                        )
-                                    }
+                            tableRow { j ->
+                                Container(width = halfSizeDp, height = sizeDp) {
+                                    SaveLayoutInfo(
+                                        size = childSize[i][j],
+                                        position = childPosition[i][j],
+                                        positionedLatch = positionedLatch
+                                    )
                                 }
                             }
                         }
@@ -657,20 +650,23 @@
                     tableSize.value = coordinates.size
                     positionedLatch.countDown()
                 }) {
-                    Table(columnWidth = { TableColumnWidth.Inflexible.Max(
-                        a = TableColumnWidth.Inflexible.Wrap,
-                        b = TableColumnWidth.Inflexible.Fixed(width = sizeDp)
-                    ) }) {
+                    Table(
+                        columnCount = columns,
+                        columnWidth = {
+                            TableColumnWidth.Inflexible.Max(
+                                a = TableColumnWidth.Inflexible.Wrap,
+                                b = TableColumnWidth.Inflexible.Fixed(width = sizeDp)
+                            )
+                        }
+                    ) {
                         for (i in 0 until rows) {
-                            tableRow {
-                                for (j in 0 until columns) {
-                                    Container(width = halfSizeDp, height = sizeDp) {
-                                        SaveLayoutInfo(
-                                            size = childSize[i][j],
-                                            position = childPosition[i][j],
-                                            positionedLatch = positionedLatch
-                                        )
-                                    }
+                            tableRow { j ->
+                                Container(width = halfSizeDp, height = sizeDp) {
+                                    SaveLayoutInfo(
+                                        size = childSize[i][j],
+                                        position = childPosition[i][j],
+                                        positionedLatch = positionedLatch
+                                    )
                                 }
                             }
                         }
@@ -718,20 +714,20 @@
                     tableSize.value = coordinates.size
                     positionedLatch.countDown()
                 }) {
-                    Table(columnWidth = { TableColumnWidth.Inflexible.Min(
-                        a = TableColumnWidth.Inflexible.Wrap,
-                        b = TableColumnWidth.Inflexible.Wrap
-                    ) }) {
+                    Table(columnCount = columns, columnWidth = {
+                        TableColumnWidth.Inflexible.Min(
+                            a = TableColumnWidth.Inflexible.Wrap,
+                            b = TableColumnWidth.Inflexible.Wrap
+                        )
+                    }) {
                         for (i in 0 until rows) {
-                            tableRow {
-                                for (j in 0 until columns) {
-                                    Container(width = sizeDp, height = sizeDp) {
-                                        SaveLayoutInfo(
-                                            size = childSize[i][j],
-                                            position = childPosition[i][j],
-                                            positionedLatch = positionedLatch
-                                        )
-                                    }
+                            tableRow { j ->
+                                Container(width = sizeDp, height = sizeDp) {
+                                    SaveLayoutInfo(
+                                        size = childSize[i][j],
+                                        position = childPosition[i][j],
+                                        positionedLatch = positionedLatch
+                                    )
                                 }
                             }
                         }
@@ -779,20 +775,20 @@
                     tableSize.value = coordinates.size
                     positionedLatch.countDown()
                 }) {
-                    Table(columnWidth = { TableColumnWidth.Inflexible.Max(
-                        a = TableColumnWidth.Inflexible.Wrap,
-                        b = TableColumnWidth.Inflexible.Wrap
-                    ) }) {
+                    Table(columnCount = columns, columnWidth = {
+                        TableColumnWidth.Inflexible.Max(
+                            a = TableColumnWidth.Inflexible.Wrap,
+                            b = TableColumnWidth.Inflexible.Wrap
+                        )
+                    }) {
                         for (i in 0 until rows) {
-                            tableRow {
-                                for (j in 0 until columns) {
-                                    Container(width = sizeDp, height = sizeDp) {
-                                        SaveLayoutInfo(
-                                            size = childSize[i][j],
-                                            position = childPosition[i][j],
-                                            positionedLatch = positionedLatch
-                                        )
-                                    }
+                            tableRow { j ->
+                                Container(width = sizeDp, height = sizeDp) {
+                                    SaveLayoutInfo(
+                                        size = childSize[i][j],
+                                        position = childPosition[i][j],
+                                        positionedLatch = positionedLatch
+                                    )
                                 }
                             }
                         }
@@ -845,7 +841,7 @@
                         tableSize.value = coordinates.size
                         positionedLatch.countDown()
                     }) {
-                        Table(columnWidth = { j ->
+                        Table(columnCount = columns, columnWidth = { j ->
                             when (j) {
                                 0 -> TableColumnWidth.Inflexible.Wrap
                                 1 -> TableColumnWidth.Flexible(flex = 1f)
@@ -855,39 +851,15 @@
                             }
                         }) {
                             for (i in 0 until rows) {
-                                tableRow {
-                                    Container(height = sizeDp, width = halfSizeDp) {
+                                tableRow { j ->
+                                    Container(
+                                        width = if (j == 0) halfSizeDp else null,
+                                        height = sizeDp,
+                                        expanded = j != 0
+                                    ) {
                                         SaveLayoutInfo(
-                                            size = childSize[i][0],
-                                            position = childPosition[i][0],
-                                            positionedLatch = positionedLatch
-                                        )
-                                    }
-                                    Container(height = sizeDp, expanded = true) {
-                                        SaveLayoutInfo(
-                                            size = childSize[i][1],
-                                            position = childPosition[i][1],
-                                            positionedLatch = positionedLatch
-                                        )
-                                    }
-                                    Container(height = sizeDp, expanded = true) {
-                                        SaveLayoutInfo(
-                                            size = childSize[i][2],
-                                            position = childPosition[i][2],
-                                            positionedLatch = positionedLatch
-                                        )
-                                    }
-                                    Container(height = sizeDp, expanded = true) {
-                                        SaveLayoutInfo(
-                                            size = childSize[i][3],
-                                            position = childPosition[i][3],
-                                            positionedLatch = positionedLatch
-                                        )
-                                    }
-                                    Container(height = sizeDp, expanded = true) {
-                                        SaveLayoutInfo(
-                                            size = childSize[i][4],
-                                            position = childPosition[i][4],
+                                            size = childSize[i][j],
+                                            position = childPosition[i][j],
                                             positionedLatch = positionedLatch
                                         )
                                     }
@@ -953,4 +925,7 @@
             )
         }
     }
+
+    private fun Array<IntPx>.sum() = this.fold(IntPx.Zero) { a, b -> a + b }
+    private fun Collection<IntPx>.sum() = this.fold(IntPx.Zero) { a, b -> a + b }
 }
\ No newline at end of file
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Align.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Align.kt
index 888706f..3eca354 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Align.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Align.kt
@@ -21,7 +21,6 @@
 import androidx.ui.core.Layout
 import androidx.ui.core.isFinite
 import androidx.ui.core.looseMin
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.ui.core.round
@@ -70,7 +69,7 @@
  */
 @Composable
 fun Align(alignment: Alignment, children: @Composable() () -> Unit) {
-    Layout(layoutBlock = { measurables, constraints ->
+    Layout(children) { measurables, constraints ->
         val measurable = measurables.firstOrNull()
         // The child cannot be larger than our max constraints, but we ignore min constraints.
         val placeable = measurable?.measure(constraints.looseMin())
@@ -96,7 +95,7 @@
                 placeable.place(position.x, position.y)
             }
         }
-    }, children = children)
+    }
 }
 
 /**
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/ConstrainedBox.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/ConstrainedBox.kt
index 7ad2633..ed2d6f1 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/ConstrainedBox.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/ConstrainedBox.kt
@@ -16,7 +16,6 @@
 
 package androidx.ui.layout
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.ui.core.Constraints
@@ -41,14 +40,14 @@
     children: @Composable() () -> Unit
 ) {
     ComplexLayout(children) {
-        layout { measurables, incomingConstraints ->
+        measure { measurables, incomingConstraints ->
             val measurable = measurables.firstOrNull()
             val childConstraints = Constraints(constraints).enforce(incomingConstraints)
             val placeable = measurable?.measure(childConstraints)
 
             val layoutWidth = placeable?.width ?: childConstraints.minWidth
             val layoutHeight = placeable?.height ?: childConstraints.minHeight
-            layoutResult(layoutWidth, layoutHeight) {
+            layout(layoutWidth, layoutHeight) {
                 placeable?.place(IntPx.Zero, IntPx.Zero)
             }
         }
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Container.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Container.kt
index dc48a4b..8123f2c 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Container.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Container.kt
@@ -28,7 +28,6 @@
 import androidx.ui.core.max
 import androidx.ui.core.offset
 import androidx.ui.core.withTight
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.compose.trace
@@ -64,7 +63,7 @@
     children: @Composable() () -> Unit
 ) {
     trace("UI:Container") {
-        Layout(children = children, layoutBlock = { measurables, incomingConstraints ->
+        Layout(children) { measurables, incomingConstraints ->
             val containerConstraints = Constraints(constraints)
                 .withTight(width?.toIntPx(), height?.toIntPx())
                 .enforce(incomingConstraints)
@@ -98,6 +97,6 @@
                     )
                 }
             }
-        })
+        }
     }
 }
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Flex.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Flex.kt
index 21a9a37..9321ebe 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Flex.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Flex.kt
@@ -17,7 +17,6 @@
 package androidx.ui.layout
 
 import androidx.annotation.FloatRange
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.ui.core.Constraints
@@ -101,7 +100,7 @@
     mainAxisSize: FlexSize = FlexSize.Max,
     crossAxisAlignment: CrossAxisAlignment = CrossAxisAlignment.Center,
     crossAxisSize: FlexSize = FlexSize.Min,
-    @Children(composable = false) block: FlexChildren.() -> Unit
+    block: FlexChildren.() -> Unit
 ) {
     Flex(
         orientation = FlexOrientation.Horizontal,
@@ -144,7 +143,7 @@
     mainAxisSize: FlexSize = FlexSize.Max,
     crossAxisAlignment: CrossAxisAlignment = CrossAxisAlignment.Center,
     crossAxisSize: FlexSize = FlexSize.Min,
-    @Children(composable = false) block: FlexChildren.() -> Unit
+    block: FlexChildren.() -> Unit
 ) {
     Flex(
         orientation = FlexOrientation.Vertical,
@@ -476,7 +475,7 @@
     mainAxisAlignment: MainAxisAlignment = MainAxisAlignment.Start,
     crossAxisSize: FlexSize = FlexSize.Min,
     crossAxisAlignment: CrossAxisAlignment = CrossAxisAlignment.Center,
-    @Children(composable = false) block: FlexChildren.() -> Unit
+    block: FlexChildren.() -> Unit
 ) {
     fun Placeable.mainAxisSize() = if (orientation == FlexOrientation.Horizontal) width else height
     fun Placeable.crossAxisSize() = if (orientation == FlexOrientation.Horizontal) height else width
@@ -489,7 +488,7 @@
         composable
     }
     ComplexLayout(flexChildren) {
-        layout { children, outerConstraints ->
+        measure { children, outerConstraints ->
             val constraints = OrientationIndependentConstraints(outerConstraints, orientation)
 
             var totalFlex = 0f
@@ -585,7 +584,7 @@
             } else {
                 mainAxisLayoutSize
             }
-            layoutResult(layoutWidth, layoutHeight) {
+            layout(layoutWidth, layoutHeight) {
                 val childrenMainAxisSize = placeables.map { it!!.mainAxisSize() }
                 val mainAxisPositions = mainAxisAlignment.aligner
                     .align(mainAxisLayoutSize, childrenMainAxisSize)
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Intrinsic.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Intrinsic.kt
index 3bd2915..a9d3480 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Intrinsic.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Intrinsic.kt
@@ -16,7 +16,6 @@
 
 package androidx.ui.layout
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.ui.core.ComplexLayout
@@ -44,13 +43,13 @@
 @Composable
 fun MinIntrinsicWidth(children: @Composable() () -> Unit) {
     ComplexLayout(children) {
-        layout { measurables, constraints ->
+        measure { measurables, constraints ->
             val measurable = measurables.firstOrNull()
             val width = measurable?.minIntrinsicWidth(constraints.maxHeight) ?: 0.ipx
             val placeable = measurable?.measure(
                 Constraints.tightConstraintsForWidth(width).enforce(constraints)
             )
-            layoutResult(placeable?.width ?: 0.ipx, placeable?.height ?: 0.ipx) {
+            layout(placeable?.width ?: 0.ipx, placeable?.height ?: 0.ipx) {
                 placeable?.place(0.ipx, 0.ipx)
             }
         }
@@ -89,13 +88,13 @@
 @Composable
 fun MinIntrinsicHeight(children: @Composable() () -> Unit) {
     ComplexLayout(children) {
-        layout { measurables, constraints ->
+        measure { measurables, constraints ->
             val measurable = measurables.firstOrNull()
             val height = measurable?.minIntrinsicHeight(constraints.maxWidth) ?: 0.ipx
             val placeable = measurable?.measure(
                 Constraints.tightConstraintsForHeight(height).enforce(constraints)
             )
-            layoutResult(placeable?.width ?: 0.ipx, placeable?.height ?: 0.ipx) {
+            layout(placeable?.width ?: 0.ipx, placeable?.height ?: 0.ipx) {
                 placeable?.place(0.ipx, 0.ipx)
             }
         }
@@ -134,13 +133,13 @@
 @Composable
 fun MaxIntrinsicWidth(children: @Composable() () -> Unit) {
     ComplexLayout(children) {
-        layout { measurables, constraints ->
+        measure { measurables, constraints ->
             val measurable = measurables.firstOrNull()
             val width = measurable?.maxIntrinsicWidth(constraints.maxHeight) ?: 0.ipx
             val placeable = measurable?.measure(
                 Constraints.tightConstraintsForWidth(width).enforce(constraints)
             )
-            layoutResult(placeable?.width ?: 0.ipx, placeable?.height ?: 0.ipx) {
+            layout(placeable?.width ?: 0.ipx, placeable?.height ?: 0.ipx) {
                 placeable?.place(0.ipx, 0.ipx)
             }
         }
@@ -179,13 +178,13 @@
 @Composable
 fun MaxIntrinsicHeight(children: @Composable() () -> Unit) {
     ComplexLayout(children) {
-        layout { measurables, constraints ->
+        measure { measurables, constraints ->
             val measurable = measurables.firstOrNull()
             val height = measurable?.maxIntrinsicHeight(constraints.maxWidth) ?: 0.ipx
             val placeable = measurable?.measure(
                 Constraints.tightConstraintsForHeight(height).enforce(constraints)
             )
-            layoutResult(placeable?.width ?: 0.ipx, placeable?.height ?: 0.ipx) {
+            layout(placeable?.width ?: 0.ipx, placeable?.height ?: 0.ipx) {
                 placeable?.place(0.ipx, 0.ipx)
             }
         }
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Padding.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Padding.kt
index 79225a6..805608f 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Padding.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Padding.kt
@@ -21,7 +21,6 @@
 import androidx.ui.core.dp
 import androidx.ui.core.min
 import androidx.ui.core.offset
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 
@@ -55,7 +54,7 @@
     padding: EdgeInsets,
     children: @Composable() () -> Unit
 ) {
-    Layout(layoutBlock = { measurables, constraints ->
+    Layout(children) { measurables, constraints ->
         val measurable = measurables.firstOrNull()
         if (measurable == null) {
             layout(constraints.minWidth, constraints.minHeight) { }
@@ -78,7 +77,7 @@
                 placeable.place(paddingLeft, paddingTop)
             }
         }
-    }, children = children)
+    }
 }
 
 /**
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Scroller.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Scroller.kt
index 677be31..7686861 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Scroller.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Scroller.kt
@@ -15,22 +15,20 @@
  */
 package androidx.ui.layout
 
+import androidx.ui.core.coerceIn
 import androidx.ui.core.Constraints
 import androidx.ui.core.Direction
 import androidx.ui.core.IntPx
 import androidx.ui.core.Layout
 import androidx.ui.core.Px
 import androidx.ui.core.PxPosition
-import androidx.ui.core.coerceIn
-import androidx.ui.core.gesture.DragGestureDetector
+import androidx.ui.core.gesture.TouchSlopDragGestureDetector
 import androidx.ui.core.gesture.DragObserver
-import androidx.ui.core.ipx
 import androidx.ui.core.min
 import androidx.ui.core.px
 import androidx.ui.core.round
 import androidx.ui.core.toPx
 import androidx.ui.core.toRect
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.Model
 import androidx.compose.composer
@@ -49,30 +47,33 @@
  * When the offset changes, [offsetChange] is called with the new offset.
  */
 @Composable
-private fun VerticalDragGestureDetector(
+private fun DirectionalDragGestureDetector(
+    vertical: Boolean,
     max: Px = Px.Infinity,
     offsetChange: (Px) -> Unit,
     children: @Composable() () -> Unit
 ) {
     val offset = +state { 0.px }
-    DragGestureDetector(
+    TouchSlopDragGestureDetector(
         dragObserver = object : DragObserver {
             override fun onDrag(dragDistance: PxPosition): PxPosition {
-                val dragPosition = -offset.value + dragDistance.y
+                val draggedAmount = if (vertical) dragDistance.y else dragDistance.x
+                val dragPosition = -offset.value + draggedAmount
                 val targetPosition = dragPosition.coerceIn(-max, 0.px)
                 if (targetPosition != -offset.value) {
                     offset.value = -targetPosition
                     offsetChange(offset.value)
                 }
-                val consumed = dragDistance.y - (targetPosition - dragPosition)
-                return PxPosition(0.px, consumed)
+                val consumed = draggedAmount + (targetPosition - dragPosition)
+                return if (vertical) PxPosition(0.px, consumed) else PxPosition(consumed, 0.px)
             }
         },
         canDrag = { direction ->
             when (direction) {
-                Direction.DOWN -> offset.value > 0.px
-                Direction.UP -> offset.value < max
-                else -> false
+                Direction.DOWN -> if (vertical) offset.value > 0.px else false
+                Direction.UP -> if (vertical) offset.value < max else false
+                Direction.RIGHT -> if (vertical) false else offset.value > 0.px
+                Direction.LEFT -> if (vertical) false else offset.value < max
             }
         }) { children() }
 }
@@ -107,24 +108,67 @@
     },
     child: @Composable() () -> Unit
 ) {
+    Scroller(
+        vertical = true,
+        scrollerPosition = scrollerPosition,
+        onScrollChanged = onScrollChanged,
+        child = child
+    )
+}
+
+/**
+ * A container that composes all of its contents and lays it out, fitting the height of the child.
+ * If the child's width is less than the [Constraints.maxWidth], the child's width is used,
+ * or the [Constraints.maxWidth] otherwise. If the contents don't fit the width, the drag gesture
+ * allows scrolling its content horizontally. The contents of the HorizontalScroller are clipped to
+ * the HorizontalScroller's bounds.
+ */
+// TODO(mount): Add fling support
+@Composable
+fun HorizontalScroller(
+    scrollerPosition: ScrollerPosition = +memo { ScrollerPosition() },
+    onScrollChanged: (position: Px, maxPosition: Px) -> Unit = { position, _ ->
+        scrollerPosition.position = position
+    },
+    child: @Composable() () -> Unit
+) {
+    Scroller(
+        vertical = false,
+        scrollerPosition = scrollerPosition,
+        onScrollChanged = onScrollChanged,
+        child = child
+    )
+}
+
+@Composable
+private fun Scroller(
+    vertical: Boolean,
+    scrollerPosition: ScrollerPosition = +memo { ScrollerPosition() },
+    onScrollChanged: (position: Px, maxPosition: Px) -> Unit = { position, _ ->
+        scrollerPosition.position = position
+    },
+    child: @Composable() () -> Unit
+) {
     val maxPosition = +state { 0.px }
     Layout(children = {
-            Clip(RectangleShape) {
-                VerticalDragGestureDetector(
-                    max = maxPosition.value,
-                    offsetChange = { newOffset -> onScrollChanged(newOffset, maxPosition.value) }) {
-                    Container {
-                        RepaintBoundary {
-                            child()
-                        }
+        Clip(RectangleShape) {
+            DirectionalDragGestureDetector(
+                vertical = vertical,
+                max = maxPosition.value,
+                offsetChange = { newOffset -> onScrollChanged(newOffset, maxPosition.value) }) {
+                Container {
+                    RepaintBoundary {
+                        child()
                     }
                 }
             }
-        }) { measurables, constraints ->
-        if (measurables.size > 1) {
-            throw IllegalStateException("Only one child is allowed in a VerticalScroller")
         }
-        val childConstraints = constraints.copy(maxHeight = IntPx.Infinity)
+    }) { measurables, constraints ->
+        val childConstraints = if (vertical) {
+            constraints.copy(maxHeight = IntPx.Infinity)
+        } else {
+            constraints.copy(maxWidth = IntPx.Infinity)
+        }
         val childMeasurable = measurables.firstOrNull()
         val placeable = childMeasurable?.measure(childConstraints)
         val width: IntPx
@@ -133,17 +177,32 @@
             width = constraints.minWidth
             height = constraints.minHeight
         } else {
-            width = placeable.width
+            width = min(placeable.width, constraints.maxWidth)
             height = min(placeable.height, constraints.maxHeight)
         }
         layout(width, height) {
-            val childHeight = placeable?.height?.toPx() ?: 0.px
-            val newMaxPosition = childHeight - height.toPx()
-            if (maxPosition.value != newMaxPosition) {
-                maxPosition.value = newMaxPosition
-                onScrollChanged(scrollerPosition.position, maxPosition.value)
+            if (placeable != null) {
+                val childSize = if (vertical) {
+                    placeable.height.toPx()
+                } else {
+                    placeable.width.toPx()
+                }
+                val newMaxPosition = childSize - if (vertical) height.toPx() else width.toPx()
+                if (maxPosition.value != newMaxPosition) {
+                    maxPosition.value = newMaxPosition
+                    onScrollChanged(scrollerPosition.position, maxPosition.value)
+                }
+                val x: IntPx
+                val y: IntPx
+                if (vertical) {
+                    x = IntPx.Zero
+                    y = -scrollerPosition.position.round()
+                } else {
+                    x = -scrollerPosition.position.round()
+                    y = IntPx.Zero
+                }
+                placeable.place(x, y)
             }
-            placeable?.place(0.ipx, -scrollerPosition.position.round())
         }
     }
 }
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Stack.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Stack.kt
index 55b5593..ef1b449 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Stack.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Stack.kt
@@ -26,7 +26,6 @@
 import androidx.ui.core.Placeable
 import androidx.ui.core.looseMin
 import androidx.ui.core.max
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.ui.core.coerceAtLeast
@@ -101,7 +100,7 @@
  */
 @Composable
 fun Stack(
-    @Children(composable = false) block: StackChildren.() -> Unit
+    block: StackChildren.() -> Unit
 ) {
     val children: @Composable() () -> Unit = with(StackChildren()) {
         apply(block)
@@ -112,7 +111,7 @@
         }
         composable
     }
-    Layout(children = children, layoutBlock = { measurables, constraints ->
+    Layout(children) { measurables, constraints ->
         val placeables = arrayOfNulls<Placeable>(measurables.size)
         // First measure aligned children to get the size of the layout.
         (0 until measurables.size).filter { i -> !measurables[i].positioned }.forEach { i ->
@@ -205,7 +204,7 @@
                 }
             }
         }
-    })
+    }
 }
 
 /**
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Table.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Table.kt
index 1dd6894..29eb921 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Table.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Table.kt
@@ -17,9 +17,10 @@
 package androidx.ui.layout
 
 import androidx.annotation.FloatRange
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
+import androidx.compose.state
+import androidx.compose.unaryPlus
 import androidx.ui.core.Constraints
 import androidx.ui.core.Dp
 import androidx.ui.core.IntPx
@@ -38,24 +39,36 @@
  * Collects information about the children of a [Table] when
  * its body is executed with a [TableChildren] as argument.
  */
-class TableChildren internal constructor() {
+class TableChildren internal constructor(private val columnCount: Int) {
 
     internal val tableChildren = mutableListOf<@Composable() () -> Unit>()
-    private var rowGroup = 0
+    internal val tableDecorations = mutableListOf<TableDecoration>()
 
-    fun tableRow(children: @Composable() () -> Unit) {
+    fun tableRow(children: @Composable() (columnIndex: Int) -> Unit) {
+        val rowIndex = tableChildren.size
         tableChildren += {
-            ParentData(data = TableChildData(rowGroup++), children = children)
+            ParentData(data = TableChildData(rowIndex)) {
+                for (j in 0 until columnCount) {
+                    children(j)
+                }
+            }
         }
     }
+
+    fun addDecoration(decoration: TableDecoration) {
+        tableDecorations += decoration
+    }
 }
 
+typealias TableDecoration =
+        @Composable() (verticalOffsets: Array<IntPx>, horizontalOffsets: Array<IntPx>) -> Unit
+
 /**
  * Parent data associated with children to assign a row group.
  */
-private data class TableChildData(val rowGroup: Int)
+private data class TableChildData(val rowIndex: Int)
 
-private val Measurable.rowGroup get() = (parentData as TableChildData).rowGroup
+private val Measurable.rowIndex get() = (parentData as TableChildData).rowIndex
 
 /**
  * Used to specify the size of a [Table]'s column.
@@ -108,24 +121,30 @@
  */
 @Composable
 fun Table(
+    columnCount: Int,
     childAlignment: Alignment = Alignment.TopLeft,
     columnWidth: (columnIndex: Int) -> TableColumnWidth = { TableColumnWidth.Flexible(1f) },
-    @Children(composable = false) block: TableChildren.() -> Unit
+    block: TableChildren.() -> Unit
 ) {
-    val children: @Composable() () -> Unit = with(TableChildren()) {
+    val verticalOffsets = +state { emptyArray<IntPx>() }
+    val horizontalOffsets = +state { emptyArray<IntPx>() }
+
+    val children: @Composable() () -> Unit = with(TableChildren(columnCount)) {
         apply(block)
         val composable = @Composable {
             tableChildren.forEach { it() }
+            tableDecorations.forEach { decoration ->
+                decoration(verticalOffsets.value, horizontalOffsets.value)
+            }
         }
         composable
     }
 
     Layout(children) { m, constraints ->
-        // Group the measurables into rows using rowGroup.
-        val measurables = m.groupBy { it.rowGroup }.values.toTypedArray()
+        // Group the measurables into rows using row index.
+        val measurables = m.groupBy { it.rowIndex }.values.toTypedArray()
 
         val rowCount = measurables.size
-        val columnCount = measurables.map { it.size }.max() ?: 0
 
         var totalFlex = 0f
         var availableSpace = if (constraints.maxWidth.isFinite()) {
@@ -211,9 +230,25 @@
             }
         }
 
+        // Compute row/column offsets.
+        val rowOffsets = Array(rowCount + 1) { IntPx.Zero }
+        val columnOffsets = Array(columnCount + 1) { IntPx.Zero }
+        for (row in 0 until rowCount) {
+            rowOffsets[row + 1] = rowOffsets[row] + rowHeights[row]
+        }
+        for (column in 0 until columnCount) {
+            columnOffsets[column + 1] = columnOffsets[column] + columnWidths[column]
+        }
+
+        // Force recomposition of decorations.
+        verticalOffsets.value = rowOffsets
+        horizontalOffsets.value = columnOffsets
+
         // TODO(calintat): Figure out what to do when these exceed max constraints.
-        val tableWidth = columnWidths.sum().coerceIn(constraints.minWidth, constraints.maxWidth)
-        val tableHeight = rowHeights.sum().coerceIn(constraints.minHeight, constraints.maxHeight)
+        val tableWidth =
+            columnOffsets[columnCount].coerceIn(constraints.minWidth, constraints.maxWidth)
+        val tableHeight =
+            rowOffsets[rowCount].coerceIn(constraints.minHeight, constraints.maxHeight)
 
         layout(tableWidth, tableHeight) {
             for (row in 0 until rowCount) {
@@ -226,14 +261,11 @@
                         )
                     )
                     placeable.place(
-                        x = columnWidths.take(column).sum() + position.x,
-                        y = rowHeights.take(row).sum() + position.y
+                        x = columnOffsets[column] + position.x,
+                        y = rowOffsets[row] + position.y
                     )
                 }
             }
         }
     }
 }
-
-internal fun Array<IntPx>.sum() = this.fold(IntPx.Zero) { a, b -> a + b }
-internal fun Collection<IntPx>.sum() = this.fold(IntPx.Zero) { a, b -> a + b }
\ No newline at end of file
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Wrap.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Wrap.kt
index 3846114..51580b3 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Wrap.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Wrap.kt
@@ -21,7 +21,6 @@
 import androidx.ui.core.ipx
 import androidx.ui.core.looseMin
 import androidx.ui.core.max
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 
@@ -36,7 +35,7 @@
  */
 @Composable
 fun Wrap(alignment: Alignment = Alignment.TopLeft, children: @Composable() () -> Unit) {
-    Layout(layoutBlock = { measurables, constraints ->
+    Layout(children) { measurables, constraints ->
         val measurable = measurables.firstOrNull()
         // The child cannot be larger than our max constraints, but we ignore min constraints.
         val placeable = measurable?.measure(constraints.looseMin())
@@ -53,5 +52,5 @@
                 placeable.place(position.x, position.y)
             }
         }
-    }, children=children)
+    }
 }
diff --git a/ui/ui-material/api/1.0.0-alpha01.txt b/ui/ui-material/api/1.0.0-alpha01.txt
index df0d16a..f062c9e 100644
--- a/ui/ui-material/api/1.0.0-alpha01.txt
+++ b/ui/ui-material/api/1.0.0-alpha01.txt
@@ -1,6 +1,16 @@
 // Signature format: 3.0
 package androidx.ui.material {
 
+  public enum AlertDialogButtonLayout {
+    enum_constant public static final androidx.ui.material.AlertDialogButtonLayout SideBySide;
+    enum_constant public static final androidx.ui.material.AlertDialogButtonLayout Stacked;
+  }
+
+  public final class AlertDialogKt {
+    ctor public AlertDialogKt();
+    method public static void AlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onCloseRequest, kotlin.jvm.functions.Function0<kotlin.Unit>? title = (kotlin.jvm.functions.Function0<? extends kotlin.Unit>)null, kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> confirmButton, kotlin.jvm.functions.Function0<kotlin.Unit>? dismissButton = (kotlin.jvm.functions.Function0<? extends kotlin.Unit>)null, androidx.ui.material.AlertDialogButtonLayout buttonLayout = AlertDialogButtonLayout.SideBySide);
+  }
+
   public final class AppBarKt {
     ctor public AppBarKt();
     method public static void AppBarIcon(androidx.ui.painting.Image icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
@@ -24,19 +34,45 @@
 
   public final class ButtonKt {
     ctor public ButtonKt();
-    method public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = +themeShape({ 
-    button
-}), androidx.ui.graphics.Color color = +themeColor({ 
+    method public static void BaseButton(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public static void Button(String text, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = +themeShape({ 
+}), androidx.ui.engine.geometry.Shape shape = RectangleShape, androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp, androidx.ui.text.TextStyle textStyle = +themeTextStyle({ 
     button
-}), androidx.ui.graphics.Color color = +themeColor({ 
+}), kotlin.jvm.functions.Function0<kotlin.Unit> children);
+    method public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.material.ButtonStyle style = ContainedButtonStyle(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
+    method public static void Button(String text, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.material.ButtonStyle style = ContainedButtonStyle());
+    method public static androidx.ui.material.ButtonStyle ContainedButtonStyle(androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp);
-    method public static void TransparentButton(String text, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = +themeShape({ 
+}), androidx.ui.engine.geometry.Shape shape = +themeShape({ 
     button
-}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp);
+}), androidx.ui.core.Dp elevation = 2.dp);
+    method public static androidx.ui.material.ButtonStyle OutlinedButtonStyle(androidx.ui.foundation.shape.border.Border border = Border(+themeColor({ 
+    onSurface.copy(OutlinedStrokeOpacity)
+}), 1.dp), androidx.ui.graphics.Color color = +themeColor({ 
+    surface
+}), androidx.ui.engine.geometry.Shape shape = +themeShape({ 
+    button
+}), androidx.ui.core.Dp elevation = 0.dp);
+    method public static androidx.ui.material.ButtonStyle TextButtonStyle(androidx.ui.engine.geometry.Shape shape = +themeShape({ 
+    button
+}));
+  }
+
+  public final class ButtonStyle {
+    ctor public ButtonStyle(androidx.ui.graphics.Color color, androidx.ui.engine.geometry.Shape shape, androidx.ui.foundation.shape.border.Border? border, androidx.ui.core.Dp elevation, androidx.ui.layout.EdgeInsets paddings, androidx.ui.text.TextStyle? textStyle);
+    method public androidx.ui.graphics.Color component1();
+    method public androidx.ui.engine.geometry.Shape component2();
+    method public androidx.ui.foundation.shape.border.Border? component3();
+    method public androidx.ui.core.Dp component4();
+    method public androidx.ui.layout.EdgeInsets component5();
+    method public androidx.ui.text.TextStyle? component6();
+    method public androidx.ui.material.ButtonStyle copy(androidx.ui.graphics.Color color, androidx.ui.engine.geometry.Shape shape, androidx.ui.foundation.shape.border.Border? border, androidx.ui.core.Dp elevation, androidx.ui.layout.EdgeInsets paddings, androidx.ui.text.TextStyle? textStyle);
+    method public androidx.ui.foundation.shape.border.Border? getBorder();
+    method public androidx.ui.graphics.Color getColor();
+    method public androidx.ui.core.Dp getElevation();
+    method public androidx.ui.layout.EdgeInsets getPaddings();
+    method public androidx.ui.engine.geometry.Shape getShape();
+    method public androidx.ui.text.TextStyle? getTextStyle();
   }
 
   public final class CheckboxKt {
@@ -72,13 +108,13 @@
     ctor public FloatingActionButtonKt();
     method public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.core.Dp minSize = FabSize, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.core.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+}), androidx.ui.core.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static void FloatingActionButton(androidx.ui.painting.Image icon, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.core.Dp elevation = 0.dp);
+}), androidx.ui.core.Dp elevation = 6.dp);
     method public static void FloatingActionButton(String text, androidx.ui.painting.Image? icon = null, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.core.Dp elevation = 0.dp);
+}), androidx.ui.core.Dp elevation = 6.dp);
     method public static androidx.ui.core.Dp getExtendedFabHeight();
     method public static androidx.ui.core.Dp getExtendedFabIconPadding();
     method public static androidx.ui.core.Dp getExtendedFabTextPadding();
@@ -118,7 +154,6 @@
   public final class MaterialThemeKt {
     ctor public MaterialThemeKt();
     method public static void MaterialButtonShapeTheme(kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public static void MaterialRippleTheme(kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static void MaterialTheme(androidx.ui.material.MaterialColors colors = androidx.ui.material.MaterialColors(), androidx.ui.material.MaterialTypography typography = androidx.ui.material.MaterialTypography(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static androidx.compose.Ambient<androidx.ui.material.MaterialColors> getColors();
     method public static androidx.compose.Ambient<androidx.ui.material.Shapes> getCurrentShapeAmbient();
@@ -313,11 +348,28 @@
 package androidx.ui.material.shape {
 
   public final class CutCornerShape extends androidx.ui.foundation.shape.corner.CornerBasedShape {
-    ctor public CutCornerShape(androidx.ui.foundation.shape.corner.CornerSizes corners);
-    method public androidx.ui.foundation.shape.corner.CornerSizes component1();
-    method public androidx.ui.material.shape.CutCornerShape copy(androidx.ui.foundation.shape.corner.CornerSizes corners);
-    method public androidx.ui.engine.geometry.Outline.Generic createOutline(androidx.ui.foundation.shape.corner.PxCornerSizes corners, androidx.ui.core.PxSize size);
-    method public androidx.ui.foundation.shape.corner.CornerSizes getCorners();
+    ctor public CutCornerShape(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+    method public androidx.ui.foundation.shape.corner.CornerSize component1();
+    method public androidx.ui.foundation.shape.corner.CornerSize component2();
+    method public androidx.ui.foundation.shape.corner.CornerSize component3();
+    method public androidx.ui.foundation.shape.corner.CornerSize component4();
+    method public androidx.ui.material.shape.CutCornerShape copy(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+    method public androidx.ui.engine.geometry.Outline.Generic createOutline(androidx.ui.core.PxSize size, androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
+    method public androidx.ui.foundation.shape.corner.CornerSize getBottomLeft();
+    method public androidx.ui.foundation.shape.corner.CornerSize getBottomRight();
+    method public androidx.ui.foundation.shape.corner.CornerSize getTopLeft();
+    method public androidx.ui.foundation.shape.corner.CornerSize getTopRight();
+  }
+
+  public final class CutCornerShapeKt {
+    ctor public CutCornerShapeKt();
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.foundation.shape.corner.CornerSize corner);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.core.Dp size);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.core.Px size);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(int percent);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.core.Dp topLeft = 0.dp, androidx.ui.core.Dp topRight = 0.dp, androidx.ui.core.Dp bottomRight = 0.dp, androidx.ui.core.Dp bottomLeft = 0.dp);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.core.Px topLeft = 0.px, androidx.ui.core.Px topRight = 0.px, androidx.ui.core.Px bottomRight = 0.px, androidx.ui.core.Px bottomLeft = 0.px);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(@IntRange(from=0, to=50) int topLeftPercent = 0, @IntRange(from=0, to=50) int topRightPercent = 0, @IntRange(from=0, to=50) int bottomRightPercent = 0, @IntRange(from=0, to=50) int bottomLeftPercent = 0);
   }
 
 }
@@ -328,12 +380,7 @@
     ctor public CardKt();
     method public static void Card(androidx.ui.engine.geometry.Shape shape = RectangleShape, androidx.ui.graphics.Color color = +themeColor({ 
     surface
-}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
-  public final class DrawShadowKt {
-    ctor public DrawShadowKt();
-    method public static void DrawShadow(androidx.ui.core.Dp elevation, androidx.ui.engine.geometry.Shape shape);
+}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 1.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
   public final class SurfaceKt {
diff --git a/ui/ui-material/api/api_lint.ignore b/ui/ui-material/api/api_lint.ignore
new file mode 100644
index 0000000..1986cc2
--- /dev/null
+++ b/ui/ui-material/api/api_lint.ignore
@@ -0,0 +1,7 @@
+// Baseline format: 1.0
+MissingNullability: androidx.ui.material.BottomAppBar#INSTANCE:
+    Missing nullability on field `INSTANCE` in class `class androidx.ui.material.BottomAppBar`
+MissingNullability: androidx.ui.material.TabRow#INSTANCE:
+    Missing nullability on field `INSTANCE` in class `class androidx.ui.material.TabRow`
+MissingNullability: androidx.ui.material.ripple.DefaultRippleEffectFactory#INSTANCE:
+    Missing nullability on field `INSTANCE` in class `class androidx.ui.material.ripple.DefaultRippleEffectFactory`
diff --git a/ui/ui-material/api/current.txt b/ui/ui-material/api/current.txt
index df0d16a..f062c9e 100644
--- a/ui/ui-material/api/current.txt
+++ b/ui/ui-material/api/current.txt
@@ -1,6 +1,16 @@
 // Signature format: 3.0
 package androidx.ui.material {
 
+  public enum AlertDialogButtonLayout {
+    enum_constant public static final androidx.ui.material.AlertDialogButtonLayout SideBySide;
+    enum_constant public static final androidx.ui.material.AlertDialogButtonLayout Stacked;
+  }
+
+  public final class AlertDialogKt {
+    ctor public AlertDialogKt();
+    method public static void AlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onCloseRequest, kotlin.jvm.functions.Function0<kotlin.Unit>? title = (kotlin.jvm.functions.Function0<? extends kotlin.Unit>)null, kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> confirmButton, kotlin.jvm.functions.Function0<kotlin.Unit>? dismissButton = (kotlin.jvm.functions.Function0<? extends kotlin.Unit>)null, androidx.ui.material.AlertDialogButtonLayout buttonLayout = AlertDialogButtonLayout.SideBySide);
+  }
+
   public final class AppBarKt {
     ctor public AppBarKt();
     method public static void AppBarIcon(androidx.ui.painting.Image icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
@@ -24,19 +34,45 @@
 
   public final class ButtonKt {
     ctor public ButtonKt();
-    method public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = +themeShape({ 
-    button
-}), androidx.ui.graphics.Color color = +themeColor({ 
+    method public static void BaseButton(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public static void Button(String text, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = +themeShape({ 
+}), androidx.ui.engine.geometry.Shape shape = RectangleShape, androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp, androidx.ui.text.TextStyle textStyle = +themeTextStyle({ 
     button
-}), androidx.ui.graphics.Color color = +themeColor({ 
+}), kotlin.jvm.functions.Function0<kotlin.Unit> children);
+    method public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.material.ButtonStyle style = ContainedButtonStyle(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
+    method public static void Button(String text, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.material.ButtonStyle style = ContainedButtonStyle());
+    method public static androidx.ui.material.ButtonStyle ContainedButtonStyle(androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp);
-    method public static void TransparentButton(String text, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = +themeShape({ 
+}), androidx.ui.engine.geometry.Shape shape = +themeShape({ 
     button
-}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp);
+}), androidx.ui.core.Dp elevation = 2.dp);
+    method public static androidx.ui.material.ButtonStyle OutlinedButtonStyle(androidx.ui.foundation.shape.border.Border border = Border(+themeColor({ 
+    onSurface.copy(OutlinedStrokeOpacity)
+}), 1.dp), androidx.ui.graphics.Color color = +themeColor({ 
+    surface
+}), androidx.ui.engine.geometry.Shape shape = +themeShape({ 
+    button
+}), androidx.ui.core.Dp elevation = 0.dp);
+    method public static androidx.ui.material.ButtonStyle TextButtonStyle(androidx.ui.engine.geometry.Shape shape = +themeShape({ 
+    button
+}));
+  }
+
+  public final class ButtonStyle {
+    ctor public ButtonStyle(androidx.ui.graphics.Color color, androidx.ui.engine.geometry.Shape shape, androidx.ui.foundation.shape.border.Border? border, androidx.ui.core.Dp elevation, androidx.ui.layout.EdgeInsets paddings, androidx.ui.text.TextStyle? textStyle);
+    method public androidx.ui.graphics.Color component1();
+    method public androidx.ui.engine.geometry.Shape component2();
+    method public androidx.ui.foundation.shape.border.Border? component3();
+    method public androidx.ui.core.Dp component4();
+    method public androidx.ui.layout.EdgeInsets component5();
+    method public androidx.ui.text.TextStyle? component6();
+    method public androidx.ui.material.ButtonStyle copy(androidx.ui.graphics.Color color, androidx.ui.engine.geometry.Shape shape, androidx.ui.foundation.shape.border.Border? border, androidx.ui.core.Dp elevation, androidx.ui.layout.EdgeInsets paddings, androidx.ui.text.TextStyle? textStyle);
+    method public androidx.ui.foundation.shape.border.Border? getBorder();
+    method public androidx.ui.graphics.Color getColor();
+    method public androidx.ui.core.Dp getElevation();
+    method public androidx.ui.layout.EdgeInsets getPaddings();
+    method public androidx.ui.engine.geometry.Shape getShape();
+    method public androidx.ui.text.TextStyle? getTextStyle();
   }
 
   public final class CheckboxKt {
@@ -72,13 +108,13 @@
     ctor public FloatingActionButtonKt();
     method public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.core.Dp minSize = FabSize, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.core.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+}), androidx.ui.core.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static void FloatingActionButton(androidx.ui.painting.Image icon, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.core.Dp elevation = 0.dp);
+}), androidx.ui.core.Dp elevation = 6.dp);
     method public static void FloatingActionButton(String text, androidx.ui.painting.Image? icon = null, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.core.Dp elevation = 0.dp);
+}), androidx.ui.core.Dp elevation = 6.dp);
     method public static androidx.ui.core.Dp getExtendedFabHeight();
     method public static androidx.ui.core.Dp getExtendedFabIconPadding();
     method public static androidx.ui.core.Dp getExtendedFabTextPadding();
@@ -118,7 +154,6 @@
   public final class MaterialThemeKt {
     ctor public MaterialThemeKt();
     method public static void MaterialButtonShapeTheme(kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public static void MaterialRippleTheme(kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static void MaterialTheme(androidx.ui.material.MaterialColors colors = androidx.ui.material.MaterialColors(), androidx.ui.material.MaterialTypography typography = androidx.ui.material.MaterialTypography(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static androidx.compose.Ambient<androidx.ui.material.MaterialColors> getColors();
     method public static androidx.compose.Ambient<androidx.ui.material.Shapes> getCurrentShapeAmbient();
@@ -313,11 +348,28 @@
 package androidx.ui.material.shape {
 
   public final class CutCornerShape extends androidx.ui.foundation.shape.corner.CornerBasedShape {
-    ctor public CutCornerShape(androidx.ui.foundation.shape.corner.CornerSizes corners);
-    method public androidx.ui.foundation.shape.corner.CornerSizes component1();
-    method public androidx.ui.material.shape.CutCornerShape copy(androidx.ui.foundation.shape.corner.CornerSizes corners);
-    method public androidx.ui.engine.geometry.Outline.Generic createOutline(androidx.ui.foundation.shape.corner.PxCornerSizes corners, androidx.ui.core.PxSize size);
-    method public androidx.ui.foundation.shape.corner.CornerSizes getCorners();
+    ctor public CutCornerShape(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+    method public androidx.ui.foundation.shape.corner.CornerSize component1();
+    method public androidx.ui.foundation.shape.corner.CornerSize component2();
+    method public androidx.ui.foundation.shape.corner.CornerSize component3();
+    method public androidx.ui.foundation.shape.corner.CornerSize component4();
+    method public androidx.ui.material.shape.CutCornerShape copy(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+    method public androidx.ui.engine.geometry.Outline.Generic createOutline(androidx.ui.core.PxSize size, androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
+    method public androidx.ui.foundation.shape.corner.CornerSize getBottomLeft();
+    method public androidx.ui.foundation.shape.corner.CornerSize getBottomRight();
+    method public androidx.ui.foundation.shape.corner.CornerSize getTopLeft();
+    method public androidx.ui.foundation.shape.corner.CornerSize getTopRight();
+  }
+
+  public final class CutCornerShapeKt {
+    ctor public CutCornerShapeKt();
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.foundation.shape.corner.CornerSize corner);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.core.Dp size);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.core.Px size);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(int percent);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.core.Dp topLeft = 0.dp, androidx.ui.core.Dp topRight = 0.dp, androidx.ui.core.Dp bottomRight = 0.dp, androidx.ui.core.Dp bottomLeft = 0.dp);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.core.Px topLeft = 0.px, androidx.ui.core.Px topRight = 0.px, androidx.ui.core.Px bottomRight = 0.px, androidx.ui.core.Px bottomLeft = 0.px);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(@IntRange(from=0, to=50) int topLeftPercent = 0, @IntRange(from=0, to=50) int topRightPercent = 0, @IntRange(from=0, to=50) int bottomRightPercent = 0, @IntRange(from=0, to=50) int bottomLeftPercent = 0);
   }
 
 }
@@ -328,12 +380,7 @@
     ctor public CardKt();
     method public static void Card(androidx.ui.engine.geometry.Shape shape = RectangleShape, androidx.ui.graphics.Color color = +themeColor({ 
     surface
-}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
-  public final class DrawShadowKt {
-    ctor public DrawShadowKt();
-    method public static void DrawShadow(androidx.ui.core.Dp elevation, androidx.ui.engine.geometry.Shape shape);
+}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 1.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
   public final class SurfaceKt {
diff --git a/ui/ui-material/api/restricted_1.0.0-alpha01.txt b/ui/ui-material/api/restricted_1.0.0-alpha01.txt
index df0d16a..f062c9e 100644
--- a/ui/ui-material/api/restricted_1.0.0-alpha01.txt
+++ b/ui/ui-material/api/restricted_1.0.0-alpha01.txt
@@ -1,6 +1,16 @@
 // Signature format: 3.0
 package androidx.ui.material {
 
+  public enum AlertDialogButtonLayout {
+    enum_constant public static final androidx.ui.material.AlertDialogButtonLayout SideBySide;
+    enum_constant public static final androidx.ui.material.AlertDialogButtonLayout Stacked;
+  }
+
+  public final class AlertDialogKt {
+    ctor public AlertDialogKt();
+    method public static void AlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onCloseRequest, kotlin.jvm.functions.Function0<kotlin.Unit>? title = (kotlin.jvm.functions.Function0<? extends kotlin.Unit>)null, kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> confirmButton, kotlin.jvm.functions.Function0<kotlin.Unit>? dismissButton = (kotlin.jvm.functions.Function0<? extends kotlin.Unit>)null, androidx.ui.material.AlertDialogButtonLayout buttonLayout = AlertDialogButtonLayout.SideBySide);
+  }
+
   public final class AppBarKt {
     ctor public AppBarKt();
     method public static void AppBarIcon(androidx.ui.painting.Image icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
@@ -24,19 +34,45 @@
 
   public final class ButtonKt {
     ctor public ButtonKt();
-    method public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = +themeShape({ 
-    button
-}), androidx.ui.graphics.Color color = +themeColor({ 
+    method public static void BaseButton(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public static void Button(String text, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = +themeShape({ 
+}), androidx.ui.engine.geometry.Shape shape = RectangleShape, androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp, androidx.ui.text.TextStyle textStyle = +themeTextStyle({ 
     button
-}), androidx.ui.graphics.Color color = +themeColor({ 
+}), kotlin.jvm.functions.Function0<kotlin.Unit> children);
+    method public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.material.ButtonStyle style = ContainedButtonStyle(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
+    method public static void Button(String text, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.material.ButtonStyle style = ContainedButtonStyle());
+    method public static androidx.ui.material.ButtonStyle ContainedButtonStyle(androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp);
-    method public static void TransparentButton(String text, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = +themeShape({ 
+}), androidx.ui.engine.geometry.Shape shape = +themeShape({ 
     button
-}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp);
+}), androidx.ui.core.Dp elevation = 2.dp);
+    method public static androidx.ui.material.ButtonStyle OutlinedButtonStyle(androidx.ui.foundation.shape.border.Border border = Border(+themeColor({ 
+    onSurface.copy(OutlinedStrokeOpacity)
+}), 1.dp), androidx.ui.graphics.Color color = +themeColor({ 
+    surface
+}), androidx.ui.engine.geometry.Shape shape = +themeShape({ 
+    button
+}), androidx.ui.core.Dp elevation = 0.dp);
+    method public static androidx.ui.material.ButtonStyle TextButtonStyle(androidx.ui.engine.geometry.Shape shape = +themeShape({ 
+    button
+}));
+  }
+
+  public final class ButtonStyle {
+    ctor public ButtonStyle(androidx.ui.graphics.Color color, androidx.ui.engine.geometry.Shape shape, androidx.ui.foundation.shape.border.Border? border, androidx.ui.core.Dp elevation, androidx.ui.layout.EdgeInsets paddings, androidx.ui.text.TextStyle? textStyle);
+    method public androidx.ui.graphics.Color component1();
+    method public androidx.ui.engine.geometry.Shape component2();
+    method public androidx.ui.foundation.shape.border.Border? component3();
+    method public androidx.ui.core.Dp component4();
+    method public androidx.ui.layout.EdgeInsets component5();
+    method public androidx.ui.text.TextStyle? component6();
+    method public androidx.ui.material.ButtonStyle copy(androidx.ui.graphics.Color color, androidx.ui.engine.geometry.Shape shape, androidx.ui.foundation.shape.border.Border? border, androidx.ui.core.Dp elevation, androidx.ui.layout.EdgeInsets paddings, androidx.ui.text.TextStyle? textStyle);
+    method public androidx.ui.foundation.shape.border.Border? getBorder();
+    method public androidx.ui.graphics.Color getColor();
+    method public androidx.ui.core.Dp getElevation();
+    method public androidx.ui.layout.EdgeInsets getPaddings();
+    method public androidx.ui.engine.geometry.Shape getShape();
+    method public androidx.ui.text.TextStyle? getTextStyle();
   }
 
   public final class CheckboxKt {
@@ -72,13 +108,13 @@
     ctor public FloatingActionButtonKt();
     method public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.core.Dp minSize = FabSize, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.core.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+}), androidx.ui.core.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static void FloatingActionButton(androidx.ui.painting.Image icon, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.core.Dp elevation = 0.dp);
+}), androidx.ui.core.Dp elevation = 6.dp);
     method public static void FloatingActionButton(String text, androidx.ui.painting.Image? icon = null, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.core.Dp elevation = 0.dp);
+}), androidx.ui.core.Dp elevation = 6.dp);
     method public static androidx.ui.core.Dp getExtendedFabHeight();
     method public static androidx.ui.core.Dp getExtendedFabIconPadding();
     method public static androidx.ui.core.Dp getExtendedFabTextPadding();
@@ -118,7 +154,6 @@
   public final class MaterialThemeKt {
     ctor public MaterialThemeKt();
     method public static void MaterialButtonShapeTheme(kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public static void MaterialRippleTheme(kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static void MaterialTheme(androidx.ui.material.MaterialColors colors = androidx.ui.material.MaterialColors(), androidx.ui.material.MaterialTypography typography = androidx.ui.material.MaterialTypography(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static androidx.compose.Ambient<androidx.ui.material.MaterialColors> getColors();
     method public static androidx.compose.Ambient<androidx.ui.material.Shapes> getCurrentShapeAmbient();
@@ -313,11 +348,28 @@
 package androidx.ui.material.shape {
 
   public final class CutCornerShape extends androidx.ui.foundation.shape.corner.CornerBasedShape {
-    ctor public CutCornerShape(androidx.ui.foundation.shape.corner.CornerSizes corners);
-    method public androidx.ui.foundation.shape.corner.CornerSizes component1();
-    method public androidx.ui.material.shape.CutCornerShape copy(androidx.ui.foundation.shape.corner.CornerSizes corners);
-    method public androidx.ui.engine.geometry.Outline.Generic createOutline(androidx.ui.foundation.shape.corner.PxCornerSizes corners, androidx.ui.core.PxSize size);
-    method public androidx.ui.foundation.shape.corner.CornerSizes getCorners();
+    ctor public CutCornerShape(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+    method public androidx.ui.foundation.shape.corner.CornerSize component1();
+    method public androidx.ui.foundation.shape.corner.CornerSize component2();
+    method public androidx.ui.foundation.shape.corner.CornerSize component3();
+    method public androidx.ui.foundation.shape.corner.CornerSize component4();
+    method public androidx.ui.material.shape.CutCornerShape copy(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+    method public androidx.ui.engine.geometry.Outline.Generic createOutline(androidx.ui.core.PxSize size, androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
+    method public androidx.ui.foundation.shape.corner.CornerSize getBottomLeft();
+    method public androidx.ui.foundation.shape.corner.CornerSize getBottomRight();
+    method public androidx.ui.foundation.shape.corner.CornerSize getTopLeft();
+    method public androidx.ui.foundation.shape.corner.CornerSize getTopRight();
+  }
+
+  public final class CutCornerShapeKt {
+    ctor public CutCornerShapeKt();
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.foundation.shape.corner.CornerSize corner);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.core.Dp size);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.core.Px size);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(int percent);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.core.Dp topLeft = 0.dp, androidx.ui.core.Dp topRight = 0.dp, androidx.ui.core.Dp bottomRight = 0.dp, androidx.ui.core.Dp bottomLeft = 0.dp);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.core.Px topLeft = 0.px, androidx.ui.core.Px topRight = 0.px, androidx.ui.core.Px bottomRight = 0.px, androidx.ui.core.Px bottomLeft = 0.px);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(@IntRange(from=0, to=50) int topLeftPercent = 0, @IntRange(from=0, to=50) int topRightPercent = 0, @IntRange(from=0, to=50) int bottomRightPercent = 0, @IntRange(from=0, to=50) int bottomLeftPercent = 0);
   }
 
 }
@@ -328,12 +380,7 @@
     ctor public CardKt();
     method public static void Card(androidx.ui.engine.geometry.Shape shape = RectangleShape, androidx.ui.graphics.Color color = +themeColor({ 
     surface
-}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
-  public final class DrawShadowKt {
-    ctor public DrawShadowKt();
-    method public static void DrawShadow(androidx.ui.core.Dp elevation, androidx.ui.engine.geometry.Shape shape);
+}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 1.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
   public final class SurfaceKt {
diff --git a/ui/ui-material/api/restricted_current.txt b/ui/ui-material/api/restricted_current.txt
index df0d16a..f062c9e 100644
--- a/ui/ui-material/api/restricted_current.txt
+++ b/ui/ui-material/api/restricted_current.txt
@@ -1,6 +1,16 @@
 // Signature format: 3.0
 package androidx.ui.material {
 
+  public enum AlertDialogButtonLayout {
+    enum_constant public static final androidx.ui.material.AlertDialogButtonLayout SideBySide;
+    enum_constant public static final androidx.ui.material.AlertDialogButtonLayout Stacked;
+  }
+
+  public final class AlertDialogKt {
+    ctor public AlertDialogKt();
+    method public static void AlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onCloseRequest, kotlin.jvm.functions.Function0<kotlin.Unit>? title = (kotlin.jvm.functions.Function0<? extends kotlin.Unit>)null, kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> confirmButton, kotlin.jvm.functions.Function0<kotlin.Unit>? dismissButton = (kotlin.jvm.functions.Function0<? extends kotlin.Unit>)null, androidx.ui.material.AlertDialogButtonLayout buttonLayout = AlertDialogButtonLayout.SideBySide);
+  }
+
   public final class AppBarKt {
     ctor public AppBarKt();
     method public static void AppBarIcon(androidx.ui.painting.Image icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
@@ -24,19 +34,45 @@
 
   public final class ButtonKt {
     ctor public ButtonKt();
-    method public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = +themeShape({ 
-    button
-}), androidx.ui.graphics.Color color = +themeColor({ 
+    method public static void BaseButton(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public static void Button(String text, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = +themeShape({ 
+}), androidx.ui.engine.geometry.Shape shape = RectangleShape, androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp, androidx.ui.text.TextStyle textStyle = +themeTextStyle({ 
     button
-}), androidx.ui.graphics.Color color = +themeColor({ 
+}), kotlin.jvm.functions.Function0<kotlin.Unit> children);
+    method public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.material.ButtonStyle style = ContainedButtonStyle(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
+    method public static void Button(String text, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.material.ButtonStyle style = ContainedButtonStyle());
+    method public static androidx.ui.material.ButtonStyle ContainedButtonStyle(androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp);
-    method public static void TransparentButton(String text, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = +themeShape({ 
+}), androidx.ui.engine.geometry.Shape shape = +themeShape({ 
     button
-}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp);
+}), androidx.ui.core.Dp elevation = 2.dp);
+    method public static androidx.ui.material.ButtonStyle OutlinedButtonStyle(androidx.ui.foundation.shape.border.Border border = Border(+themeColor({ 
+    onSurface.copy(OutlinedStrokeOpacity)
+}), 1.dp), androidx.ui.graphics.Color color = +themeColor({ 
+    surface
+}), androidx.ui.engine.geometry.Shape shape = +themeShape({ 
+    button
+}), androidx.ui.core.Dp elevation = 0.dp);
+    method public static androidx.ui.material.ButtonStyle TextButtonStyle(androidx.ui.engine.geometry.Shape shape = +themeShape({ 
+    button
+}));
+  }
+
+  public final class ButtonStyle {
+    ctor public ButtonStyle(androidx.ui.graphics.Color color, androidx.ui.engine.geometry.Shape shape, androidx.ui.foundation.shape.border.Border? border, androidx.ui.core.Dp elevation, androidx.ui.layout.EdgeInsets paddings, androidx.ui.text.TextStyle? textStyle);
+    method public androidx.ui.graphics.Color component1();
+    method public androidx.ui.engine.geometry.Shape component2();
+    method public androidx.ui.foundation.shape.border.Border? component3();
+    method public androidx.ui.core.Dp component4();
+    method public androidx.ui.layout.EdgeInsets component5();
+    method public androidx.ui.text.TextStyle? component6();
+    method public androidx.ui.material.ButtonStyle copy(androidx.ui.graphics.Color color, androidx.ui.engine.geometry.Shape shape, androidx.ui.foundation.shape.border.Border? border, androidx.ui.core.Dp elevation, androidx.ui.layout.EdgeInsets paddings, androidx.ui.text.TextStyle? textStyle);
+    method public androidx.ui.foundation.shape.border.Border? getBorder();
+    method public androidx.ui.graphics.Color getColor();
+    method public androidx.ui.core.Dp getElevation();
+    method public androidx.ui.layout.EdgeInsets getPaddings();
+    method public androidx.ui.engine.geometry.Shape getShape();
+    method public androidx.ui.text.TextStyle? getTextStyle();
   }
 
   public final class CheckboxKt {
@@ -72,13 +108,13 @@
     ctor public FloatingActionButtonKt();
     method public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.core.Dp minSize = FabSize, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.core.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+}), androidx.ui.core.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static void FloatingActionButton(androidx.ui.painting.Image icon, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.core.Dp elevation = 0.dp);
+}), androidx.ui.core.Dp elevation = 6.dp);
     method public static void FloatingActionButton(String text, androidx.ui.painting.Image? icon = null, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = +themeColor({ 
     primary
-}), androidx.ui.core.Dp elevation = 0.dp);
+}), androidx.ui.core.Dp elevation = 6.dp);
     method public static androidx.ui.core.Dp getExtendedFabHeight();
     method public static androidx.ui.core.Dp getExtendedFabIconPadding();
     method public static androidx.ui.core.Dp getExtendedFabTextPadding();
@@ -118,7 +154,6 @@
   public final class MaterialThemeKt {
     ctor public MaterialThemeKt();
     method public static void MaterialButtonShapeTheme(kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public static void MaterialRippleTheme(kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static void MaterialTheme(androidx.ui.material.MaterialColors colors = androidx.ui.material.MaterialColors(), androidx.ui.material.MaterialTypography typography = androidx.ui.material.MaterialTypography(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
     method public static androidx.compose.Ambient<androidx.ui.material.MaterialColors> getColors();
     method public static androidx.compose.Ambient<androidx.ui.material.Shapes> getCurrentShapeAmbient();
@@ -313,11 +348,28 @@
 package androidx.ui.material.shape {
 
   public final class CutCornerShape extends androidx.ui.foundation.shape.corner.CornerBasedShape {
-    ctor public CutCornerShape(androidx.ui.foundation.shape.corner.CornerSizes corners);
-    method public androidx.ui.foundation.shape.corner.CornerSizes component1();
-    method public androidx.ui.material.shape.CutCornerShape copy(androidx.ui.foundation.shape.corner.CornerSizes corners);
-    method public androidx.ui.engine.geometry.Outline.Generic createOutline(androidx.ui.foundation.shape.corner.PxCornerSizes corners, androidx.ui.core.PxSize size);
-    method public androidx.ui.foundation.shape.corner.CornerSizes getCorners();
+    ctor public CutCornerShape(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+    method public androidx.ui.foundation.shape.corner.CornerSize component1();
+    method public androidx.ui.foundation.shape.corner.CornerSize component2();
+    method public androidx.ui.foundation.shape.corner.CornerSize component3();
+    method public androidx.ui.foundation.shape.corner.CornerSize component4();
+    method public androidx.ui.material.shape.CutCornerShape copy(androidx.ui.foundation.shape.corner.CornerSize topLeft, androidx.ui.foundation.shape.corner.CornerSize topRight, androidx.ui.foundation.shape.corner.CornerSize bottomRight, androidx.ui.foundation.shape.corner.CornerSize bottomLeft);
+    method public androidx.ui.engine.geometry.Outline.Generic createOutline(androidx.ui.core.PxSize size, androidx.ui.core.Px topLeft, androidx.ui.core.Px topRight, androidx.ui.core.Px bottomRight, androidx.ui.core.Px bottomLeft);
+    method public androidx.ui.foundation.shape.corner.CornerSize getBottomLeft();
+    method public androidx.ui.foundation.shape.corner.CornerSize getBottomRight();
+    method public androidx.ui.foundation.shape.corner.CornerSize getTopLeft();
+    method public androidx.ui.foundation.shape.corner.CornerSize getTopRight();
+  }
+
+  public final class CutCornerShapeKt {
+    ctor public CutCornerShapeKt();
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.foundation.shape.corner.CornerSize corner);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.core.Dp size);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.core.Px size);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(int percent);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.core.Dp topLeft = 0.dp, androidx.ui.core.Dp topRight = 0.dp, androidx.ui.core.Dp bottomRight = 0.dp, androidx.ui.core.Dp bottomLeft = 0.dp);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(androidx.ui.core.Px topLeft = 0.px, androidx.ui.core.Px topRight = 0.px, androidx.ui.core.Px bottomRight = 0.px, androidx.ui.core.Px bottomLeft = 0.px);
+    method public static androidx.ui.material.shape.CutCornerShape CutCornerShape(@IntRange(from=0, to=50) int topLeftPercent = 0, @IntRange(from=0, to=50) int topRightPercent = 0, @IntRange(from=0, to=50) int bottomRightPercent = 0, @IntRange(from=0, to=50) int bottomLeftPercent = 0);
   }
 
 }
@@ -328,12 +380,7 @@
     ctor public CardKt();
     method public static void Card(androidx.ui.engine.geometry.Shape shape = RectangleShape, androidx.ui.graphics.Color color = +themeColor({ 
     surface
-}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
-  public final class DrawShadowKt {
-    ctor public DrawShadowKt();
-    method public static void DrawShadow(androidx.ui.core.Dp elevation, androidx.ui.engine.geometry.Shape shape);
+}), androidx.ui.foundation.shape.border.Border? border = null, androidx.ui.core.Dp elevation = 1.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
   public final class SurfaceKt {
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/AndroidManifest.xml b/ui/ui-material/integration-tests/material-demos/src/main/AndroidManifest.xml
index d7dac44..a401789 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/AndroidManifest.xml
+++ b/ui/ui-material/integration-tests/material-demos/src/main/AndroidManifest.xml
@@ -151,5 +151,23 @@
                   android:label="Material Theme Settings"
                   android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
         </activity>
+
+        <activity android:name=".SideBySideAlertDialogActivity"
+            android:configChanges="orientation|screenSize"
+            android:label="Material/AlertDialog.SideBySide">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="androidx.ui.demos.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".StackedAlertDialogActivity"
+            android:configChanges="orientation|screenSize"
+            android:label="Material/AlertDialog.Stacked">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="androidx.ui.demos.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
     </application>
-</manifest>
+</manifest>
\ No newline at end of file
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ButtonActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ButtonActivity.kt
index e6ad89c..bfc901e 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ButtonActivity.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ButtonActivity.kt
@@ -36,18 +36,17 @@
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.compose.unaryPlus
-import androidx.ui.core.Text
-import androidx.ui.core.dp
-import androidx.ui.foundation.shape.border.Border
-import androidx.ui.graphics.Color
 import androidx.ui.layout.Center
 import androidx.ui.layout.Column
 import androidx.ui.layout.MainAxisAlignment
-import androidx.ui.layout.Padding
 import androidx.ui.material.Button
-import androidx.ui.material.TransparentButton
+import androidx.ui.material.ContainedButtonStyle
+import androidx.ui.material.samples.BaseButtonSample
+import androidx.ui.material.samples.ButtonWithTextSample
+import androidx.ui.material.samples.ContainedButtonSample
+import androidx.ui.material.samples.OutlinedButtonSample
+import androidx.ui.material.samples.TextButtonSample
 import androidx.ui.material.themeColor
-import androidx.ui.material.themeTextStyle
 
 class ButtonActivity : MaterialDemoActivity() {
 
@@ -56,36 +55,22 @@
         val onClick: () -> Unit = { Log.e("ButtonDemo", "onClick") }
         Center {
             Column(mainAxisAlignment = MainAxisAlignment.SpaceEvenly) {
-                Button(onClick = onClick, text = "LONG TEXT")
-                Button(onClick = onClick, text = "SH")
-                TransparentButton(onClick = onClick, text = "NO BACKGROUND")
-                Button(
-                    onClick = onClick,
-                    color = +themeColor { secondary },
-                    text = "SECONDARY COLOR"
-                )
+                ContainedButtonSample(onClick)
 
-                TransparentButton(
-                    onClick = onClick,
-                    border = Border(Color(0xFF888888.toInt()), 1.dp),
-                    text = "OUTLINED"
-                )
+                OutlinedButtonSample(onClick)
 
-                val customColor = Color(0xFFFFFF00.toInt())
-                Button(
-                    onClick = onClick,
-                    text = "CUSTOM STYLE",
-                    textStyle = +themeTextStyle { body2.copy(color = customColor) })
-                Button(onClick = onClick) {
-                    Padding(padding = 16.dp) {
-                        Text(text = "CUSTOM BUTTON!")
-                    }
-                }
+                TextButtonSample(onClick)
+
+                Button("SECONDARY COLOR", onClick, ContainedButtonStyle(+themeColor { secondary }))
+
+                ButtonWithTextSample(onClick)
+
+                BaseButtonSample(onClick)
 
                 // TODO(Andrey): Disabled button has wrong bg and text color for now.
                 // Need to figure out where will we store their styling. Not a part of
                 // MaterialColors right now and specs are not clear about this.
-                Button(text = "DISABLED. TODO")
+                Button("DISABLED. TODO")
             }
         }
     }
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/CustomShapeActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/CustomShapeActivity.kt
index 7d49679..a943ca6 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/CustomShapeActivity.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/CustomShapeActivity.kt
@@ -29,6 +29,7 @@
 import androidx.ui.layout.Wrap
 import androidx.ui.material.Button
 import androidx.ui.material.MaterialTheme
+import androidx.ui.material.OutlinedButtonStyle
 
 class CustomShapeActivity : MaterialDemoActivity() {
 
@@ -48,10 +49,12 @@
     MaterialTheme {
         Wrap(Alignment.Center) {
             Button(
-                shape = TriangleShape,
-                color = Color.Aqua,
                 onClick = {},
-                border = Border(Color.DarkGray, 1.dp)
+                style = OutlinedButtonStyle(
+                    shape = TriangleShape,
+                    color = Color.Aqua,
+                    border = Border(Color.DarkGray, 1.dp)
+                )
             ) {
                 FixedSpacer(100.dp, 100.dp)
             }
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/RippleDemo.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/RippleDemo.kt
index ebb0aa1..d93ad3f 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/RippleDemo.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/RippleDemo.kt
@@ -24,7 +24,6 @@
 import androidx.ui.core.dp
 import androidx.ui.core.px
 import androidx.ui.foundation.shape.border.Border
-import androidx.ui.foundation.shape.corner.CornerSizes
 import androidx.ui.foundation.shape.corner.RoundedCornerShape
 import androidx.ui.graphics.Color
 import androidx.ui.layout.Container
@@ -40,7 +39,7 @@
         MaterialTheme {
             Padding(padding = 50.dp) {
                 Card(
-                    shape = RoundedCornerShape(CornerSizes(100.px)),
+                    shape = RoundedCornerShape(100.px),
                     border = Border(Color(0x80000000.toInt()), 1.dp)
                 ) {
                     Ripple(bounded = true) {
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SideBySideAlertDialogActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SideBySideAlertDialogActivity.kt
new file mode 100644
index 0000000..fc3d239
--- /dev/null
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SideBySideAlertDialogActivity.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2019 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.ui.material.demos
+
+import androidx.compose.Composable
+import androidx.compose.composer
+import androidx.ui.material.samples.SideBySideAlertDialogSample
+
+class SideBySideAlertDialogActivity : MaterialDemoActivity() {
+
+    @Composable
+    override fun materialContent() {
+        SideBySideAlertDialogSample()
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/StackedAlertDialogActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/StackedAlertDialogActivity.kt
new file mode 100644
index 0000000..d55a8ba
--- /dev/null
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/StackedAlertDialogActivity.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2019 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.ui.material.demos
+import androidx.compose.Composable
+import androidx.compose.composer
+import androidx.ui.material.samples.StackedAlertDialogSample
+
+class StackedAlertDialogActivity : MaterialDemoActivity() {
+
+    @Composable
+    override fun materialContent() {
+        StackedAlertDialogSample()
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/TabActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/TabActivity.kt
index 0a22493..e4e2961 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/TabActivity.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/TabActivity.kt
@@ -24,6 +24,7 @@
 import androidx.ui.layout.Center
 import androidx.ui.layout.FlexColumn
 import androidx.ui.material.Button
+import androidx.ui.material.ContainedButtonStyle
 import androidx.ui.material.samples.FancyIndicatorContainerTabs
 import androidx.ui.material.samples.FancyIndicatorTabs
 import androidx.ui.material.samples.FancyTabs
@@ -55,9 +56,12 @@
 
             expanded(flex = 1f) {
                 Center {
-                    Button(color = Color.Cyan, text = buttonText, onClick = {
-                        showingSimple.value = !showingSimple.value
-                    })
+                    Button(
+                        style = ContainedButtonStyle(color = Color.Cyan),
+                        text = buttonText,
+                        onClick = {
+                            showingSimple.value = !showingSimple.value
+                        })
                 }
             }
         }
diff --git a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/RallyCards.kt b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/RallyCards.kt
index 3e0b661..a1d2658 100644
--- a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/RallyCards.kt
+++ b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/RallyCards.kt
@@ -33,9 +33,10 @@
 import androidx.ui.layout.Padding
 import androidx.ui.layout.Row
 import androidx.ui.layout.WidthSpacer
+import androidx.ui.material.Button
 import androidx.ui.material.Colors
 import androidx.ui.material.Divider
-import androidx.ui.material.TransparentButton
+import androidx.ui.material.TextButtonStyle
 import androidx.ui.material.surface.Card
 import androidx.ui.material.themeTextStyle
 
@@ -52,7 +53,7 @@
             Column {
                 Row(mainAxisAlignment = MainAxisAlignment.SpaceBetween) {
                     Text(text = "Alerts", style = +themeTextStyle { subtitle2 })
-                    TransparentButton(text = "See All", onClick = { })
+                    Button(text = "See All", onClick = { }, style = TextButtonStyle())
                 }
                 Padding(padding = EdgeInsets(0.dp, 12.dp, 0.dp, 12.dp)) {
                     val colors = +ambient(Colors)
@@ -71,7 +72,7 @@
                         // TODO: icons still don't work
 //                        <vectorResource res=context.resources
 //                            resId=androidx.ui.material.studies.R.drawable.sort_icon/>
-                        TransparentButton(text = "Sort", onClick = { })
+                        Button(text = "Sort", onClick = { }, style = TextButtonStyle())
                     }
                 }
             }
@@ -117,7 +118,7 @@
                         color = Color(0xFF37EFBA.toInt())
                     )
                     Divider(color = colors.surface, height = 2.dp)
-                    TransparentButton(text = "See All")
+                    Button(text = "See All", style = TextButtonStyle())
                 }
             }
         }
diff --git a/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/AlertDialogSample.kt b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/AlertDialogSample.kt
new file mode 100644
index 0000000..8a6450c
--- /dev/null
+++ b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/AlertDialogSample.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2019 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.ui.material.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.Composable
+import androidx.compose.composer
+import androidx.compose.state
+import androidx.compose.unaryPlus
+import androidx.ui.core.Text
+import androidx.ui.material.AlertDialog
+import androidx.ui.material.AlertDialogButtonLayout
+import androidx.ui.material.Button
+
+@Sampled
+@Composable
+fun SideBySideAlertDialogSample() {
+    val openDialog = +state { true }
+
+    if (openDialog.value) {
+        AlertDialog(
+            onCloseRequest = {
+                // Because we are not setting openDialog.value to false here,
+                // the user can close this dialog only via one of the buttons we provide.
+            },
+            title = {
+                Text(text = "Title")
+            },
+            text = {
+                Text("This area typically contains the supportive text" +
+                        " which presents the details regarding the Dialog's purpose.")
+            },
+            confirmButton = {
+                Button("Confirm", onClick = {
+                    openDialog.value = false
+                })
+            },
+            dismissButton = {
+                Button("Dismiss", onClick = {
+                    openDialog.value = false
+                })
+            },
+            buttonLayout = AlertDialogButtonLayout.SideBySide
+        )
+    }
+}
+
+@Sampled
+@Composable
+fun StackedAlertDialogSample() {
+    val openDialog = +state { true }
+
+    if (openDialog.value) {
+        AlertDialog(
+            onCloseRequest = {
+                // In this example we allow the dialog to be closed by other actions
+                // such as taping outside or pressing the back button.
+                openDialog.value = false
+            },
+            title = {
+                Text(text = "Title")
+            },
+            text = {
+                Text("This area typically contains the supportive text" +
+                        " which presents the details regarding the Dialog's purpose.")
+            },
+            confirmButton = {
+                Button("Long Confirm Button", onClick = {
+                    openDialog.value = false
+                })
+            },
+            dismissButton = {
+                Button("Long Dismiss Button", onClick = {
+                    openDialog.value = false
+                })
+            },
+            buttonLayout = AlertDialogButtonLayout.Stacked
+        )
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/ButtonSamples.kt b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/ButtonSamples.kt
new file mode 100644
index 0000000..48a8b66
--- /dev/null
+++ b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/ButtonSamples.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2019 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.ui.material.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.Composable
+import androidx.compose.composer
+import androidx.ui.core.Text
+import androidx.ui.core.dp
+import androidx.ui.graphics.Color
+import androidx.ui.layout.Padding
+import androidx.ui.material.BaseButton
+import androidx.ui.material.Button
+import androidx.ui.material.ContainedButtonStyle
+import androidx.ui.material.OutlinedButtonStyle
+import androidx.ui.material.TextButtonStyle
+import androidx.ui.text.TextStyle
+
+@Sampled
+@Composable
+fun BaseButtonSample(onClick: () -> Unit) {
+    BaseButton(onClick) {
+        Padding(padding = 16.dp) {
+            Text(text = "Base Button")
+        }
+    }
+}
+
+@Sampled
+@Composable
+fun OutlinedButtonSample(onClick: () -> Unit) {
+    Button("Outlined Button", onClick, OutlinedButtonStyle())
+}
+
+@Sampled
+@Composable
+fun ContainedButtonSample(onClick: () -> Unit) {
+    // ContainedButtonStyle is the default style.
+    Button("Contained Button", onClick)
+}
+
+@Sampled
+@Composable
+fun TextButtonSample(onClick: () -> Unit) {
+    Button("Text Button", onClick, TextButtonStyle())
+}
+
+@Sampled
+@Composable
+fun ButtonSample(onClick: () -> Unit) {
+    Button(onClick) {
+        Text("Custom text style", TextStyle(color = Color.Lime))
+    }
+}
+
+@Sampled
+@Composable
+fun ButtonWithTextSample(onClick: () -> Unit) {
+    Button("Button", onClick)
+}
diff --git a/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/TabSamples.kt b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/TabSamples.kt
index 058f62f..647f4c9 100644
--- a/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/TabSamples.kt
+++ b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/TabSamples.kt
@@ -32,7 +32,6 @@
 import androidx.ui.foundation.selection.MutuallyExclusiveSetItem
 import androidx.ui.foundation.shape.border.Border
 import androidx.ui.foundation.shape.border.DrawBorder
-import androidx.ui.foundation.shape.corner.CornerSizes
 import androidx.ui.foundation.shape.corner.RoundedCornerShape
 import androidx.ui.graphics.Color
 import androidx.ui.layout.Alignment
@@ -230,7 +229,7 @@
     // Color is passed in as a parameter [color]
     Padding(5.dp) {
         Container(expanded = true) {
-            DrawBorder(RoundedCornerShape(CornerSizes(5.dp)), Border(color, 2.dp))
+            DrawBorder(RoundedCornerShape(5.dp), Border(color, 2.dp))
         }
     }
 }
diff --git a/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/ThemeSamples.kt b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/ThemeSamples.kt
new file mode 100644
index 0000000..5e45c43
--- /dev/null
+++ b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/ThemeSamples.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2019 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.ui.material.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.Composable
+import androidx.compose.composer
+import androidx.compose.unaryPlus
+import androidx.ui.core.Text
+import androidx.ui.core.sp
+import androidx.ui.foundation.ColoredRect
+import androidx.ui.graphics.Color
+import androidx.ui.material.MaterialColors
+import androidx.ui.material.MaterialTheme
+import androidx.ui.material.MaterialTypography
+import androidx.ui.material.themeColor
+import androidx.ui.material.themeTextStyle
+import androidx.ui.text.TextStyle
+import androidx.ui.text.font.FontFamily
+import androidx.ui.text.font.FontWeight
+
+@Sampled
+@Composable
+fun MaterialThemeSample() {
+    val colors = MaterialColors(
+        primary = Color(0xFF1EB980.toInt()),
+        surface = Color(0xFF26282F.toInt()),
+        onSurface = Color.White
+    )
+    val typography = MaterialTypography(
+        h1 = TextStyle(fontFamily = FontFamily("RobotoCondensed"),
+            fontWeight = FontWeight.w100,
+            fontSize = 96.sp),
+        h2 = TextStyle(fontFamily = FontFamily("RobotoCondensed"),
+            fontWeight = FontWeight.w100,
+            fontSize = 60.sp)
+
+    )
+    MaterialTheme(colors = colors, typography = typography) {
+        // Your app content goes here
+    }
+}
+
+@Sampled
+@Composable
+fun ThemeColorSample() {
+    ColoredRect(color = +themeColor { primary })
+}
+
+@Sampled
+@Composable
+fun ThemeTextStyleSample() {
+    Text(text = "Styled text", style = +themeTextStyle { h1 })
+}
\ No newline at end of file
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/AppBarTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/AppBarTest.kt
index de0c637..5aa2aff 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/AppBarTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/AppBarTest.kt
@@ -27,7 +27,6 @@
 import androidx.ui.core.LayoutCoordinates
 import androidx.ui.core.OnChildPositioned
 import androidx.ui.core.PxPosition
-import androidx.ui.core.Semantics
 import androidx.ui.core.Text
 import androidx.ui.core.currentTextStyle
 import androidx.ui.core.ipx
@@ -35,11 +34,13 @@
 import androidx.ui.core.toPx
 import androidx.ui.foundation.ColoredRect
 import androidx.ui.graphics.Color
+import androidx.ui.semantics.Semantics
+import androidx.ui.semantics.testTag
 import androidx.ui.text.TextStyle
 import androidx.ui.test.assertCountEquals
 import androidx.ui.test.assertIsVisible
 import androidx.ui.test.createComposeRule
-import androidx.ui.test.findAll
+import androidx.ui.test.findAllByTag
 import androidx.ui.test.findByText
 import org.junit.Rule
 import org.junit.Test
@@ -183,13 +184,15 @@
                 TopAppBar(
                     contextualActions = createImageList(numberOfActions),
                     action = { action ->
-                        Semantics(testTag = tag) { action() }
+                        Semantics(properties = { testTag = tag }) {
+                            action()
+                        }
                     }
                 )
             }
         }
 
-        findAll { testTag == tag }.assertCountEquals(numberOfActions)
+        findAllByTag(tag).assertCountEquals(numberOfActions)
     }
 
     @Test
@@ -202,13 +205,15 @@
                 TopAppBar(
                     contextualActions = createImageList(numberOfActions),
                     action = { action ->
-                        Semantics(testTag = tag) { action() }
+                        Semantics(properties = { testTag = tag }) {
+                            action()
+                        }
                     }
                 )
             }
         }
 
-        findAll { testTag == tag }.assertCountEquals(maxNumberOfActions)
+        findAllByTag(tag).assertCountEquals(maxNumberOfActions)
     }
 
     @Test
@@ -423,13 +428,15 @@
                 BottomAppBar(
                     contextualActions = createImageList(numberOfActions),
                     action = { action ->
-                        Semantics(testTag = tag) { action() }
+                        Semantics(properties = { testTag = tag }) {
+                            action()
+                        }
                     }
                 )
             }
         }
 
-        findAll { testTag == tag }.assertCountEquals(numberOfActions)
+        findAllByTag(tag).assertCountEquals(numberOfActions)
     }
 
     @Test
@@ -442,13 +449,15 @@
                 BottomAppBar(
                     contextualActions = createImageList(numberOfActions),
                     action = { action ->
-                        Semantics(testTag = tag) { action() }
+                        Semantics(properties = { testTag = tag }) {
+                            action()
+                        }
                     }
                 )
             }
         }
 
-        findAll { testTag == tag }.assertCountEquals(maxNumberOfActions)
+        findAllByTag(tag).assertCountEquals(maxNumberOfActions)
     }
 
     private fun createImageList(count: Int) =
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/ButtonTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/ButtonTest.kt
new file mode 100644
index 0000000..c2a01fb
--- /dev/null
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/ButtonTest.kt
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2019 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.ui.material
+
+import androidx.test.filters.MediumTest
+import androidx.compose.composer
+import androidx.compose.unaryPlus
+import androidx.ui.core.Dp
+import androidx.ui.core.LayoutCoordinates
+import androidx.ui.core.OnChildPositioned
+import androidx.ui.core.OnPositioned
+import androidx.ui.core.PxPosition
+import androidx.ui.core.PxSize
+import androidx.ui.core.TestTag
+import androidx.ui.core.Text
+import androidx.ui.core.currentTextStyle
+import androidx.ui.core.dp
+import androidx.ui.core.sp
+import androidx.ui.core.toPx
+import androidx.ui.core.withDensity
+import androidx.ui.layout.Center
+import androidx.ui.layout.Column
+import androidx.ui.layout.Wrap
+import androidx.ui.test.assertSemanticsIsEqualTo
+import androidx.ui.test.createComposeRule
+import androidx.ui.test.createFullSemantics
+import androidx.ui.test.doClick
+import androidx.ui.test.findByTag
+import androidx.ui.test.findByText
+import androidx.ui.text.TextStyle
+import com.google.common.truth.Truth
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+
+@MediumTest
+@RunWith(JUnit4::class)
+class ButtonTest {
+
+    @get:Rule
+    val composeTestRule = createComposeRule()
+
+    private val defaultButtonSemantics = createFullSemantics(
+        isEnabled = true
+    )
+
+    @Test
+    fun buttonTest_defaultSemantics() {
+
+        composeTestRule.setMaterialContent {
+            Center {
+                TestTag(tag = "myButton") {
+                    Button(onClick = {}, text = "myButton")
+                }
+            }
+        }
+
+        findByTag("myButton")
+            .assertSemanticsIsEqualTo(defaultButtonSemantics)
+    }
+
+    @Test
+    fun buttonTest_disabledSemantics() {
+
+        composeTestRule.setMaterialContent {
+            Center {
+                TestTag(tag = "myButton") {
+                    Button(text = "myButton")
+                }
+            }
+        }
+
+        findByTag("myButton")
+            .assertSemanticsIsEqualTo(
+                createFullSemantics(
+                    isEnabled = false
+                )
+            )
+    }
+
+    @Test
+    fun buttonTest_findByTextAndClick() {
+        var counter = 0
+        val onClick: () -> Unit = { ++counter }
+        val text = "myButton"
+
+        composeTestRule.setMaterialContent {
+            Center {
+                Button(onClick = onClick, text = text)
+            }
+        }
+
+        // TODO(b/129400818): this actually finds the text, not the button as
+        // merge semantics aren't implemented yet
+        findByText(text)
+            .doClick()
+
+        Truth
+            .assertThat(counter)
+            .isEqualTo(1)
+    }
+
+    @Test
+    fun buttonTest_ClickIsIndependentBetweenButtons() {
+        var button1Counter = 0
+        val button1OnClick: () -> Unit = { ++button1Counter }
+        val button1Tag = "button1"
+
+        var button2Counter = 0
+        val button2OnClick: () -> Unit = { ++button2Counter }
+        val button2Tag = "button2"
+
+        val text = "myButton"
+
+        composeTestRule.setMaterialContent {
+            Column {
+                TestTag(tag = button1Tag) {
+                    Button(onClick = button1OnClick, text = text)
+                }
+                TestTag(tag = button2Tag) {
+                    Button(onClick = button2OnClick, text = text)
+                }
+            }
+        }
+
+        findByTag(button1Tag)
+            .doClick()
+
+        Truth
+            .assertThat(button1Counter)
+            .isEqualTo(1)
+
+        Truth
+            .assertThat(button2Counter)
+            .isEqualTo(0)
+
+        findByTag(button2Tag)
+            .doClick()
+
+        Truth
+            .assertThat(button1Counter)
+            .isEqualTo(1)
+
+        Truth
+            .assertThat(button2Counter)
+            .isEqualTo(1)
+    }
+
+    @Test
+    fun buttonTest_ButtonHeightIsFromSpec() {
+        if (composeTestRule.density.fontScale > 1f) {
+            // This test can be reasonable failing on the non default font scales
+            // so lets skip it.
+            return
+        }
+        composeTestRule
+            .setMaterialContentAndCollectSizes {
+                Button(onClick = {}, text = "Test button")
+            }
+            .assertHeightEqualsTo(36.dp)
+    }
+
+    @Test
+    fun buttonTest_ButtonWithLargeFontSizeIsLargerThenMinHeight() {
+        val realSize: PxSize = composeTestRule.setMaterialContentAndGetPixelSize {
+            Button(onClick = {}) {
+                Text(
+                    text = "Test button",
+                    style = TextStyle(fontSize = 50.sp)
+                )
+            }
+        }
+
+        withDensity(composeTestRule.density) {
+            Truth.assertThat(realSize.height.value)
+                .isGreaterThan(36.dp.toIntPx().value.toFloat())
+        }
+    }
+
+    @Test
+    fun buttonTest_ContainedButtonPropagateDefaultTextStyle() {
+        composeTestRule.setMaterialContent {
+            Button(onClick = {}, style = ContainedButtonStyle()) {
+                Truth.assertThat(+currentTextStyle())
+                    .isEqualTo(+themeTextStyle { button.copy(color = +themeColor { onPrimary }) })
+            }
+        }
+    }
+
+    @Test
+    fun buttonTest_OutlinedButtonPropagateDefaultTextStyle() {
+        composeTestRule.setMaterialContent {
+            Button(onClick = {}, style = OutlinedButtonStyle()) {
+                Truth.assertThat(+currentTextStyle())
+                    .isEqualTo(+themeTextStyle { button.copy(color = +themeColor { primary }) })
+            }
+        }
+    }
+
+    @Test
+    fun buttonTest_TextButtonPropagateDefaultTextStyle() {
+        composeTestRule.setMaterialContent {
+            Button(onClick = {}, style = OutlinedButtonStyle()) {
+                Truth.assertThat(+currentTextStyle())
+                    .isEqualTo(+themeTextStyle { button.copy(color = +themeColor { primary }) })
+            }
+        }
+    }
+
+    @Test
+    fun buttonTest_ContainedButtonHorPaddingIsFromSpec() {
+        assertLeftPaddingIs(16.dp) {
+            ContainedButtonStyle()
+        }
+    }
+
+    @Test
+    fun buttonTest_OutlinedButtonHorPaddingIsFromSpec() {
+        assertLeftPaddingIs(16.dp) {
+            OutlinedButtonStyle()
+        }
+    }
+
+    @Test
+    fun buttonTest_TextButtonHorPaddingIsFromSpec() {
+        assertLeftPaddingIs(8.dp) {
+            TextButtonStyle()
+        }
+    }
+
+    private fun assertLeftPaddingIs(padding: Dp, style: () -> ButtonStyle) {
+        var parentCoordinates: LayoutCoordinates? = null
+        var childCoordinates: LayoutCoordinates? = null
+        val parentLatch = CountDownLatch(1)
+        val childLatch = CountDownLatch(1)
+        composeTestRule.setMaterialContent {
+            Wrap {
+                Button(onClick = {}, style = style.invoke()) {
+                    OnPositioned {
+                        parentCoordinates = it
+                        parentLatch.countDown()
+                    }
+                    OnChildPositioned(onPositioned = {
+                        childCoordinates = it
+                        childLatch.countDown()
+                    }) {
+                        Text("Test button")
+                    }
+                }
+            }
+        }
+
+        assertTrue(parentLatch.await(1, TimeUnit.SECONDS))
+        assertTrue(childLatch.await(1, TimeUnit.SECONDS))
+        val topLeft = childCoordinates!!.localToGlobal(PxPosition.Origin).x -
+                parentCoordinates!!.localToGlobal(PxPosition.Origin).x
+        assertEquals(topLeft, withDensity(composeTestRule.density) { padding.toIntPx().toPx() })
+    }
+}
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/ButtonUiTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/ButtonUiTest.kt
deleted file mode 100644
index fb9cc63..0000000
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/ButtonUiTest.kt
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright 2019 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.ui.material
-
-import androidx.test.filters.MediumTest
-import androidx.compose.composer
-import androidx.ui.core.PxSize
-import androidx.ui.core.TestTag
-import androidx.ui.core.dp
-import androidx.ui.core.sp
-import androidx.ui.core.withDensity
-import androidx.ui.layout.Center
-import androidx.ui.layout.Column
-import androidx.ui.test.assertSemanticsIsEqualTo
-import androidx.ui.test.createComposeRule
-import androidx.ui.test.createFullSemantics
-import androidx.ui.test.doClick
-import androidx.ui.test.findByTag
-import androidx.ui.test.findByText
-import androidx.ui.text.TextStyle
-import com.google.common.truth.Truth
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@MediumTest
-@RunWith(JUnit4::class)
-class ButtonUiTest {
-
-    @get:Rule
-    val composeTestRule = createComposeRule()
-
-    private val defaultButtonSemantics = createFullSemantics(
-        isEnabled = true,
-        isButton = true
-    )
-
-    @Test
-    fun buttonTest_defaultSemantics() {
-
-        composeTestRule.setMaterialContent {
-            Center {
-                TestTag(tag = "myButton") {
-                    Button(onClick = {}, text = "myButton")
-                }
-            }
-        }
-
-        findByTag("myButton")
-            .assertSemanticsIsEqualTo(defaultButtonSemantics)
-    }
-
-    @Test
-    fun buttonTest_disabledSemantics() {
-
-        composeTestRule.setMaterialContent {
-            Center {
-                TestTag(tag = "myButton") {
-                    Button(text = "myButton")
-                }
-            }
-        }
-
-        findByTag("myButton")
-            .assertSemanticsIsEqualTo(
-                createFullSemantics(
-                    isEnabled = false,
-                    isButton = true
-                )
-            )
-    }
-
-    @Test
-    fun buttonTest_findByTextAndClick() {
-        var counter = 0
-        val onClick: () -> Unit = { ++counter }
-        val text = "myButton"
-
-        composeTestRule.setMaterialContent {
-            Center {
-                Button(onClick = onClick, text = text)
-            }
-        }
-
-        // TODO(b/129400818): this actually finds the text, not the button as
-        // merge semantics aren't implemented yet
-        findByText(text)
-            .doClick()
-
-        Truth
-            .assertThat(counter)
-            .isEqualTo(1)
-    }
-
-    @Test
-    fun buttonTest_ClickIsIndependentBetweenButtons() {
-        var button1Counter = 0
-        val button1OnClick: () -> Unit = { ++button1Counter }
-        val button1Tag = "button1"
-
-        var button2Counter = 0
-        val button2OnClick: () -> Unit = { ++button2Counter }
-        val button2Tag = "button2"
-
-        val text = "myButton"
-
-        composeTestRule.setMaterialContent {
-            Column {
-                TestTag(tag = button1Tag) {
-                    Button(onClick = button1OnClick, text = text)
-                }
-                TestTag(tag = button2Tag) {
-                    Button(onClick = button2OnClick, text = text)
-                }
-            }
-        }
-
-        findByTag(button1Tag)
-            .doClick()
-
-        Truth
-            .assertThat(button1Counter)
-            .isEqualTo(1)
-
-        Truth
-            .assertThat(button2Counter)
-            .isEqualTo(0)
-
-        findByTag(button2Tag)
-            .doClick()
-
-        Truth
-            .assertThat(button1Counter)
-            .isEqualTo(1)
-
-        Truth
-            .assertThat(button2Counter)
-            .isEqualTo(1)
-    }
-
-    @Test
-    fun buttonTest_ButtonHeightIsFromSpec() {
-        if (composeTestRule.density.fontScale > 1f) {
-            // This test can be reasonable failing on the non default font scales
-            // so lets skip it.
-            return
-        }
-        composeTestRule
-            .setMaterialContentAndCollectSizes {
-                Button(onClick = {}, text = "Test button")
-            }
-            .assertHeightEqualsTo(36.dp)
-    }
-
-    @Test
-    fun buttonTest_ButtonWithLargeFontSizeIsLargerThenMinHeight() {
-        val realSize: PxSize = composeTestRule.setMaterialContentAndGetPixelSize {
-            Button(
-                onClick = {},
-                text = "Test button",
-                textStyle = TextStyle(fontSize = 50.sp)
-            )
-        }
-
-        withDensity(composeTestRule.density) {
-            Truth.assertThat(realSize.height.value)
-                .isGreaterThan(36.dp.toIntPx().value.toFloat())
-        }
-    }
-}
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/CheckboxUiTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/CheckboxUiTest.kt
index cf168d3..376e7d8 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/CheckboxUiTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/CheckboxUiTest.kt
@@ -21,20 +21,22 @@
 import androidx.test.filters.MediumTest
 import androidx.ui.core.TestTag
 import androidx.ui.core.dp
+import androidx.ui.foundation.Strings
 import androidx.ui.foundation.selection.ToggleableState
 import androidx.ui.foundation.selection.ToggleableState.Checked
 import androidx.ui.foundation.selection.ToggleableState.Indeterminate
 import androidx.ui.foundation.selection.ToggleableState.Unchecked
+import androidx.ui.foundation.semantics.toggleableState
 import androidx.ui.layout.Column
+import androidx.ui.semantics.accessibilityValue
 import androidx.ui.test.assertIsChecked
-import androidx.ui.test.assertIsNotChecked
+import androidx.ui.test.assertIsUnchecked
 import androidx.ui.test.assertSemanticsIsEqualTo
 import androidx.ui.test.copyWith
 import androidx.ui.test.createComposeRule
 import androidx.ui.test.createFullSemantics
 import androidx.ui.test.doClick
 import androidx.ui.test.findByTag
-import com.google.common.truth.Truth
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -50,11 +52,13 @@
     // TODO(b/126881459): this should be the default semantic for checkbox
     private val defaultCheckboxCheckedSemantics = createFullSemantics(
         isEnabled = true,
-        isChecked = true
+        value = Strings.Checked,
+        toggleableState = Checked
     )
 
     private val defaultCheckboxUncheckedSemantics = defaultCheckboxCheckedSemantics.copyWith {
-        isChecked = false
+        accessibilityValue = Strings.Unchecked
+        toggleableState = Unchecked
     }
 
     private val defaultTag = "myCheckbox"
@@ -89,7 +93,7 @@
         }
 
         findByTag(defaultTag)
-            .assertIsNotChecked()
+            .assertIsUnchecked()
             .doClick()
             .assertIsChecked()
     }
@@ -104,11 +108,11 @@
         }
 
         findByTag(defaultTag)
-            .assertIsNotChecked()
+            .assertIsUnchecked()
             .doClick()
             .assertIsChecked()
             .doClick()
-            .assertIsNotChecked()
+            .assertIsUnchecked()
     }
 
     @Test
@@ -122,9 +126,9 @@
         }
 
         findByTag(defaultTag)
-            .assertIsNotChecked()
+            .assertIsUnchecked()
             .doClick()
-            .assertIsNotChecked()
+            .assertIsUnchecked()
     }
 
     @Test
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/RadioGroupUiTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/RadioGroupUiTest.kt
index 67f7537..378179d 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/RadioGroupUiTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/RadioGroupUiTest.kt
@@ -17,13 +17,14 @@
 package androidx.ui.material
 
 import androidx.compose.composer
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.Model
 import androidx.test.filters.MediumTest
 import androidx.ui.core.TestTag
 import androidx.ui.core.dp
+import androidx.ui.foundation.Strings
 import androidx.ui.layout.Column
+import androidx.ui.semantics.accessibilityValue
 import androidx.ui.test.assertIsInMutuallyExclusiveGroup
 import androidx.ui.test.assertIsSelected
 import androidx.ui.test.assertSemanticsIsEqualTo
@@ -32,8 +33,7 @@
 import androidx.ui.test.createFullSemantics
 import androidx.ui.test.doClick
 import androidx.ui.test.findByTag
-import androidx.ui.test.assertIsNotSelected
-import com.google.common.truth.Truth
+import androidx.ui.test.assertIsUnselected
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -54,11 +54,11 @@
     private val itemThree = "Sap"
 
     private val unselectedRadioGroupItemSemantics = createFullSemantics(
-        inMutuallyExclusiveGroup = true,
-        isSelected = false
+        value = Strings.NotSelected
     )
+
     private val selectedRadioGroupItemSemantics = unselectedRadioGroupItemSemantics.copyWith {
-        isSelected = true
+        accessibilityValue = Strings.Selected
     }
     private val options = listOf(itemOne, itemTwo, itemThree)
 
@@ -97,10 +97,10 @@
             .assertIsSelected()
         findByTag(itemTwo)
             .assertIsInMutuallyExclusiveGroup()
-            .assertIsNotSelected()
+            .assertIsUnselected()
         findByTag(itemThree)
             .assertIsInMutuallyExclusiveGroup()
-            .assertIsNotSelected()
+            .assertIsUnselected()
     }
 
     @Test
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/SwitchUiTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/SwitchUiTest.kt
index 855bf30..7d4afcf 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/SwitchUiTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/SwitchUiTest.kt
@@ -22,9 +22,13 @@
 import androidx.test.filters.MediumTest
 import androidx.ui.core.TestTag
 import androidx.ui.core.dp
+import androidx.ui.foundation.Strings
+import androidx.ui.foundation.selection.ToggleableState
+import androidx.ui.foundation.semantics.toggleableState
 import androidx.ui.layout.Column
+import androidx.ui.semantics.accessibilityValue
 import androidx.ui.test.assertIsChecked
-import androidx.ui.test.assertIsNotChecked
+import androidx.ui.test.assertIsUnchecked
 import androidx.ui.test.assertSemanticsIsEqualTo
 import androidx.ui.test.copyWith
 import androidx.ui.test.createComposeRule
@@ -45,10 +49,13 @@
 
     private val defaultUncheckedSwitchSemantics = createFullSemantics(
         isEnabled = true,
-        isChecked = false
+        toggleableState = ToggleableState.Unchecked,
+        value = Strings.Unchecked // TODO(a11y): Do we still call this checked/unchecked?
     )
+
     private val defaultCheckedSwitchSemantics = defaultUncheckedSwitchSemantics.copyWith {
-        isChecked = true
+        toggleableState = ToggleableState.Checked
+        accessibilityValue = Strings.Checked
     }
     private val defaultSwitchTag = "switch"
 
@@ -78,7 +85,7 @@
             }
         }
         findByTag(defaultSwitchTag)
-            .assertIsNotChecked()
+            .assertIsUnchecked()
             .doClick()
             .assertIsChecked()
     }
@@ -93,11 +100,11 @@
             }
         }
         findByTag(defaultSwitchTag)
-            .assertIsNotChecked()
+            .assertIsUnchecked()
             .doClick()
             .assertIsChecked()
             .doClick()
-            .assertIsNotChecked()
+            .assertIsUnchecked()
     }
 
     @Test
@@ -109,9 +116,9 @@
             }
         }
         findByTag(defaultSwitchTag)
-            .assertIsNotChecked()
+            .assertIsUnchecked()
             .doClick()
-            .assertIsNotChecked()
+            .assertIsUnchecked()
     }
 
     @Test
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/TabTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/TabTest.kt
index b4b1c5c..ff7b033 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/TabTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/TabTest.kt
@@ -35,11 +35,12 @@
 import androidx.ui.painting.Image
 import androidx.ui.painting.ImageConfig
 import androidx.ui.test.assertCountEquals
-import androidx.ui.test.assertIsNotSelected
+import androidx.ui.test.assertIsUnselected
 import androidx.ui.test.assertIsSelected
 import androidx.ui.test.createComposeRule
 import androidx.ui.test.doClick
 import androidx.ui.test.findAll
+import androidx.ui.test.isInMutuallyExclusiveGroup
 import com.google.common.truth.Truth
 import org.junit.Rule
 import org.junit.Test
@@ -182,7 +183,7 @@
                 if (index == 0) {
                     interaction.assertIsSelected()
                 } else {
-                    interaction.assertIsNotSelected()
+                    interaction.assertIsUnselected()
                 }
             }
         }.assertCountEquals(3)
@@ -201,7 +202,7 @@
                 if (index == 0) {
                     interaction.assertIsSelected()
                 } else {
-                    interaction.assertIsNotSelected()
+                    interaction.assertIsUnselected()
                 }
             }
         }.assertCountEquals(3)
@@ -215,7 +216,7 @@
                 if (index == lastIndex) {
                     interaction.assertIsSelected()
                 } else {
-                    interaction.assertIsNotSelected()
+                    interaction.assertIsUnselected()
                 }
             }
         }.assertCountEquals(3)
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/shape/CutCornerShapeTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/shape/CutCornerShapeTest.kt
index ff8249b..4c1072d 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/shape/CutCornerShapeTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/shape/CutCornerShapeTest.kt
@@ -22,8 +22,6 @@
 import androidx.ui.core.px
 import androidx.ui.engine.geometry.Outline
 import androidx.ui.engine.geometry.Shape
-import androidx.ui.foundation.shape.corner.CornerSize
-import androidx.ui.foundation.shape.corner.CornerSizes
 import androidx.ui.painting.Path
 import androidx.ui.painting.PathOperation
 import com.google.common.truth.Truth.assertThat
@@ -41,13 +39,7 @@
 
     @Test
     fun cutCornersUniformCorners() {
-        val cut = CutCornerShape(
-            CornerSizes(
-                CornerSize(
-                    10.px
-                )
-            )
-        )
+        val cut = CutCornerShape(10.px)
 
         val outline = cut.toOutline() as Outline.Generic
         assertPathsEquals(outline.path, Path().apply {
@@ -69,14 +61,7 @@
         val size2 = 22f
         val size3 = 32f
         val size4 = 42f
-        val cut = CutCornerShape(
-            CornerSizes(
-                CornerSize(size1.px),
-                CornerSize(size2.px),
-                CornerSize(size3.px),
-                CornerSize(size4.px)
-            )
-        )
+        val cut = CutCornerShape(size1.px, size2.px, size3.px, size4.px)
 
         val outline = cut.toOutline() as Outline.Generic
         assertPathsEquals(outline.path, Path().apply {
@@ -94,8 +79,8 @@
 
     @Test
     fun cutCornerShapesAreEquals() {
-        assertThat(CutCornerShape(CornerSizes(10.px)))
-            .isEqualTo(CutCornerShape(CornerSizes(10.px)))
+        assertThat(CutCornerShape(10.px))
+            .isEqualTo(CutCornerShape(10.px))
     }
 
     private fun Shape.toOutline() = createOutline(size, density)
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/AlertDialog.kt b/ui/ui-material/src/main/java/androidx/ui/material/AlertDialog.kt
new file mode 100644
index 0000000..7b09461
--- /dev/null
+++ b/ui/ui-material/src/main/java/androidx/ui/material/AlertDialog.kt
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2019 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.ui.material
+
+import androidx.compose.Composable
+import androidx.compose.composer
+import androidx.compose.ambient
+import androidx.compose.unaryPlus
+import androidx.ui.core.CurrentTextStyleProvider
+import androidx.ui.core.dp
+import androidx.ui.foundation.Dialog
+import androidx.ui.foundation.shape.corner.RoundedCornerShape
+import androidx.ui.layout.Alignment
+import androidx.ui.layout.Column
+import androidx.ui.layout.Container
+import androidx.ui.layout.CrossAxisAlignment
+import androidx.ui.layout.EdgeInsets
+import androidx.ui.layout.FlexSize
+import androidx.ui.layout.HeightSpacer
+import androidx.ui.layout.MainAxisAlignment
+import androidx.ui.layout.Row
+import androidx.ui.layout.WidthSpacer
+import androidx.ui.material.surface.Surface
+
+/**
+ * Alert dialog is a [Dialog] which interrupts the user with urgent information, details or actions.
+ *
+ * There are two different layouts for showing the buttons inside the Alert dialog provided by
+ * [AlertDialogButtonLayout].
+ *
+ * Sample of dialog with side by side buttons:
+ *
+ * @sample androidx.ui.material.samples.SideBySideAlertDialogSample
+ *
+ * Sample of dialog with stacked buttons:
+ *
+ * @sample androidx.ui.material.samples.StackedAlertDialogSample
+ *
+ * @param onCloseRequest Executes when the user tries to dismiss the Dialog by clicking outside
+ * or pressing the back button.
+ * @param title The title of the Dialog which should specify the purpose of the Dialog. The title
+ * is not mandatory, because there may be sufficient information inside the [text].
+ * @param text The text which presents the details regarding
+ * the Dialog's purpose.
+ * @param confirmButton A button which is meant to confirm a proposed action, thus resolving
+ * what triggered the dialog.
+ * @param dismissButton A button which is meant to dismiss the dialog.
+ * @param buttonLayout An enum which specifies how the buttons are positioned inside the dialog:
+ * SideBySide or Stacked.
+ *
+ */
+// TODO(b/137311217): type inference for nullable lambdas currently doesn't work
+@Suppress("USELESS_CAST")
+@Composable
+fun AlertDialog(
+    onCloseRequest: () -> Unit,
+    title: (@Composable() () -> Unit)? = null as @Composable() (() -> Unit)?,
+    text: (@Composable() () -> Unit),
+    confirmButton: (@Composable() () -> Unit),
+    dismissButton: (@Composable() () -> Unit)? = null as @Composable() (() -> Unit)?,
+    buttonLayout: AlertDialogButtonLayout = AlertDialogButtonLayout.SideBySide
+) {
+    // TODO: Find a cleaner way to pass the properties of the MaterialTheme
+    val currentColors = +ambient(Colors)
+    val currentTypography = +ambient(Typography)
+    Dialog(onCloseRequest = onCloseRequest) {
+        MaterialTheme(colors = currentColors, typography = currentTypography) {
+            Surface(shape = AlertDialogShape) {
+                Container(width = AlertDialogWidth) {
+                    Column(mainAxisSize = FlexSize.Min,
+                        crossAxisAlignment = CrossAxisAlignment.Start) {
+                        if (title != null) {
+                            Container(
+                                alignment = Alignment.CenterLeft,
+                                padding = TitlePadding
+                            ) {
+                                val textStyle = +themeTextStyle { h6 }
+                                CurrentTextStyleProvider(textStyle) {
+                                    title()
+                                }
+                            }
+                        } else {
+                            // TODO(b/138924683): Temporary until padding for the Text's
+                            //  baseline
+                            HeightSpacer(NoTitleExtraHeight)
+                        }
+
+                        Container(alignment = Alignment.CenterLeft, padding = TextPadding) {
+                            val textStyle = +themeTextStyle { body1 }
+                            CurrentTextStyleProvider(textStyle) {
+                                text()
+                            }
+                        }
+                        HeightSpacer(height = TextToButtonsHeight)
+                        AlertDialogButtonLayout(
+                            confirmButton = confirmButton,
+                            dismissButton = dismissButton,
+                            buttonLayout = buttonLayout
+                        )
+                    }
+                }
+            }
+        }
+    }
+}
+
+// TODO(b/138925106): Add Auto mode when the flow layout is implemented
+/**
+ * An enum which specifies how the buttons are positioned inside the [AlertDialog]:
+ *
+ * [SideBySide] - positions the dismiss button on the left side of the confirm button.
+ * [Stacked] - positions the dismiss button below the confirm button.
+ */
+enum class AlertDialogButtonLayout {
+    SideBySide,
+    Stacked
+}
+
+@Composable
+private fun AlertDialogButtonLayout(
+    confirmButton: @Composable() () -> Unit,
+    dismissButton: @Composable() (() -> Unit)?,
+    buttonLayout: AlertDialogButtonLayout
+) {
+    Container(padding = ButtonsPadding, alignment = Alignment.CenterRight, expanded = true) {
+        if (buttonLayout == AlertDialogButtonLayout.SideBySide) {
+            Row(
+                mainAxisAlignment = MainAxisAlignment.End,
+                mainAxisSize = FlexSize.Min
+            ) {
+                if (dismissButton != null) {
+                    dismissButton()
+                    WidthSpacer(ButtonsWidthSpace)
+                }
+
+                confirmButton()
+            }
+        } else {
+            Column {
+                confirmButton()
+
+                if (dismissButton != null) {
+                    HeightSpacer(ButtonsHeightSpace)
+                    dismissButton()
+                }
+            }
+        }
+    }
+}
+
+private val AlertDialogWidth = 280.dp
+private val ButtonsPadding = EdgeInsets(left = 0.dp, top = 8.dp, right = 8.dp, bottom = 8.dp)
+private val ButtonsWidthSpace = 8.dp
+private val ButtonsHeightSpace = 12.dp
+// TODO(b/138924683): Top padding should be actually be a distance between the Text baseline and
+//  the Title baseline
+private val TextPadding = EdgeInsets(left = 24.dp, top = 20.dp, right = 24.dp, bottom = 0.dp)
+// TODO(b/138924683): Top padding should be actually be relative to the Text baseline
+private val TitlePadding = EdgeInsets(left = 24.dp, top = 24.dp, right = 24.dp, bottom = 0.dp)
+// The height difference of the padding between a Dialog with a title and one without a title
+private val NoTitleExtraHeight = 2.dp
+private val TextToButtonsHeight = 28.dp
+// TODO: The corner radius should be customizable
+private val AlertDialogShape = RoundedCornerShape(4.dp)
\ No newline at end of file
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/AppBar.kt b/ui/ui-material/src/main/java/androidx/ui/material/AppBar.kt
index 84652bd..1f2b907 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/AppBar.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/AppBar.kt
@@ -20,7 +20,6 @@
 import androidx.compose.composer
 import androidx.compose.unaryPlus
 import androidx.ui.core.CurrentTextStyleProvider
-import androidx.ui.core.Semantics
 import androidx.ui.core.Text
 import androidx.ui.core.dp
 import androidx.ui.core.sp
@@ -46,6 +45,7 @@
 import androidx.ui.material.BottomAppBar.FabPosition.End
 import androidx.ui.material.ripple.Ripple
 import androidx.ui.painting.Image
+import androidx.ui.semantics.Semantics
 import androidx.ui.text.TextStyle
 
 /**
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Button.kt b/ui/ui-material/src/main/java/androidx/ui/material/Button.kt
index 5137a35..f8b7b54 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Button.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Button.kt
@@ -1,3 +1,4 @@
+
 /*
  * Copyright 2019 The Android Open Source Project
  *
@@ -16,8 +17,8 @@
 
 package androidx.ui.material
 
-import androidx.compose.Children
 import androidx.compose.Composable
+import androidx.compose.Immutable
 import androidx.compose.composer
 import androidx.compose.unaryPlus
 import androidx.ui.core.CurrentTextStyleProvider
@@ -26,6 +27,7 @@
 import androidx.ui.core.dp
 import androidx.ui.engine.geometry.Shape
 import androidx.ui.foundation.Clickable
+import androidx.ui.foundation.shape.RectangleShape
 import androidx.ui.foundation.shape.border.Border
 import androidx.ui.graphics.Color
 import androidx.ui.layout.Container
@@ -36,160 +38,218 @@
 import androidx.ui.text.TextStyle
 
 /**
- * [Button] with flexible user interface. You can provide any content you want as a
- * [children] composable.
+ * Styling configuration for a [Button].
  *
- * To make a [Button] clickable, you must provide an [onClick]. Not providing it will
- * also make this [Button] to be displayed as a disabled one.
- * You can specify a [shape] of the surface, it's background [color] and an [elevation].
+ * The three basic Material button styles are provided by [ContainedButtonStyle], intended for high
+ * emphasis buttons, [OutlinedButtonStyle], intended for medium emphasis buttons, and
+ * [TextButtonStyle], intended for low emphasis buttons.
  *
- * The text style for internal [Text] components will be changed to [MaterialTypography.button],
- * text color will try to match the correlated color for the background [color]. For example,
- * on [MaterialColors.primary] background [MaterialColors.onPrimary] will be used for text.
- * To modify these default style values use [CurrentTextStyleProvider].
+ * @param color The background color. Use [Color.Transparent] to have no color
+ * @param shape Defines the button's shape as well as its shadow
+ * @param border Optional border to draw on top of the shape
+ * @param elevation The z-coordinate at which to place this button. This controls the size
+ *  of the shadow below the button
+ * @param paddings The spacing values to apply internally between the container and the content
+ * @param textStyle The text style to apply as a default for any children [Text] components
+ */
+@Immutable
+data class ButtonStyle(
+    val color: Color,
+    val shape: Shape,
+    val border: Border? = null,
+    val elevation: Dp = 0.dp,
+    val paddings: EdgeInsets = ButtonPaddings,
+    val textStyle: TextStyle? = null
+)
+
+/**
+ * Style used to configure a Button to look like a
+ * [Material Contained Button][https://material.io/design/components/buttons.html#contained-button].
  *
- * Example:
- *     Button(onClick = { ... }) {
- *         Padding(padding = EdgeInsets(16.dp)) {
- *             Text(text=TextSpan(text="CUSTOM BUTTON"))
- *         }
- *     }
+ * Contained buttons are high-emphasis, distinguished by their use of elevation and fill. They
+ * contain actions that are primary to your app.
  *
- * @see Button overload for the default Material Design implementation of [Button] with text.
+ * @sample androidx.ui.material.samples.ContainedButtonSample
  *
- * @param onClick Will be called when user clicked on the button. The button will be disabled
- *  when it is null.
- * @param shape Defines the Button's shape as well its shadow. When null is provided it uses
- *  the [Shapes.button] value from the theme.
- * @param color The background color. [MaterialColors.primary] is used when null
- *  is provided. Provide [Color.Transparent] to have no color.
- * @param border Optional border to draw on top of the shape.
+ * @see OutlinedButtonStyle
+ * @see TextButtonStyle
+ *
+ * @param color The background color
+ * @param shape Defines the button's shape as well as its shadow
+ * @param elevation The z-coordinate at which to place this button. This controls the size
+ *  of the shadow below the button
+ */
+fun ContainedButtonStyle(
+    color: Color = +themeColor { primary },
+    shape: Shape = +themeShape { button },
+    elevation: Dp = 2.dp
+) = ButtonStyle(
+    color = color,
+    shape = shape,
+    elevation = elevation
+)
+
+/**
+ * Style used to configure a Button to look like a
+ * [Material Outlined Button][https://material.io/design/components/buttons.html#outlined-button].
+ *
+ * Outlined buttons are medium-emphasis buttons. They contain actions that are important, but are
+ * not the primary action in an app.
+ *
+ * Outlined buttons are also a lower emphasis alternative to contained buttons, or a higher emphasis
+ * alternative to text buttons.
+ *
+ * @sample androidx.ui.material.samples.OutlinedButtonSample
+ *
+ * @see ContainedButtonStyle
+ * @see TextButtonStyle
+ *
+ * @param border Border to draw on top of the button.
+ * @param color The background color. Provide [Color.Transparent] to have no color.
+ * @param shape Defines the Button's shape.
  * @param elevation The z-coordinate at which to place this button. This controls the size
  *  of the shadow below the button.
  */
+fun OutlinedButtonStyle(
+    border: Border = Border(+themeColor { onSurface.copy(alpha = OutlinedStrokeOpacity) }, 1.dp),
+    color: Color = +themeColor { surface },
+    shape: Shape = +themeShape { button },
+    elevation: Dp = 0.dp
+) = ButtonStyle(
+    color = color,
+    shape = shape,
+    border = border,
+    elevation = elevation,
+    textStyle = TextStyle(color = +themeColor { primary })
+)
+
+/**
+ * Style used to configure a Button to look like a
+ * [Material Text Button][https://material.io/design/components/buttons.html#text-button].
+ *
+ * Text buttons are typically used for less-pronounced actions, including those located in cards and
+ * dialogs.
+ *
+ * @sample androidx.ui.material.samples.TextButtonSample
+ *
+ * @see ContainedButtonStyle
+ * @see OutlinedButtonStyle
+ *
+ * @param shape Defines the Button's shape.
+ */
+fun TextButtonStyle(
+    shape: Shape = +themeShape { button }
+) = ButtonStyle(
+    color = Color.Transparent,
+    shape = shape,
+    paddings = TextButtonPaddings,
+    textStyle = TextStyle(color = +themeColor { primary })
+)
+
+/**
+ * Material Design implementation of [Button][https://material.io/design/components/buttons.html].
+ *
+ * To make a button clickable, you must provide an onClick. If no onClick is provided, this button will display
+ * itself as disabled.
+ *
+ * The default text style for internal [Text] components will be set to [MaterialTypography.button]. Text color will
+ * try to match the correlated color for the background color. For example if the background color is set to
+ * [MaterialColors.primary] then the text will by default use [MaterialColors.onPrimary].
+ *
+ * @sample androidx.ui.material.samples.ButtonSample
+ *
+ * @see BaseButton for the lower level variant of this component that does not provide an internal padded container.
+ *
+ * @param onClick Will be called when the user clicks the button. The button will be disabled if it is null.
+ * @param style Contains the styling parameters for the button.
+ */
 @Composable
 fun Button(
     onClick: (() -> Unit)? = null,
-    shape: Shape = +themeShape { button },
-    color: Color = +themeColor { primary },
-    border: Border? = null,
-    elevation: Dp = 0.dp,
+    style: ButtonStyle = ContainedButtonStyle(),
     children: @Composable() () -> Unit
 ) {
-    val textStyle = +themeTextStyle { button }
-    Surface(shape = shape, color = color, border = border, elevation = elevation) {
-        CurrentTextStyleProvider(value = textStyle) {
-            val clickableChildren = @Composable {
-                Clickable(onClick = onClick) {
-                    children()
-                }
-            }
-            if (onClick != null) {
-                Ripple(bounded = true) {
-                    clickableChildren()
-                }
-            } else {
-                clickableChildren()
-            }
-        }
+    BaseButton(
+        onClick = onClick,
+        color = style.color,
+        shape = style.shape,
+        border = style.border,
+        elevation = style.elevation,
+        textStyle = +themeTextStyle { button.merge(style.textStyle) }
+    ) {
+        Container(constraints = ButtonConstraints, padding = style.paddings, children = children)
     }
 }
 
 /**
- * Material Design implementation of [Button] with [text].
+ * Material Design implementation of [Button][https://material.io/design/components/buttons.html] that contains some
+ * text.
  *
- * To make a [Button] clickable, you must provide an [onClick]. Not providing it will
- * also make this [Button] to be displayed as a disabled one.
- * You can specify a [shape] of the surface, it's background [color] and [elevation].
+ * To make a button clickable, you must provide an onClick. If no onClick is provided, this button will display
+ * itself as disabled.
  *
- * The text style for internal [Text] components will be changed to [MaterialTypography.button],
- * text color will try to match the correlated color for the background [color]. For example,
- * on [MaterialColors.primary] background [MaterialColors.onPrimary] will be used for text.
+ * The default text style for internal [Text] components will be set to [MaterialTypography.button]. Text color will
+ * try to match the correlated color for the background color. For example if the background color is set to
+ * [MaterialColors.primary] then the text will by default use [MaterialColors.onPrimary].
  *
- * Example:
- *     Button(
- *         onClick = { ... },
- *         text="TEXT"))
+ * @sample androidx.ui.material.samples.ButtonWithTextSample
  *
- * @see Button for the flexible implementation with a customizable content.
- * @see TransparentButton for the version with no background.
+ * There is a different overload for this component that takes a lambda of customizable content.
  *
  * @param text The text to display.
- * @param textStyle The optional text style to apply for the text.
- * @param onClick Will be called when user clicked on the button. The button will be disabled
- *  when it is null.
- * @param shape Defines the Button's shape as well its shadow. When null is provided it uses
- *  the [Shapes.button] value from the theme.
- * @param color The background color. [MaterialColors.primary] is used when null
- *  is provided. Use [TransparentButton] to have no color.
- * @param border Optional border to draw on top of the shape.
- * @param elevation The z-coordinate at which to place this button. This controls the size
- *  of the shadow below the button.
+ * @param onClick Will be called when the user clicks the button. The button will be disabled if it is null.
+ * @param style Contains the styling parameters for the button.
  */
 @Composable
 fun Button(
     text: String,
-    textStyle: TextStyle? = null,
     onClick: (() -> Unit)? = null,
-    shape: Shape = +themeShape { button },
-    color: Color = +themeColor { primary },
-    border: Border? = null,
-    elevation: Dp = 0.dp
+    style: ButtonStyle = ContainedButtonStyle()
 ) {
-    Button(
-        onClick = onClick,
-        elevation = elevation,
-        color = color,
-        border = border,
-        shape = shape
-    ) {
-        val hasBackground = color.alpha > 0 || border != null
-        Container(
-            constraints = ButtonConstraints,
-            padding = if (hasBackground) ButtonPaddings else ButtonPaddingsNoBg
-        ) {
-            Text(text = text, style = textStyle)
-        }
+    Button(style = style, onClick = onClick) {
+        Text(text = text)
     }
 }
 
 /**
- * Material Design implementation of [Button] with [text] and no background.
- * This will also apply [MaterialColors.primary] as a text color by default, but
- * you can override this with [textStyle].
+ * A basic Button with no internal content. Content can be provided via the children lambda parameter.
  *
- * To make a [Button] clickable, you must provide an [onClick]. Not providing it will
- * also make this [Button] to be displayed as a disabled one.
- * You can specify a [shape] of the surface, it's background [color] and [elevation].
+ * To make a button clickable, you must provide an onClick. If no onClick is provided, this button will display
+ * itself as disabled.
  *
- * @param text The text to display.
- * @param textStyle The optional text style to apply for the text.
- * @param onClick Will be called when user clicked on the button. The button will be disabled
- *  when it is null.
- * @param shape Defines the Button's shape as well its shadow. When null is provided it uses
- *  the [Shapes.button] from [CurrentShapeAmbient].
- * @param border Optional border to draw on top of the shape.
+ * @sample androidx.ui.material.samples.BaseButtonSample
+ *
+ * For a Material styled button, see [Button].
+ *
+ * @param onClick Will be called when the user clicks the button. The button will be disabled if it is null.
+ * @param color The background color. Provide [Color.Transparent] to have no color.
+ * @param shape Defines the Button's shape as well its shadow.
+ * @param border Optional border to draw on top of the button.
  * @param elevation The z-coordinate at which to place this button. This controls the size
  *  of the shadow below the button.
+ * @param textStyle The text style to apply for the children [Text] components.
  */
 @Composable
-fun TransparentButton(
-    text: String,
-    textStyle: TextStyle? = null,
+fun BaseButton(
     onClick: (() -> Unit)? = null,
-    shape: Shape = +themeShape { button },
+    color: Color = +themeColor { primary },
+    shape: Shape = RectangleShape,
     border: Border? = null,
-    elevation: Dp = 0.dp
+    elevation: Dp = 0.dp,
+    textStyle: TextStyle = +themeTextStyle { button },
+    children: @Composable() () -> Unit
 ) {
-    val finalTextStyle = TextStyle(color = +themeColor { primary }).merge(textStyle)
-    Button(
-        text = text,
-        onClick = onClick,
-        shape = shape,
-        elevation = elevation,
-        textStyle = finalTextStyle,
-        border = border,
-        color = Color.Transparent)
+    Surface(shape, color, border, elevation) {
+        CurrentTextStyleProvider(value = textStyle) {
+            if (onClick != null) {
+                Ripple(bounded = true) {
+                    Clickable(onClick = onClick, children = children)
+                }
+            } else {
+                Clickable(children = children)
+            }
+        }
+    }
 }
 
 // Specification for Material Button:
@@ -197,18 +257,17 @@
     minWidth = 64.dp,
     minHeight = 36.dp
 )
-private val ButtonHorPadding = 16.dp
-private val ButtonHorPaddingNoBg = 8.dp
-private val ButtonVerPadding = 8.dp
+private val ButtonHorizontalPadding = 16.dp
+private val ButtonVerticalPadding = 8.dp
 private val ButtonPaddings = EdgeInsets(
-    left = ButtonHorPadding,
-    top = ButtonVerPadding,
-    right = ButtonHorPadding,
-    bottom = ButtonVerPadding
+    left = ButtonHorizontalPadding,
+    top = ButtonVerticalPadding,
+    right = ButtonHorizontalPadding,
+    bottom = ButtonVerticalPadding
 )
-private val ButtonPaddingsNoBg = EdgeInsets(
-    left = ButtonHorPaddingNoBg,
-    top = ButtonVerPadding,
-    right = ButtonHorPaddingNoBg,
-    bottom = ButtonVerPadding
-)
\ No newline at end of file
+private val TextButtonHorizontalPadding = 8.dp
+private val TextButtonPaddings = ButtonPaddings.copy(
+    left = TextButtonHorizontalPadding,
+    right = TextButtonHorizontalPadding
+)
+private val OutlinedStrokeOpacity = 0.12f
\ No newline at end of file
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Drawer.kt b/ui/ui-material/src/main/java/androidx/ui/material/Drawer.kt
index 547149d8..7e5e527 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Drawer.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Drawer.kt
@@ -298,7 +298,7 @@
         RepaintBoundary {
             child()
         }
-    }, layoutBlock = { measurables, constraints ->
+    }) { measurables, constraints ->
         if (measurables.size > 1) {
             throw IllegalStateException("Only one child is allowed")
         }
@@ -316,7 +316,7 @@
         layout(width, height) {
             placeable?.place(xOffset.toIntPx(), yOffset.toIntPx())
         }
-    })
+    }
 }
 
 private val ScrimDefaultOpacity = 0.32f
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/FloatingActionButton.kt b/ui/ui-material/src/main/java/androidx/ui/material/FloatingActionButton.kt
index 019eb31..28a1e28 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/FloatingActionButton.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/FloatingActionButton.kt
@@ -16,7 +16,6 @@
 
 package androidx.ui.material
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.compose.unaryPlus
@@ -63,10 +62,15 @@
     minSize: Dp = FabSize,
     shape: Shape = CircleShape,
     color: Color = +themeColor { primary },
-    elevation: Dp = 0.dp, // TODO(Andrey) add the default elevation when it ready b/123215187
+    elevation: Dp = 6.dp,
     children: @Composable() () -> Unit
 ) {
-    Button(color = color, onClick = onClick, shape = shape, elevation = elevation) {
+    BaseButton(
+        color = color,
+        shape = shape,
+        elevation = elevation,
+        onClick = onClick
+    ) {
         Container(constraints = DpConstraints(minWidth = minSize, minHeight = minSize)) {
             children()
         }
@@ -95,7 +99,7 @@
     icon: Image,
     onClick: (() -> Unit)? = null,
     color: Color = +themeColor { primary },
-    elevation: Dp = 0.dp
+    elevation: Dp = 6.dp
 ) {
     FloatingActionButton(onClick = onClick, color = color, elevation = elevation) {
         SimpleImage(image = icon)
@@ -126,7 +130,7 @@
     textStyle: TextStyle? = null,
     onClick: (() -> Unit)? = null,
     color: Color = +themeColor { primary },
-    elevation: Dp = 0.dp
+    elevation: Dp = 6.dp
 ) {
     FloatingActionButton(
         onClick = onClick,
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/MaterialTheme.kt b/ui/ui-material/src/main/java/androidx/ui/material/MaterialTheme.kt
index 76ce952..6ca12a8 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/MaterialTheme.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/MaterialTheme.kt
@@ -18,7 +18,6 @@
 
 import androidx.annotation.CheckResult
 import androidx.compose.Ambient
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.compose.ambient
@@ -30,7 +29,6 @@
 import androidx.ui.core.sp
 import androidx.ui.core.withDensity
 import androidx.ui.engine.geometry.Shape
-import androidx.ui.foundation.shape.corner.CornerSizes
 import androidx.ui.foundation.shape.corner.RoundedCornerShape
 import androidx.ui.graphics.Color
 import androidx.ui.material.ripple.CurrentRippleTheme
@@ -41,17 +39,22 @@
 import androidx.ui.text.TextStyle
 
 /**
- * This Component defines the styling principles from the Material design specification. It must be
+ * This component defines the styling principles from the Material design specification. It must be
  * present within a hierarchy of components that includes Material components, as it defines key
  * values such as base colors and typography.
  *
- * By default, it defines the colors as specified in the Color theme creation spec
- * (https://material.io/design/color/the-color-system.html#color-theme-creation) and the typography
- * defined in the Type Scale spec
- * (https://material.io/design/typography/the-type-system.html#type-scale).
+ * Material components such as [Button] and [Checkbox] use this definition to set default values.
  *
- * All values may be overriden by providing this component with the [colors] and [typography]
- * attributes. Use this to configure the overall theme of your application.
+ * It defines colors as specified in the [Material Color theme creation spec]
+ * [https://material.io/design/color/the-color-system.html#color-theme-creation] and the typography
+ * defined in the [Material Type Scale spec]
+ * [https://material.io/design/typography/the-type-system.html#type-scale].
+ *
+ * All values may be set by providing this component with the [colors][MaterialColors] and
+ * [typography][MaterialTypography] attributes. Use this to configure the overall theme of your
+ * application.
+ *
+ * @sample androidx.ui.material.samples.MaterialThemeSample
  */
 @Composable
 fun MaterialTheme(
@@ -75,21 +78,25 @@
  * by the Material spec. You can read the values in it when creating custom components that want
  * to use Material colors, as well as override the values when you want to re-style a part of your
  * hierarchy.
+ *
+ * To access values within this ambient, use [themeColor].
  */
 val Colors = Ambient.of<MaterialColors>("colors") { error("No colors found!") }
 
 /**
- * This Ambient holds on to the current definiton of typography for this application as described
+ * This Ambient holds on to the current definition of typography for this application as described
  * by the Material spec.  You can read the values in it when creating custom components that want
  * to use Material types, as well as override the values when you want to re-style a part of your
- * hierarchy. Material components related to text such as [H1TextStyle] will refer to this Ambient
- * to obtain the values with which to style text.
+ * hierarchy. Material components related to text such as [Button] will use this Ambient
+ * to set values with which to style children text components.
+ *
+ * To access values within this ambient, use [themeTextStyle].
  */
 val Typography = Ambient.of<MaterialTypography>("typography") { error("No typography found!") }
 
 /**
- * Data class holding color values as defined by the Material specification
- * (https://material.io/design/color/the-color-system.html#color-theme-creation).
+ * Data class holding color values as defined by the [Material color specification]
+ * [https://material.io/design/color/the-color-system.html#color-theme-creation].
  */
 data class MaterialColors(
     /**
@@ -98,25 +105,23 @@
      */
     val primary: Color = Color(0xFF6200EE.toInt()),
     /**
-     * The primary variant is used to distinguish two elements of the app using the primary color,
-     * such as the top app bar and the system bar.
+     * The primary variant color is used to distinguish two elements of the app using the primary
+     * color, such as the top app bar and the system bar.
      */
     val primaryVariant: Color = Color(0xFF3700B3.toInt()),
     /**
      * The secondary color provides more ways to accent and distinguish your product.
      * Secondary colors are best for:
-     * <ul>
-     *     <li>Floating action buttons</li>
-     *     <li>Selection controls, like sliders and switches</li>
-     *     <li>Highlighting selected text</li>
-     *     <li>Progress bars</li>
-     *     <li>Links and headlines</li>
-     * </ul>
+     * - Floating action buttons
+     * - Selection controls, like sliders and switches
+     * - Highlighting selected text
+     * - Progress bars
+     * - Links and headlines
      */
     val secondary: Color = Color(0xFF03DAC6.toInt()),
     /**
-     * The secondary variant is used to distinguish two elements of the app using the secondary
-     * color.
+     * The secondary variant color is used to distinguish two elements of the app using the
+     * secondary color.
      */
     val secondaryVariant: Color = Color(0xFF018786.toInt()),
     /**
@@ -154,8 +159,8 @@
 )
 
 /**
- * Data class holding typography definitions as defined by the Material specification
- * (https://material.io/design/typography/the-type-system.html#type-scale).
+ * Data class holding typography definitions as defined by the [Material typography specification]
+ * [https://material.io/design/typography/the-type-system.html#type-scale].
  */
 data class MaterialTypography(
     // TODO(clara): case
@@ -221,7 +226,7 @@
  * guidelines for descendants
  */
 @Composable
-fun MaterialRippleTheme(children: @Composable() () -> Unit) {
+private fun MaterialRippleTheme(children: @Composable() () -> Unit) {
     val materialColors = +ambient(Colors)
     val defaultTheme = +memo {
         RippleTheme(
@@ -241,7 +246,9 @@
 }
 
 /**
- * Helps to resolve the [Color] by applying [choosingBlock] for the [MaterialColors].
+ * Helper effect that resolves [Color]s from the [Colors] ambient by applying [choosingBlock].
+ *
+ * @sample androidx.ui.material.samples.ThemeColorSample
  */
 @CheckResult(suggest = "+")
 fun themeColor(
@@ -249,7 +256,10 @@
 ) = effectOf<Color> { (+ambient(Colors)).choosingBlock() }
 
 /**
- * Helps to resolve the [TextStyle] by applying [choosingBlock] for the [MaterialTypography].
+ * Helper effect that resolves [TextStyle]s from the [Typography] ambient by applying
+ * [choosingBlock].
+ *
+ * @sample androidx.ui.material.samples.ThemeTextStyleSample
  */
 @CheckResult(suggest = "+")
 fun themeTextStyle(
@@ -289,14 +299,15 @@
 fun MaterialButtonShapeTheme(children: @Composable() () -> Unit) {
     val value = +withDensity {
         Shapes(
-            button = RoundedCornerShape(CornerSizes(4.dp))
+            button = RoundedCornerShape(4.dp)
         )
     }
     CurrentShapeAmbient.Provider(value = value, children = children)
 }
 
 /**
- * Helps to resolve the [Shape] by applying [choosingBlock] for the [Shapes].
+ * Helper effect to resolve [Shape]s from the [CurrentShapeAmbient] ambient by applying
+ * [choosingBlock].
  */
 @CheckResult(suggest = "+")
 fun themeShape(
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/ripple/RippleTheme.kt b/ui/ui-material/src/main/java/androidx/ui/material/ripple/RippleTheme.kt
index c428435..2622055b 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/ripple/RippleTheme.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/ripple/RippleTheme.kt
@@ -16,19 +16,15 @@
 
 package androidx.ui.material.ripple
 
-import androidx.ui.material.MaterialRippleTheme
 import androidx.ui.graphics.Color
 import androidx.compose.Ambient
 
 /**
- * Defines the appearance and the behavior for [RippleEffect]s.
- * Used for customisation of [Ripple].
+ * Defines the appearance and the behavior for [RippleEffect]s. Used for customisation of [Ripple].
  *
- * To change some parameter and apply it to descendants modify
- * the [CurrentRippleTheme] ambient.
+ * To change some parameter and apply it to descendants modify the [CurrentRippleTheme] ambient.
  *
- * To apply the default values based on the Material Design guidelines
- * use [MaterialRippleTheme].
+ * To apply the default values based on the Material Design guidelines use [androidx.ui.material.MaterialTheme].
  */
 data class RippleTheme(
     /**
@@ -48,5 +44,5 @@
 typealias RippleColorCallback = (background: Color?) -> (Color)
 
 val CurrentRippleTheme = Ambient.of<RippleTheme> {
-    error("No RippleTheme provided. Please add MaterialRippleTheme as an ancestor.")
+    error("No RippleTheme provided. Please add MaterialTheme as an ancestor.")
 }
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/shape/CutCornerShape.kt b/ui/ui-material/src/main/java/androidx/ui/material/shape/CutCornerShape.kt
index 8f14f3d..5226f09 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/shape/CutCornerShape.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/shape/CutCornerShape.kt
@@ -16,37 +16,117 @@
 
 package androidx.ui.material.shape
 
+import androidx.annotation.IntRange
+import androidx.ui.core.Dp
+import androidx.ui.core.Px
 import androidx.ui.core.PxSize
+import androidx.ui.core.dp
+import androidx.ui.core.px
 import androidx.ui.engine.geometry.Outline
 import androidx.ui.foundation.shape.corner.CornerBasedShape
-import androidx.ui.foundation.shape.corner.CornerSizes
-import androidx.ui.foundation.shape.corner.PxCornerSizes
+import androidx.ui.foundation.shape.corner.CornerSize
 import androidx.ui.painting.Path
 
 /**
  * A shape describing the rectangle with cut corners.
  * Corner size is representing the cut length - the size of both legs of the cut's right triangle.
  *
- * @param corners define all four corner sizes
+ * @param topLeft a size of the top left corner
+ * @param topRight a size of the top right corner
+ * @param bottomRight a size of the bottom left corner
+ * @param bottomLeft a size of the bottom right corner
  */
 data class CutCornerShape(
-    val corners: CornerSizes
-) : CornerBasedShape(corners) {
+    val topLeft: CornerSize,
+    val topRight: CornerSize,
+    val bottomRight: CornerSize,
+    val bottomLeft: CornerSize
+) : CornerBasedShape(topLeft, topRight, bottomRight, bottomLeft) {
 
-    override fun createOutline(corners: PxCornerSizes, size: PxSize) =
-        Outline.Generic(Path().apply {
-            var cornerSize = corners.topLeft.value
-            moveTo(0f, cornerSize)
-            lineTo(cornerSize, 0f)
-            cornerSize = corners.topRight.value
-            lineTo(size.width.value - cornerSize, 0f)
-            lineTo(size.width.value, cornerSize)
-            cornerSize = corners.bottomRight.value
-            lineTo(size.width.value, size.height.value - cornerSize)
-            lineTo(size.width.value - cornerSize, size.height.value)
-            cornerSize = corners.bottomLeft.value
-            lineTo(cornerSize, size.height.value)
-            lineTo(0f, size.height.value - cornerSize)
-            close()
-        })
+    override fun createOutline(
+        size: PxSize,
+        topLeft: Px,
+        topRight: Px,
+        bottomRight: Px,
+        bottomLeft: Px
+    ) = Outline.Generic(Path().apply {
+        var cornerSize = topLeft.value
+        moveTo(0f, cornerSize)
+        lineTo(cornerSize, 0f)
+        cornerSize = topRight.value
+        lineTo(size.width.value - cornerSize, 0f)
+        lineTo(size.width.value, cornerSize)
+        cornerSize = bottomRight.value
+        lineTo(size.width.value, size.height.value - cornerSize)
+        lineTo(size.width.value - cornerSize, size.height.value)
+        cornerSize = bottomLeft.value
+        lineTo(cornerSize, size.height.value)
+        lineTo(0f, size.height.value - cornerSize)
+        close()
+    })
 }
+
+/**
+ * Creates [CutCornerShape] with the same size applied for all four corners.
+ */
+/*inline*/ fun CutCornerShape(corner: CornerSize) = CutCornerShape(corner, corner, corner, corner)
+
+/**
+ * Creates [CutCornerShape] with the same size applied for all four corners.
+ */
+/*inline*/ fun CutCornerShape(size: Dp) = CutCornerShape(CornerSize(size))
+
+/**
+ * Creates [CutCornerShape] with the same size applied for all four corners.
+ */
+/*inline*/ fun CutCornerShape(size: Px) = CutCornerShape(CornerSize(size))
+
+/**
+ * Creates [CutCornerShape] with the same size applied for all four corners.
+ */
+/*inline*/ fun CutCornerShape(percent: Int) = CutCornerShape(CornerSize(percent))
+
+/**
+ * Creates [CutCornerShape] with sizes defined by [Dp].
+ */
+/*inline*/ fun CutCornerShape(
+    topLeft: Dp = 0.dp,
+    topRight: Dp = 0.dp,
+    bottomRight: Dp = 0.dp,
+    bottomLeft: Dp = 0.dp
+) = CutCornerShape(
+    CornerSize(topLeft),
+    CornerSize(topRight),
+    CornerSize(bottomRight),
+    CornerSize(bottomLeft)
+)
+
+/**
+ * Creates [CutCornerShape] with sizes defined by [Px].
+ */
+/*inline*/ fun CutCornerShape(
+    topLeft: Px = 0.px,
+    topRight: Px = 0.px,
+    bottomRight: Px = 0.px,
+    bottomLeft: Px = 0.px
+) = CutCornerShape(
+    CornerSize(topLeft),
+    CornerSize(topRight),
+    CornerSize(bottomRight),
+    CornerSize(bottomLeft)
+)
+
+/**
+ * Creates [CutCornerShape] with sizes defined by percents of the shape's smaller side.
+ */
+/*inline*/ fun CutCornerShape(
+    @IntRange(from = 0, to = 50) topLeftPercent: Int = 0,
+    @IntRange(from = 0, to = 50) topRightPercent: Int = 0,
+    @IntRange(from = 0, to = 50) bottomRightPercent: Int = 0,
+    @IntRange(from = 0, to = 50) bottomLeftPercent: Int = 0
+) = CutCornerShape(
+    CornerSize(topLeftPercent),
+    CornerSize(topRightPercent),
+    CornerSize(bottomRightPercent),
+    CornerSize(bottomLeftPercent)
+)
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/surface/Card.kt b/ui/ui-material/src/main/java/androidx/ui/material/surface/Card.kt
index 544666b..8ec7d6a 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/surface/Card.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/surface/Card.kt
@@ -16,7 +16,6 @@
 
 package androidx.ui.material.surface
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.compose.unaryPlus
@@ -48,12 +47,12 @@
     shape: Shape = RectangleShape, // TODO (Andrey: Take the default shape from the theme)
     color: Color = +themeColor { surface },
     border: Border? = null,
-    elevation: Dp = 0.dp,
+    elevation: Dp = 1.dp,
     children: @Composable() () -> Unit
 ) {
     // TODO(Andrey: This currently adds no logic on top of Surface, I just reserve the name
     // for now. We will see what will be the additional Card specific logic later.
-    // It will add the default shape with rounded corners, default 1px elevation, elevate on hover.
+    // It will add the default shape with rounded corners, elevate on hover.
     Surface(
         shape = shape,
         color = color,
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/surface/DrawShadow.kt b/ui/ui-material/src/main/java/androidx/ui/material/surface/DrawShadow.kt
deleted file mode 100644
index 8522e61..0000000
--- a/ui/ui-material/src/main/java/androidx/ui/material/surface/DrawShadow.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2019 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.ui.material.surface
-
-import androidx.compose.Composable
-import androidx.compose.composer
-import androidx.ui.core.Dp
-import androidx.ui.core.dp
-import androidx.ui.engine.geometry.Shape
-
-/**
- * Draws the shadow. The [elevation] defines the visual dept of the physical object.
- * The physical object has a shape specified by [shape].
- *
- * TODO("Andrey: Replace with the real implementation based on RenderNode's elevation")
- *
- * @param elevation The z-coordinate at which to place this physical object.
- * @param shape Defines a shape of the physical object
- */
-@Composable
-fun DrawShadow(
-    elevation: Dp,
-    @Suppress("UNUSED_PARAMETER")
-    shape: Shape
-) {
-    if (elevation != 0.dp) {
-        TODO("Shadows are not yet supported")
-    }
-}
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/surface/Surface.kt b/ui/ui-material/src/main/java/androidx/ui/material/surface/Surface.kt
index 8a75fb3..ebb427e 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/surface/Surface.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/surface/Surface.kt
@@ -16,18 +16,17 @@
 
 package androidx.ui.material.surface
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.compose.unaryPlus
 import androidx.ui.core.Clip
 import androidx.ui.core.CurrentTextStyleProvider
 import androidx.ui.core.Dp
+import androidx.ui.core.DrawShadow
 import androidx.ui.core.Layout
 import androidx.ui.core.Text
 import androidx.ui.core.dp
 import androidx.ui.core.ipx
-import androidx.ui.engine.geometry.addOutline
 import androidx.ui.engine.geometry.Shape
 import androidx.ui.foundation.shape.border.Border
 import androidx.ui.foundation.shape.DrawShape
@@ -87,7 +86,9 @@
     children: @Composable() () -> Unit
 ) {
     SurfaceLayout {
-        DrawShadow(shape = shape, elevation = elevation)
+        if (elevation > 0.dp) {
+            DrawShadow(shape = shape, elevation = elevation)
+        }
         DrawShape(shape = shape, color = color)
         Clip(shape = shape) {
             RippleSurface(color = color) {
@@ -111,7 +112,7 @@
  */
 @Composable
 private fun SurfaceLayout(children: @Composable() () -> Unit) {
-    Layout(children = children, layoutBlock = { measurables, constraints ->
+    Layout(children) { measurables, constraints ->
         if (measurables.size > 1) {
             throw IllegalStateException("Surface can have only one direct measurable child!")
         }
@@ -124,5 +125,5 @@
                 placeable.place(0.ipx, 0.ipx)
             }
         }
-    })
+    }
 }
diff --git a/ui/ui-platform/api/1.0.0-alpha01.txt b/ui/ui-platform/api/1.0.0-alpha01.txt
index dd10fd6..63c6bd3 100644
--- a/ui/ui-platform/api/1.0.0-alpha01.txt
+++ b/ui/ui-platform/api/1.0.0-alpha01.txt
@@ -1,4 +1,16 @@
 // Signature format: 3.0
+package androidx.ui.autofill {
+
+  public final class AndroidAutofillDebugUtilsKt {
+    ctor public AndroidAutofillDebugUtilsKt();
+  }
+
+  public final class AndroidAutofillKt {
+    ctor public AndroidAutofillKt();
+  }
+
+}
+
 package androidx.ui.core {
 
   public final class AndroidCraneView extends android.view.ViewGroup implements androidx.ui.core.Owner androidx.ui.core.SemanticsTreeProvider {
@@ -6,7 +18,10 @@
     method public androidx.ui.core.PxPosition calculatePosition();
     method public void callDraw(androidx.ui.painting.Canvas canvas, androidx.ui.core.ComponentNode node, androidx.ui.core.PxSize parentSize, androidx.ui.core.DensityReceiver densityReceiver);
     method public java.util.List<androidx.ui.core.SemanticsTreeNode> getAllSemanticNodes();
+    method public androidx.ui.autofill.Autofill? getAutofill();
+    method public androidx.ui.autofill.AutofillTree getAutofillTree();
     method public kotlin.jvm.functions.Function0<kotlin.Unit>? getCommitUnsubscribe();
+    method public kotlin.jvm.functions.Function0<kotlin.Unit> getConfigurationChangeObserver();
     method public androidx.ui.core.Constraints getConstraints();
     method public long getMeasureIteration();
     method public androidx.ui.core.Ref<androidx.ui.core.AndroidCraneView>? getRef();
@@ -24,9 +39,13 @@
     method public void onStartMeasure(androidx.ui.core.LayoutNode layoutNode);
     method public void sendEvent(android.view.MotionEvent event);
     method public void setCommitUnsubscribe(kotlin.jvm.functions.Function0<kotlin.Unit>? p);
+    method public void setConfigurationChangeObserver(kotlin.jvm.functions.Function0<kotlin.Unit> p);
     method public void setConstraints(androidx.ui.core.Constraints p);
     method public void setRef(androidx.ui.core.Ref<androidx.ui.core.AndroidCraneView>? value);
+    property public final androidx.ui.autofill.Autofill? autofill;
+    property public final androidx.ui.autofill.AutofillTree autofillTree;
     property public final kotlin.jvm.functions.Function0<kotlin.Unit>? commitUnsubscribe;
+    property public final kotlin.jvm.functions.Function0<kotlin.Unit> configurationChangeObserver;
     property public final androidx.ui.core.Constraints constraints;
     property public long measureIteration;
     property public final androidx.ui.core.Ref<androidx.ui.core.AndroidCraneView>? ref;
@@ -54,8 +73,8 @@
     method public androidx.ui.core.RepaintBoundaryNode? getRepaintBoundary();
     method public final void setDepth(int p);
     method public final void setOwnerData(Object? p);
-    method public final void visitChildren(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
-    method public final void visitChildrenReverse(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
+    method public final inline void visitChildren(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
+    method public final inline void visitChildrenReverse(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
     property protected androidx.ui.core.LayoutNode? containingLayoutNode;
     property public final int count;
     property public final int depth;
@@ -193,83 +212,33 @@
   public final class RepaintBoundaryNode extends androidx.ui.core.ComponentNode {
     ctor public RepaintBoundaryNode(String? name);
     method public boolean getClipToShape();
+    method public androidx.ui.core.Dp getElevation();
     method public String? getName();
     method public float getOpacity();
     method public androidx.ui.engine.geometry.Shape? getShape();
     method public void setClipToShape(boolean value);
+    method public void setElevation(androidx.ui.core.Dp value);
     method public void setOpacity(float value);
     method public void setShape(androidx.ui.engine.geometry.Shape? value);
     property public final boolean clipToShape;
+    property public final androidx.ui.core.Dp elevation;
     property public final float opacity;
     property public androidx.ui.core.RepaintBoundaryNode? repaintBoundary;
     property public final androidx.ui.engine.geometry.Shape? shape;
   }
 
   public final class SemanticsComponentNode extends androidx.ui.core.ComponentNode {
-    ctor public SemanticsComponentNode(boolean container, boolean explicitChildNodes, Boolean? enabled, Boolean? checked, Boolean? selected, Boolean? button, Boolean? header, Boolean? textField, Boolean? focused, Boolean? inMutuallyExclusiveGroup, Boolean? obscured, Boolean? scopesRoute, Boolean? namesRoute, Boolean? hidden, String? label, String? value, String? hint, androidx.ui.text.style.TextDirection? textDirection, String? testTag, java.util.List<? extends androidx.ui.core.semantics.SemanticsAction<?>> actions);
+    ctor public SemanticsComponentNode(androidx.ui.core.semantics.SemanticsConfiguration semanticsConfiguration, boolean container, boolean explicitChildNodes);
     ctor public SemanticsComponentNode();
-    method public java.util.List<androidx.ui.core.semantics.SemanticsAction<?>> getActions();
-    method public Boolean? getButton();
-    method public Boolean? getChecked();
     method public boolean getContainer();
-    method public Boolean? getEnabled();
     method public boolean getExplicitChildNodes();
-    method public Boolean? getFocused();
-    method public Boolean? getHeader();
-    method public Boolean? getHidden();
-    method public String? getHint();
-    method public Boolean? getInMutuallyExclusiveGroup();
-    method public String? getLabel();
-    method public Boolean? getNamesRoute();
-    method public Boolean? getObscured();
-    method public Boolean? getScopesRoute();
-    method public Boolean? getSelected();
     method public androidx.ui.core.semantics.SemanticsConfiguration getSemanticsConfiguration();
-    method public String? getTestTag();
-    method public androidx.ui.text.style.TextDirection? getTextDirection();
-    method public Boolean? getTextField();
-    method public String? getValue();
-    method public void setActions(java.util.List<? extends androidx.ui.core.semantics.SemanticsAction<?>> p);
-    method public void setButton(Boolean? p);
-    method public void setChecked(Boolean? p);
     method public void setContainer(boolean p);
-    method public void setEnabled(Boolean? p);
     method public void setExplicitChildNodes(boolean p);
-    method public void setFocused(Boolean? p);
-    method public void setHeader(Boolean? p);
-    method public void setHidden(Boolean? p);
-    method public void setHint(String? p);
-    method public void setInMutuallyExclusiveGroup(Boolean? p);
-    method public void setLabel(String? p);
-    method public void setNamesRoute(Boolean? p);
-    method public void setObscured(Boolean? p);
-    method public void setScopesRoute(Boolean? p);
-    method public void setSelected(Boolean? p);
-    method public void setTestTag(String? p);
-    method public void setTextDirection(androidx.ui.text.style.TextDirection? p);
-    method public void setTextField(Boolean? p);
-    method public void setValue(String? p);
-    property public final java.util.List<androidx.ui.core.semantics.SemanticsAction<?>> actions;
-    property public final Boolean? button;
-    property public final Boolean? checked;
+    method public void setSemanticsConfiguration(androidx.ui.core.semantics.SemanticsConfiguration p);
     property public final boolean container;
-    property public final Boolean? enabled;
     property public final boolean explicitChildNodes;
-    property public final Boolean? focused;
-    property public final Boolean? header;
-    property public final Boolean? hidden;
-    property public final String? hint;
-    property public final Boolean? inMutuallyExclusiveGroup;
-    property public final String? label;
-    property public final Boolean? namesRoute;
-    property public final Boolean? obscured;
-    property public final Boolean? scopesRoute;
-    property public final Boolean? selected;
     property public final androidx.ui.core.semantics.SemanticsConfiguration semanticsConfiguration;
-    property public final String? testTag;
-    property public final androidx.ui.text.style.TextDirection? textDirection;
-    property public final Boolean? textField;
-    property public final String? value;
   }
 
   public interface SemanticsTreeNode {
@@ -304,22 +273,6 @@
     method public void sendEvent(android.view.MotionEvent event);
   }
 
-  public final class Unicode {
-    field public static final String ALM = "\u061c";
-    field public static final String FSI = "\u2068";
-    field public static final androidx.ui.core.Unicode! INSTANCE;
-    field public static final String LRE = "\u202a";
-    field public static final String LRI = "\u2066";
-    field public static final String LRM = "\u200e";
-    field public static final String LRO = "\u202d";
-    field public static final String PDF = "\u202c";
-    field public static final String PDI = "\u2069";
-    field public static final String RLE = "\u202b";
-    field public static final String RLI = "\u2067";
-    field public static final String RLM = "\u200f";
-    field public static final String RLO = "\u202e";
-  }
-
 }
 
 package androidx.ui.core.input {
@@ -357,138 +310,31 @@
 
 package androidx.ui.core.semantics {
 
-  public final class SemanticsConfiguration {
+  public final class SemanticsConfiguration implements java.lang.Iterable<java.util.Map.Entry<? extends androidx.ui.semantics.SemanticsPropertyKey<?>,?>> kotlin.jvm.internal.markers.KMappedMarker androidx.ui.semantics.SemanticsPropertyReceiver {
     ctor public SemanticsConfiguration();
+    method public operator <T> boolean contains(androidx.ui.semantics.SemanticsPropertyKey<T> key);
     method public androidx.ui.core.semantics.SemanticsConfiguration copy();
-    method public java.util.List<androidx.ui.core.semantics.SemanticsAction<?>> getActions();
+    method public operator <T> T! get(androidx.ui.semantics.SemanticsPropertyKey<T> key);
     method public boolean getExplicitChildNodes();
     method public boolean getHasBeenAnnotated();
-    method public boolean getHasImplicitScrolling();
-    method public String? getHint();
-    method public androidx.ui.core.semantics.SemanticsHintOverrides? getHintOverrides();
-    method public String? getLabel();
-    method public boolean getLiveRegion();
-    method public boolean getNamesRoute();
-    method public boolean getScopesRoute();
-    method public Float? getScrollExtentMax();
-    method public Float? getScrollExtentMin();
-    method public Float? getScrollPosition();
-    method public String? getTestTag();
-    method public androidx.ui.text.style.TextDirection? getTextDirection();
-    method public androidx.ui.text.TextSelection? getTextSelection();
-    method public String? getValue();
-    method public boolean isBlockingSemanticsOfPreviouslyPaintedNodes();
-    method public boolean isButton();
-    method public Boolean? isChecked();
-    method public boolean isCompatibleWith(androidx.ui.core.semantics.SemanticsConfiguration? other);
-    method public Boolean? isEnabled();
-    method public boolean isFocused();
-    method public boolean isHeader();
-    method public boolean isHidden();
-    method public boolean isImage();
-    method public boolean isInMutuallyExclusiveGroup();
+    method public <T> T! getOrElse(androidx.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public <T> T? getOrElseNullable(androidx.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public boolean isMergingSemanticsOfDescendants();
-    method public boolean isObscured();
-    method public boolean isSelected();
     method public boolean isSemanticBoundary();
-    method public boolean isTextField();
-    method public Boolean? isToggled();
-    method public void setActions(java.util.List<? extends androidx.ui.core.semantics.SemanticsAction<?>> value);
-    method public void setBlockingSemanticsOfPreviouslyPaintedNodes(boolean p);
-    method public void setButton(boolean p);
-    method public void setChecked(Boolean? value);
-    method public void setEnabled(Boolean? value);
+    method public java.util.Iterator<java.util.Map.Entry<androidx.ui.semantics.SemanticsPropertyKey<?>,java.lang.Object>> iterator();
+    method public <T> void set(androidx.ui.semantics.SemanticsPropertyKey<T> key, T? value);
     method public void setExplicitChildNodes(boolean p);
-    method public void setFocused(boolean p);
-    method public void setHasBeenAnnotated(boolean p);
-    method public void setHasImplicitScrolling(boolean p);
-    method public void setHeader(boolean p);
-    method public void setHidden(boolean p);
-    method public void setHint(String? p);
-    method public void setHintOverrides(androidx.ui.core.semantics.SemanticsHintOverrides? p);
-    method public void setImage(boolean p);
-    method public void setInMutuallyExclusiveGroup(boolean p);
-    method public void setLabel(String? p);
-    method public void setLiveRegion(boolean p);
     method public void setMergingSemanticsOfDescendants(boolean value);
-    method public void setNamesRoute(boolean p);
-    method public void setObscured(boolean p);
-    method public void setScopesRoute(boolean p);
-    method public void setScrollExtentMax(Float? p);
-    method public void setScrollExtentMin(Float? p);
-    method public void setScrollPosition(Float? p);
-    method public void setSelected(boolean p);
     method public void setSemanticBoundary(boolean value);
-    method public void setTestTag(String? p);
-    method public void setTextDirection(androidx.ui.text.style.TextDirection? p);
-    method public void setTextField(boolean p);
-    method public void setTextSelection(androidx.ui.text.TextSelection? p);
-    method public void setToggled(Boolean? value);
-    method public void setValue(String? p);
-    property public final java.util.List<androidx.ui.core.semantics.SemanticsAction<?>> actions;
     property public final boolean explicitChildNodes;
     property public final boolean hasBeenAnnotated;
-    property public final boolean hasImplicitScrolling;
-    property public final String? hint;
-    property public final androidx.ui.core.semantics.SemanticsHintOverrides? hintOverrides;
-    property public final boolean isBlockingSemanticsOfPreviouslyPaintedNodes;
-    property public final boolean isButton;
-    property public final Boolean? isChecked;
-    property public final Boolean? isEnabled;
-    property public final boolean isFocused;
-    property public final boolean isHeader;
-    property public final boolean isHidden;
-    property public final boolean isImage;
-    property public final boolean isInMutuallyExclusiveGroup;
     property public final boolean isMergingSemanticsOfDescendants;
-    property public final boolean isObscured;
-    property public final boolean isSelected;
     property public final boolean isSemanticBoundary;
-    property public final boolean isTextField;
-    property public final Boolean? isToggled;
-    property public final String? label;
-    property public final boolean liveRegion;
-    property public final boolean namesRoute;
-    property public final boolean scopesRoute;
-    property public final Float? scrollExtentMax;
-    property public final Float? scrollExtentMin;
-    property public final Float? scrollPosition;
-    property public final String? testTag;
-    property public final androidx.ui.text.style.TextDirection? textDirection;
-    property public final androidx.ui.text.TextSelection? textSelection;
-    property public final String? value;
   }
 
   public final class SemanticsConfigurationKt {
     ctor public SemanticsConfigurationKt();
-  }
-
-  public enum SemanticsFlag {
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag HasCheckedState;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag HasEnabledState;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag HasImplicitScrolling;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag HasToggledState;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsButton;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsChecked;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsEnabled;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsFocused;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsHeader;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsHidden;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsImage;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsInMutuallyExclusiveGroup;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsLiveRegion;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsObscured;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsSelected;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsTextField;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsToggled;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag NamesRoute;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag ScopesRoute;
-    field public static final androidx.ui.core.semantics.SemanticsFlag.Companion! Companion;
-  }
-
-  public static final class SemanticsFlag.Companion {
-    method public java.util.Map<java.lang.Integer,androidx.ui.core.semantics.SemanticsFlag> getValues();
-    property public final java.util.Map<java.lang.Integer,androidx.ui.core.semantics.SemanticsFlag> values;
+    method public static <T> T? getOrNull(androidx.ui.core.semantics.SemanticsConfiguration, androidx.ui.semantics.SemanticsPropertyKey<T> key);
   }
 
   public final class SemanticsHintOverrides {
@@ -517,7 +363,6 @@
     method public androidx.ui.engine.geometry.Rect? getParentPaintClipRect();
     method public androidx.ui.engine.geometry.Rect? getParentSemanticsClipRect();
     method public androidx.ui.engine.geometry.Rect getRect();
-    method public boolean isDifferentFromCurrentSemanticAnnotation(androidx.ui.core.semantics.SemanticsConfiguration config);
     method public boolean isInvisible();
     method public boolean isMergedIntoParent();
     method public boolean isPartOfNodeMerging();
@@ -557,7 +402,26 @@
 
   public final class SemanticsOwner {
     ctor public SemanticsOwner();
-    method public void performAction(int id, androidx.ui.core.semantics.SemanticsActionType<?> action, Object? args = null);
+  }
+
+}
+
+package androidx.ui.internal {
+
+  public final class Unicode {
+    field public static final String ALM = "\u061c";
+    field public static final String FSI = "\u2068";
+    field public static final androidx.ui.internal.Unicode! INSTANCE;
+    field public static final String LRE = "\u202a";
+    field public static final String LRI = "\u2066";
+    field public static final String LRM = "\u200e";
+    field public static final String LRO = "\u202d";
+    field public static final String PDF = "\u202c";
+    field public static final String PDI = "\u2069";
+    field public static final String RLE = "\u202b";
+    field public static final String RLI = "\u2067";
+    field public static final String RLM = "\u200f";
+    field public static final String RLO = "\u202e";
   }
 
 }
diff --git a/ui/ui-platform/api/api_lint.ignore b/ui/ui-platform/api/api_lint.ignore
index 3275a9b..9756be2 100644
--- a/ui/ui-platform/api/api_lint.ignore
+++ b/ui/ui-platform/api/api_lint.ignore
@@ -1,18 +1,4 @@
 // Baseline format: 1.0
-AutoBoxing: androidx.ui.core.semantics.SemanticsConfiguration#getScrollExtentMax():
-    Must avoid boxed primitives (`java.lang.Float`)
-AutoBoxing: androidx.ui.core.semantics.SemanticsConfiguration#getScrollExtentMin():
-    Must avoid boxed primitives (`java.lang.Float`)
-AutoBoxing: androidx.ui.core.semantics.SemanticsConfiguration#getScrollPosition():
-    Must avoid boxed primitives (`java.lang.Float`)
-AutoBoxing: androidx.ui.core.semantics.SemanticsConfiguration#setScrollExtentMax(Float) parameter #0:
-    Must avoid boxed primitives (`java.lang.Float`)
-AutoBoxing: androidx.ui.core.semantics.SemanticsConfiguration#setScrollExtentMin(Float) parameter #0:
-    Must avoid boxed primitives (`java.lang.Float`)
-AutoBoxing: androidx.ui.core.semantics.SemanticsConfiguration#setScrollPosition(Float) parameter #0:
-    Must avoid boxed primitives (`java.lang.Float`)
-
-
 DocumentExceptions: androidx.ui.core.AndroidCraneView#onAttach(androidx.ui.core.ComponentNode):
     Method AndroidCraneView.onAttach appears to be throwing java.lang.IllegalStateException; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
 DocumentExceptions: androidx.ui.core.ComponentNodesKt#childToLocal(androidx.ui.core.LayoutNode, androidx.ui.core.LayoutNode, androidx.ui.core.PxPosition):
@@ -21,3 +7,9 @@
 
 EndsWithImpl: androidx.ui.core.SemanticsTreeNodeImpl:
     Don't expose your implementation details: `SemanticsTreeNodeImpl` ends with `Impl`
+
+
+MissingNullability: androidx.ui.core.semantics.SemanticsNode#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.core.semantics.SemanticsNode`
+MissingNullability: androidx.ui.internal.Unicode#INSTANCE:
+    Missing nullability on field `INSTANCE` in class `class androidx.ui.internal.Unicode`
diff --git a/ui/ui-platform/api/current.txt b/ui/ui-platform/api/current.txt
index dd10fd6..63c6bd3 100644
--- a/ui/ui-platform/api/current.txt
+++ b/ui/ui-platform/api/current.txt
@@ -1,4 +1,16 @@
 // Signature format: 3.0
+package androidx.ui.autofill {
+
+  public final class AndroidAutofillDebugUtilsKt {
+    ctor public AndroidAutofillDebugUtilsKt();
+  }
+
+  public final class AndroidAutofillKt {
+    ctor public AndroidAutofillKt();
+  }
+
+}
+
 package androidx.ui.core {
 
   public final class AndroidCraneView extends android.view.ViewGroup implements androidx.ui.core.Owner androidx.ui.core.SemanticsTreeProvider {
@@ -6,7 +18,10 @@
     method public androidx.ui.core.PxPosition calculatePosition();
     method public void callDraw(androidx.ui.painting.Canvas canvas, androidx.ui.core.ComponentNode node, androidx.ui.core.PxSize parentSize, androidx.ui.core.DensityReceiver densityReceiver);
     method public java.util.List<androidx.ui.core.SemanticsTreeNode> getAllSemanticNodes();
+    method public androidx.ui.autofill.Autofill? getAutofill();
+    method public androidx.ui.autofill.AutofillTree getAutofillTree();
     method public kotlin.jvm.functions.Function0<kotlin.Unit>? getCommitUnsubscribe();
+    method public kotlin.jvm.functions.Function0<kotlin.Unit> getConfigurationChangeObserver();
     method public androidx.ui.core.Constraints getConstraints();
     method public long getMeasureIteration();
     method public androidx.ui.core.Ref<androidx.ui.core.AndroidCraneView>? getRef();
@@ -24,9 +39,13 @@
     method public void onStartMeasure(androidx.ui.core.LayoutNode layoutNode);
     method public void sendEvent(android.view.MotionEvent event);
     method public void setCommitUnsubscribe(kotlin.jvm.functions.Function0<kotlin.Unit>? p);
+    method public void setConfigurationChangeObserver(kotlin.jvm.functions.Function0<kotlin.Unit> p);
     method public void setConstraints(androidx.ui.core.Constraints p);
     method public void setRef(androidx.ui.core.Ref<androidx.ui.core.AndroidCraneView>? value);
+    property public final androidx.ui.autofill.Autofill? autofill;
+    property public final androidx.ui.autofill.AutofillTree autofillTree;
     property public final kotlin.jvm.functions.Function0<kotlin.Unit>? commitUnsubscribe;
+    property public final kotlin.jvm.functions.Function0<kotlin.Unit> configurationChangeObserver;
     property public final androidx.ui.core.Constraints constraints;
     property public long measureIteration;
     property public final androidx.ui.core.Ref<androidx.ui.core.AndroidCraneView>? ref;
@@ -54,8 +73,8 @@
     method public androidx.ui.core.RepaintBoundaryNode? getRepaintBoundary();
     method public final void setDepth(int p);
     method public final void setOwnerData(Object? p);
-    method public final void visitChildren(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
-    method public final void visitChildrenReverse(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
+    method public final inline void visitChildren(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
+    method public final inline void visitChildrenReverse(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
     property protected androidx.ui.core.LayoutNode? containingLayoutNode;
     property public final int count;
     property public final int depth;
@@ -193,83 +212,33 @@
   public final class RepaintBoundaryNode extends androidx.ui.core.ComponentNode {
     ctor public RepaintBoundaryNode(String? name);
     method public boolean getClipToShape();
+    method public androidx.ui.core.Dp getElevation();
     method public String? getName();
     method public float getOpacity();
     method public androidx.ui.engine.geometry.Shape? getShape();
     method public void setClipToShape(boolean value);
+    method public void setElevation(androidx.ui.core.Dp value);
     method public void setOpacity(float value);
     method public void setShape(androidx.ui.engine.geometry.Shape? value);
     property public final boolean clipToShape;
+    property public final androidx.ui.core.Dp elevation;
     property public final float opacity;
     property public androidx.ui.core.RepaintBoundaryNode? repaintBoundary;
     property public final androidx.ui.engine.geometry.Shape? shape;
   }
 
   public final class SemanticsComponentNode extends androidx.ui.core.ComponentNode {
-    ctor public SemanticsComponentNode(boolean container, boolean explicitChildNodes, Boolean? enabled, Boolean? checked, Boolean? selected, Boolean? button, Boolean? header, Boolean? textField, Boolean? focused, Boolean? inMutuallyExclusiveGroup, Boolean? obscured, Boolean? scopesRoute, Boolean? namesRoute, Boolean? hidden, String? label, String? value, String? hint, androidx.ui.text.style.TextDirection? textDirection, String? testTag, java.util.List<? extends androidx.ui.core.semantics.SemanticsAction<?>> actions);
+    ctor public SemanticsComponentNode(androidx.ui.core.semantics.SemanticsConfiguration semanticsConfiguration, boolean container, boolean explicitChildNodes);
     ctor public SemanticsComponentNode();
-    method public java.util.List<androidx.ui.core.semantics.SemanticsAction<?>> getActions();
-    method public Boolean? getButton();
-    method public Boolean? getChecked();
     method public boolean getContainer();
-    method public Boolean? getEnabled();
     method public boolean getExplicitChildNodes();
-    method public Boolean? getFocused();
-    method public Boolean? getHeader();
-    method public Boolean? getHidden();
-    method public String? getHint();
-    method public Boolean? getInMutuallyExclusiveGroup();
-    method public String? getLabel();
-    method public Boolean? getNamesRoute();
-    method public Boolean? getObscured();
-    method public Boolean? getScopesRoute();
-    method public Boolean? getSelected();
     method public androidx.ui.core.semantics.SemanticsConfiguration getSemanticsConfiguration();
-    method public String? getTestTag();
-    method public androidx.ui.text.style.TextDirection? getTextDirection();
-    method public Boolean? getTextField();
-    method public String? getValue();
-    method public void setActions(java.util.List<? extends androidx.ui.core.semantics.SemanticsAction<?>> p);
-    method public void setButton(Boolean? p);
-    method public void setChecked(Boolean? p);
     method public void setContainer(boolean p);
-    method public void setEnabled(Boolean? p);
     method public void setExplicitChildNodes(boolean p);
-    method public void setFocused(Boolean? p);
-    method public void setHeader(Boolean? p);
-    method public void setHidden(Boolean? p);
-    method public void setHint(String? p);
-    method public void setInMutuallyExclusiveGroup(Boolean? p);
-    method public void setLabel(String? p);
-    method public void setNamesRoute(Boolean? p);
-    method public void setObscured(Boolean? p);
-    method public void setScopesRoute(Boolean? p);
-    method public void setSelected(Boolean? p);
-    method public void setTestTag(String? p);
-    method public void setTextDirection(androidx.ui.text.style.TextDirection? p);
-    method public void setTextField(Boolean? p);
-    method public void setValue(String? p);
-    property public final java.util.List<androidx.ui.core.semantics.SemanticsAction<?>> actions;
-    property public final Boolean? button;
-    property public final Boolean? checked;
+    method public void setSemanticsConfiguration(androidx.ui.core.semantics.SemanticsConfiguration p);
     property public final boolean container;
-    property public final Boolean? enabled;
     property public final boolean explicitChildNodes;
-    property public final Boolean? focused;
-    property public final Boolean? header;
-    property public final Boolean? hidden;
-    property public final String? hint;
-    property public final Boolean? inMutuallyExclusiveGroup;
-    property public final String? label;
-    property public final Boolean? namesRoute;
-    property public final Boolean? obscured;
-    property public final Boolean? scopesRoute;
-    property public final Boolean? selected;
     property public final androidx.ui.core.semantics.SemanticsConfiguration semanticsConfiguration;
-    property public final String? testTag;
-    property public final androidx.ui.text.style.TextDirection? textDirection;
-    property public final Boolean? textField;
-    property public final String? value;
   }
 
   public interface SemanticsTreeNode {
@@ -304,22 +273,6 @@
     method public void sendEvent(android.view.MotionEvent event);
   }
 
-  public final class Unicode {
-    field public static final String ALM = "\u061c";
-    field public static final String FSI = "\u2068";
-    field public static final androidx.ui.core.Unicode! INSTANCE;
-    field public static final String LRE = "\u202a";
-    field public static final String LRI = "\u2066";
-    field public static final String LRM = "\u200e";
-    field public static final String LRO = "\u202d";
-    field public static final String PDF = "\u202c";
-    field public static final String PDI = "\u2069";
-    field public static final String RLE = "\u202b";
-    field public static final String RLI = "\u2067";
-    field public static final String RLM = "\u200f";
-    field public static final String RLO = "\u202e";
-  }
-
 }
 
 package androidx.ui.core.input {
@@ -357,138 +310,31 @@
 
 package androidx.ui.core.semantics {
 
-  public final class SemanticsConfiguration {
+  public final class SemanticsConfiguration implements java.lang.Iterable<java.util.Map.Entry<? extends androidx.ui.semantics.SemanticsPropertyKey<?>,?>> kotlin.jvm.internal.markers.KMappedMarker androidx.ui.semantics.SemanticsPropertyReceiver {
     ctor public SemanticsConfiguration();
+    method public operator <T> boolean contains(androidx.ui.semantics.SemanticsPropertyKey<T> key);
     method public androidx.ui.core.semantics.SemanticsConfiguration copy();
-    method public java.util.List<androidx.ui.core.semantics.SemanticsAction<?>> getActions();
+    method public operator <T> T! get(androidx.ui.semantics.SemanticsPropertyKey<T> key);
     method public boolean getExplicitChildNodes();
     method public boolean getHasBeenAnnotated();
-    method public boolean getHasImplicitScrolling();
-    method public String? getHint();
-    method public androidx.ui.core.semantics.SemanticsHintOverrides? getHintOverrides();
-    method public String? getLabel();
-    method public boolean getLiveRegion();
-    method public boolean getNamesRoute();
-    method public boolean getScopesRoute();
-    method public Float? getScrollExtentMax();
-    method public Float? getScrollExtentMin();
-    method public Float? getScrollPosition();
-    method public String? getTestTag();
-    method public androidx.ui.text.style.TextDirection? getTextDirection();
-    method public androidx.ui.text.TextSelection? getTextSelection();
-    method public String? getValue();
-    method public boolean isBlockingSemanticsOfPreviouslyPaintedNodes();
-    method public boolean isButton();
-    method public Boolean? isChecked();
-    method public boolean isCompatibleWith(androidx.ui.core.semantics.SemanticsConfiguration? other);
-    method public Boolean? isEnabled();
-    method public boolean isFocused();
-    method public boolean isHeader();
-    method public boolean isHidden();
-    method public boolean isImage();
-    method public boolean isInMutuallyExclusiveGroup();
+    method public <T> T! getOrElse(androidx.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public <T> T? getOrElseNullable(androidx.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public boolean isMergingSemanticsOfDescendants();
-    method public boolean isObscured();
-    method public boolean isSelected();
     method public boolean isSemanticBoundary();
-    method public boolean isTextField();
-    method public Boolean? isToggled();
-    method public void setActions(java.util.List<? extends androidx.ui.core.semantics.SemanticsAction<?>> value);
-    method public void setBlockingSemanticsOfPreviouslyPaintedNodes(boolean p);
-    method public void setButton(boolean p);
-    method public void setChecked(Boolean? value);
-    method public void setEnabled(Boolean? value);
+    method public java.util.Iterator<java.util.Map.Entry<androidx.ui.semantics.SemanticsPropertyKey<?>,java.lang.Object>> iterator();
+    method public <T> void set(androidx.ui.semantics.SemanticsPropertyKey<T> key, T? value);
     method public void setExplicitChildNodes(boolean p);
-    method public void setFocused(boolean p);
-    method public void setHasBeenAnnotated(boolean p);
-    method public void setHasImplicitScrolling(boolean p);
-    method public void setHeader(boolean p);
-    method public void setHidden(boolean p);
-    method public void setHint(String? p);
-    method public void setHintOverrides(androidx.ui.core.semantics.SemanticsHintOverrides? p);
-    method public void setImage(boolean p);
-    method public void setInMutuallyExclusiveGroup(boolean p);
-    method public void setLabel(String? p);
-    method public void setLiveRegion(boolean p);
     method public void setMergingSemanticsOfDescendants(boolean value);
-    method public void setNamesRoute(boolean p);
-    method public void setObscured(boolean p);
-    method public void setScopesRoute(boolean p);
-    method public void setScrollExtentMax(Float? p);
-    method public void setScrollExtentMin(Float? p);
-    method public void setScrollPosition(Float? p);
-    method public void setSelected(boolean p);
     method public void setSemanticBoundary(boolean value);
-    method public void setTestTag(String? p);
-    method public void setTextDirection(androidx.ui.text.style.TextDirection? p);
-    method public void setTextField(boolean p);
-    method public void setTextSelection(androidx.ui.text.TextSelection? p);
-    method public void setToggled(Boolean? value);
-    method public void setValue(String? p);
-    property public final java.util.List<androidx.ui.core.semantics.SemanticsAction<?>> actions;
     property public final boolean explicitChildNodes;
     property public final boolean hasBeenAnnotated;
-    property public final boolean hasImplicitScrolling;
-    property public final String? hint;
-    property public final androidx.ui.core.semantics.SemanticsHintOverrides? hintOverrides;
-    property public final boolean isBlockingSemanticsOfPreviouslyPaintedNodes;
-    property public final boolean isButton;
-    property public final Boolean? isChecked;
-    property public final Boolean? isEnabled;
-    property public final boolean isFocused;
-    property public final boolean isHeader;
-    property public final boolean isHidden;
-    property public final boolean isImage;
-    property public final boolean isInMutuallyExclusiveGroup;
     property public final boolean isMergingSemanticsOfDescendants;
-    property public final boolean isObscured;
-    property public final boolean isSelected;
     property public final boolean isSemanticBoundary;
-    property public final boolean isTextField;
-    property public final Boolean? isToggled;
-    property public final String? label;
-    property public final boolean liveRegion;
-    property public final boolean namesRoute;
-    property public final boolean scopesRoute;
-    property public final Float? scrollExtentMax;
-    property public final Float? scrollExtentMin;
-    property public final Float? scrollPosition;
-    property public final String? testTag;
-    property public final androidx.ui.text.style.TextDirection? textDirection;
-    property public final androidx.ui.text.TextSelection? textSelection;
-    property public final String? value;
   }
 
   public final class SemanticsConfigurationKt {
     ctor public SemanticsConfigurationKt();
-  }
-
-  public enum SemanticsFlag {
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag HasCheckedState;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag HasEnabledState;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag HasImplicitScrolling;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag HasToggledState;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsButton;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsChecked;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsEnabled;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsFocused;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsHeader;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsHidden;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsImage;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsInMutuallyExclusiveGroup;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsLiveRegion;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsObscured;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsSelected;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsTextField;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsToggled;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag NamesRoute;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag ScopesRoute;
-    field public static final androidx.ui.core.semantics.SemanticsFlag.Companion! Companion;
-  }
-
-  public static final class SemanticsFlag.Companion {
-    method public java.util.Map<java.lang.Integer,androidx.ui.core.semantics.SemanticsFlag> getValues();
-    property public final java.util.Map<java.lang.Integer,androidx.ui.core.semantics.SemanticsFlag> values;
+    method public static <T> T? getOrNull(androidx.ui.core.semantics.SemanticsConfiguration, androidx.ui.semantics.SemanticsPropertyKey<T> key);
   }
 
   public final class SemanticsHintOverrides {
@@ -517,7 +363,6 @@
     method public androidx.ui.engine.geometry.Rect? getParentPaintClipRect();
     method public androidx.ui.engine.geometry.Rect? getParentSemanticsClipRect();
     method public androidx.ui.engine.geometry.Rect getRect();
-    method public boolean isDifferentFromCurrentSemanticAnnotation(androidx.ui.core.semantics.SemanticsConfiguration config);
     method public boolean isInvisible();
     method public boolean isMergedIntoParent();
     method public boolean isPartOfNodeMerging();
@@ -557,7 +402,26 @@
 
   public final class SemanticsOwner {
     ctor public SemanticsOwner();
-    method public void performAction(int id, androidx.ui.core.semantics.SemanticsActionType<?> action, Object? args = null);
+  }
+
+}
+
+package androidx.ui.internal {
+
+  public final class Unicode {
+    field public static final String ALM = "\u061c";
+    field public static final String FSI = "\u2068";
+    field public static final androidx.ui.internal.Unicode! INSTANCE;
+    field public static final String LRE = "\u202a";
+    field public static final String LRI = "\u2066";
+    field public static final String LRM = "\u200e";
+    field public static final String LRO = "\u202d";
+    field public static final String PDF = "\u202c";
+    field public static final String PDI = "\u2069";
+    field public static final String RLE = "\u202b";
+    field public static final String RLI = "\u2067";
+    field public static final String RLM = "\u200f";
+    field public static final String RLO = "\u202e";
   }
 
 }
diff --git a/ui/ui-platform/api/restricted_1.0.0-alpha01.txt b/ui/ui-platform/api/restricted_1.0.0-alpha01.txt
index 5fb4d01..58b0117 100644
--- a/ui/ui-platform/api/restricted_1.0.0-alpha01.txt
+++ b/ui/ui-platform/api/restricted_1.0.0-alpha01.txt
@@ -1,4 +1,16 @@
 // Signature format: 3.0
+package androidx.ui.autofill {
+
+  public final class AndroidAutofillDebugUtilsKt {
+    ctor public AndroidAutofillDebugUtilsKt();
+  }
+
+  public final class AndroidAutofillKt {
+    ctor public AndroidAutofillKt();
+  }
+
+}
+
 package androidx.ui.core {
 
   public final class AndroidCraneView extends android.view.ViewGroup implements androidx.ui.core.Owner androidx.ui.core.SemanticsTreeProvider {
@@ -6,7 +18,10 @@
     method public androidx.ui.core.PxPosition calculatePosition();
     method public void callDraw(androidx.ui.painting.Canvas canvas, androidx.ui.core.ComponentNode node, androidx.ui.core.PxSize parentSize, androidx.ui.core.DensityReceiver densityReceiver);
     method public java.util.List<androidx.ui.core.SemanticsTreeNode> getAllSemanticNodes();
+    method public androidx.ui.autofill.Autofill? getAutofill();
+    method public androidx.ui.autofill.AutofillTree getAutofillTree();
     method public kotlin.jvm.functions.Function0<kotlin.Unit>? getCommitUnsubscribe();
+    method public kotlin.jvm.functions.Function0<kotlin.Unit> getConfigurationChangeObserver();
     method public androidx.ui.core.Constraints getConstraints();
     method public long getMeasureIteration();
     method public androidx.ui.core.Ref<androidx.ui.core.AndroidCraneView>? getRef();
@@ -24,9 +39,13 @@
     method public void onStartMeasure(androidx.ui.core.LayoutNode layoutNode);
     method public void sendEvent(android.view.MotionEvent event);
     method public void setCommitUnsubscribe(kotlin.jvm.functions.Function0<kotlin.Unit>? p);
+    method public void setConfigurationChangeObserver(kotlin.jvm.functions.Function0<kotlin.Unit> p);
     method public void setConstraints(androidx.ui.core.Constraints p);
     method public void setRef(androidx.ui.core.Ref<androidx.ui.core.AndroidCraneView>? value);
+    property public final androidx.ui.autofill.Autofill? autofill;
+    property public final androidx.ui.autofill.AutofillTree autofillTree;
     property public final kotlin.jvm.functions.Function0<kotlin.Unit>? commitUnsubscribe;
+    property public final kotlin.jvm.functions.Function0<kotlin.Unit> configurationChangeObserver;
     property public final androidx.ui.core.Constraints constraints;
     property public long measureIteration;
     property public final androidx.ui.core.Ref<androidx.ui.core.AndroidCraneView>? ref;
@@ -54,8 +73,8 @@
     method public androidx.ui.core.RepaintBoundaryNode? getRepaintBoundary();
     method public final void setDepth(int p);
     method public final void setOwnerData(Object? p);
-    method public final void visitChildren(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
-    method public final void visitChildrenReverse(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
+    method public final inline void visitChildren(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
+    method public final inline void visitChildrenReverse(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
     property protected androidx.ui.core.LayoutNode? containingLayoutNode;
     property public final int count;
     property public final int depth;
@@ -193,83 +212,33 @@
   public final class RepaintBoundaryNode extends androidx.ui.core.ComponentNode {
     ctor public RepaintBoundaryNode(String? name);
     method public boolean getClipToShape();
+    method public androidx.ui.core.Dp getElevation();
     method public String? getName();
     method public float getOpacity();
     method public androidx.ui.engine.geometry.Shape? getShape();
     method public void setClipToShape(boolean value);
+    method public void setElevation(androidx.ui.core.Dp value);
     method public void setOpacity(float value);
     method public void setShape(androidx.ui.engine.geometry.Shape? value);
     property public final boolean clipToShape;
+    property public final androidx.ui.core.Dp elevation;
     property public final float opacity;
     property public androidx.ui.core.RepaintBoundaryNode? repaintBoundary;
     property public final androidx.ui.engine.geometry.Shape? shape;
   }
 
   public final class SemanticsComponentNode extends androidx.ui.core.ComponentNode {
-    ctor public SemanticsComponentNode(boolean container, boolean explicitChildNodes, Boolean? enabled, Boolean? checked, Boolean? selected, Boolean? button, Boolean? header, Boolean? textField, Boolean? focused, Boolean? inMutuallyExclusiveGroup, Boolean? obscured, Boolean? scopesRoute, Boolean? namesRoute, Boolean? hidden, String? label, String? value, String? hint, androidx.ui.text.style.TextDirection? textDirection, String? testTag, java.util.List<? extends androidx.ui.core.semantics.SemanticsAction<?>> actions);
+    ctor public SemanticsComponentNode(androidx.ui.core.semantics.SemanticsConfiguration semanticsConfiguration, boolean container, boolean explicitChildNodes);
     ctor public SemanticsComponentNode();
-    method public java.util.List<androidx.ui.core.semantics.SemanticsAction<?>> getActions();
-    method public Boolean? getButton();
-    method public Boolean? getChecked();
     method public boolean getContainer();
-    method public Boolean? getEnabled();
     method public boolean getExplicitChildNodes();
-    method public Boolean? getFocused();
-    method public Boolean? getHeader();
-    method public Boolean? getHidden();
-    method public String? getHint();
-    method public Boolean? getInMutuallyExclusiveGroup();
-    method public String? getLabel();
-    method public Boolean? getNamesRoute();
-    method public Boolean? getObscured();
-    method public Boolean? getScopesRoute();
-    method public Boolean? getSelected();
     method public androidx.ui.core.semantics.SemanticsConfiguration getSemanticsConfiguration();
-    method public String? getTestTag();
-    method public androidx.ui.text.style.TextDirection? getTextDirection();
-    method public Boolean? getTextField();
-    method public String? getValue();
-    method public void setActions(java.util.List<? extends androidx.ui.core.semantics.SemanticsAction<?>> p);
-    method public void setButton(Boolean? p);
-    method public void setChecked(Boolean? p);
     method public void setContainer(boolean p);
-    method public void setEnabled(Boolean? p);
     method public void setExplicitChildNodes(boolean p);
-    method public void setFocused(Boolean? p);
-    method public void setHeader(Boolean? p);
-    method public void setHidden(Boolean? p);
-    method public void setHint(String? p);
-    method public void setInMutuallyExclusiveGroup(Boolean? p);
-    method public void setLabel(String? p);
-    method public void setNamesRoute(Boolean? p);
-    method public void setObscured(Boolean? p);
-    method public void setScopesRoute(Boolean? p);
-    method public void setSelected(Boolean? p);
-    method public void setTestTag(String? p);
-    method public void setTextDirection(androidx.ui.text.style.TextDirection? p);
-    method public void setTextField(Boolean? p);
-    method public void setValue(String? p);
-    property public final java.util.List<androidx.ui.core.semantics.SemanticsAction<?>> actions;
-    property public final Boolean? button;
-    property public final Boolean? checked;
+    method public void setSemanticsConfiguration(androidx.ui.core.semantics.SemanticsConfiguration p);
     property public final boolean container;
-    property public final Boolean? enabled;
     property public final boolean explicitChildNodes;
-    property public final Boolean? focused;
-    property public final Boolean? header;
-    property public final Boolean? hidden;
-    property public final String? hint;
-    property public final Boolean? inMutuallyExclusiveGroup;
-    property public final String? label;
-    property public final Boolean? namesRoute;
-    property public final Boolean? obscured;
-    property public final Boolean? scopesRoute;
-    property public final Boolean? selected;
     property public final androidx.ui.core.semantics.SemanticsConfiguration semanticsConfiguration;
-    property public final String? testTag;
-    property public final androidx.ui.text.style.TextDirection? textDirection;
-    property public final Boolean? textField;
-    property public final String? value;
   }
 
   public interface SemanticsTreeNode {
@@ -304,22 +273,6 @@
     method public void sendEvent(android.view.MotionEvent event);
   }
 
-  public final class Unicode {
-    field public static final String ALM = "\u061c";
-    field public static final String FSI = "\u2068";
-    field public static final androidx.ui.core.Unicode! INSTANCE;
-    field public static final String LRE = "\u202a";
-    field public static final String LRI = "\u2066";
-    field public static final String LRM = "\u200e";
-    field public static final String LRO = "\u202d";
-    field public static final String PDF = "\u202c";
-    field public static final String PDI = "\u2069";
-    field public static final String RLE = "\u202b";
-    field public static final String RLI = "\u2067";
-    field public static final String RLM = "\u200f";
-    field public static final String RLO = "\u202e";
-  }
-
 }
 
 package androidx.ui.core.input {
@@ -357,138 +310,31 @@
 
 package androidx.ui.core.semantics {
 
-  public final class SemanticsConfiguration {
+  public final class SemanticsConfiguration implements java.lang.Iterable<java.util.Map.Entry<? extends androidx.ui.semantics.SemanticsPropertyKey<?>,?>> kotlin.jvm.internal.markers.KMappedMarker androidx.ui.semantics.SemanticsPropertyReceiver {
     ctor public SemanticsConfiguration();
+    method public operator <T> boolean contains(androidx.ui.semantics.SemanticsPropertyKey<T> key);
     method public androidx.ui.core.semantics.SemanticsConfiguration copy();
-    method public java.util.List<androidx.ui.core.semantics.SemanticsAction<?>> getActions();
+    method public operator <T> T! get(androidx.ui.semantics.SemanticsPropertyKey<T> key);
     method public boolean getExplicitChildNodes();
     method public boolean getHasBeenAnnotated();
-    method public boolean getHasImplicitScrolling();
-    method public String? getHint();
-    method public androidx.ui.core.semantics.SemanticsHintOverrides? getHintOverrides();
-    method public String? getLabel();
-    method public boolean getLiveRegion();
-    method public boolean getNamesRoute();
-    method public boolean getScopesRoute();
-    method public Float? getScrollExtentMax();
-    method public Float? getScrollExtentMin();
-    method public Float? getScrollPosition();
-    method public String? getTestTag();
-    method public androidx.ui.text.style.TextDirection? getTextDirection();
-    method public androidx.ui.text.TextSelection? getTextSelection();
-    method public String? getValue();
-    method public boolean isBlockingSemanticsOfPreviouslyPaintedNodes();
-    method public boolean isButton();
-    method public Boolean? isChecked();
-    method public boolean isCompatibleWith(androidx.ui.core.semantics.SemanticsConfiguration? other);
-    method public Boolean? isEnabled();
-    method public boolean isFocused();
-    method public boolean isHeader();
-    method public boolean isHidden();
-    method public boolean isImage();
-    method public boolean isInMutuallyExclusiveGroup();
+    method public <T> T! getOrElse(androidx.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public <T> T? getOrElseNullable(androidx.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public boolean isMergingSemanticsOfDescendants();
-    method public boolean isObscured();
-    method public boolean isSelected();
     method public boolean isSemanticBoundary();
-    method public boolean isTextField();
-    method public Boolean? isToggled();
-    method public void setActions(java.util.List<? extends androidx.ui.core.semantics.SemanticsAction<?>> value);
-    method public void setBlockingSemanticsOfPreviouslyPaintedNodes(boolean p);
-    method public void setButton(boolean p);
-    method public void setChecked(Boolean? value);
-    method public void setEnabled(Boolean? value);
+    method public java.util.Iterator<java.util.Map.Entry<androidx.ui.semantics.SemanticsPropertyKey<?>,java.lang.Object>> iterator();
+    method public <T> void set(androidx.ui.semantics.SemanticsPropertyKey<T> key, T? value);
     method public void setExplicitChildNodes(boolean p);
-    method public void setFocused(boolean p);
-    method public void setHasBeenAnnotated(boolean p);
-    method public void setHasImplicitScrolling(boolean p);
-    method public void setHeader(boolean p);
-    method public void setHidden(boolean p);
-    method public void setHint(String? p);
-    method public void setHintOverrides(androidx.ui.core.semantics.SemanticsHintOverrides? p);
-    method public void setImage(boolean p);
-    method public void setInMutuallyExclusiveGroup(boolean p);
-    method public void setLabel(String? p);
-    method public void setLiveRegion(boolean p);
     method public void setMergingSemanticsOfDescendants(boolean value);
-    method public void setNamesRoute(boolean p);
-    method public void setObscured(boolean p);
-    method public void setScopesRoute(boolean p);
-    method public void setScrollExtentMax(Float? p);
-    method public void setScrollExtentMin(Float? p);
-    method public void setScrollPosition(Float? p);
-    method public void setSelected(boolean p);
     method public void setSemanticBoundary(boolean value);
-    method public void setTestTag(String? p);
-    method public void setTextDirection(androidx.ui.text.style.TextDirection? p);
-    method public void setTextField(boolean p);
-    method public void setTextSelection(androidx.ui.text.TextSelection? p);
-    method public void setToggled(Boolean? value);
-    method public void setValue(String? p);
-    property public final java.util.List<androidx.ui.core.semantics.SemanticsAction<?>> actions;
     property public final boolean explicitChildNodes;
     property public final boolean hasBeenAnnotated;
-    property public final boolean hasImplicitScrolling;
-    property public final String? hint;
-    property public final androidx.ui.core.semantics.SemanticsHintOverrides? hintOverrides;
-    property public final boolean isBlockingSemanticsOfPreviouslyPaintedNodes;
-    property public final boolean isButton;
-    property public final Boolean? isChecked;
-    property public final Boolean? isEnabled;
-    property public final boolean isFocused;
-    property public final boolean isHeader;
-    property public final boolean isHidden;
-    property public final boolean isImage;
-    property public final boolean isInMutuallyExclusiveGroup;
     property public final boolean isMergingSemanticsOfDescendants;
-    property public final boolean isObscured;
-    property public final boolean isSelected;
     property public final boolean isSemanticBoundary;
-    property public final boolean isTextField;
-    property public final Boolean? isToggled;
-    property public final String? label;
-    property public final boolean liveRegion;
-    property public final boolean namesRoute;
-    property public final boolean scopesRoute;
-    property public final Float? scrollExtentMax;
-    property public final Float? scrollExtentMin;
-    property public final Float? scrollPosition;
-    property public final String? testTag;
-    property public final androidx.ui.text.style.TextDirection? textDirection;
-    property public final androidx.ui.text.TextSelection? textSelection;
-    property public final String? value;
   }
 
   public final class SemanticsConfigurationKt {
     ctor public SemanticsConfigurationKt();
-  }
-
-  public enum SemanticsFlag {
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag HasCheckedState;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag HasEnabledState;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag HasImplicitScrolling;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag HasToggledState;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsButton;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsChecked;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsEnabled;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsFocused;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsHeader;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsHidden;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsImage;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsInMutuallyExclusiveGroup;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsLiveRegion;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsObscured;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsSelected;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsTextField;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsToggled;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag NamesRoute;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag ScopesRoute;
-    field public static final androidx.ui.core.semantics.SemanticsFlag.Companion! Companion;
-  }
-
-  public static final class SemanticsFlag.Companion {
-    method public java.util.Map<java.lang.Integer,androidx.ui.core.semantics.SemanticsFlag> getValues();
-    property public final java.util.Map<java.lang.Integer,androidx.ui.core.semantics.SemanticsFlag> values;
+    method public static <T> T? getOrNull(androidx.ui.core.semantics.SemanticsConfiguration, androidx.ui.semantics.SemanticsPropertyKey<T> key);
   }
 
   public final class SemanticsHintOverrides {
@@ -517,7 +363,6 @@
     method public androidx.ui.engine.geometry.Rect? getParentPaintClipRect();
     method public androidx.ui.engine.geometry.Rect? getParentSemanticsClipRect();
     method public androidx.ui.engine.geometry.Rect getRect();
-    method public boolean isDifferentFromCurrentSemanticAnnotation(androidx.ui.core.semantics.SemanticsConfiguration config);
     method public boolean isInvisible();
     method public boolean isMergedIntoParent();
     method public boolean isPartOfNodeMerging();
@@ -557,7 +402,6 @@
 
   public final class SemanticsOwner {
     ctor public SemanticsOwner();
-    method public void performAction(int id, androidx.ui.core.semantics.SemanticsActionType<?> action, Object? args = null);
   }
 
 }
@@ -571,3 +415,23 @@
 
 }
 
+package androidx.ui.internal {
+
+  public final class Unicode {
+    field public static final String ALM = "\u061c";
+    field public static final String FSI = "\u2068";
+    field public static final androidx.ui.internal.Unicode! INSTANCE;
+    field public static final String LRE = "\u202a";
+    field public static final String LRI = "\u2066";
+    field public static final String LRM = "\u200e";
+    field public static final String LRO = "\u202d";
+    field public static final String PDF = "\u202c";
+    field public static final String PDI = "\u2069";
+    field public static final String RLE = "\u202b";
+    field public static final String RLI = "\u2067";
+    field public static final String RLM = "\u200f";
+    field public static final String RLO = "\u202e";
+  }
+
+}
+
diff --git a/ui/ui-platform/api/restricted_current.txt b/ui/ui-platform/api/restricted_current.txt
index 5fb4d01..58b0117 100644
--- a/ui/ui-platform/api/restricted_current.txt
+++ b/ui/ui-platform/api/restricted_current.txt
@@ -1,4 +1,16 @@
 // Signature format: 3.0
+package androidx.ui.autofill {
+
+  public final class AndroidAutofillDebugUtilsKt {
+    ctor public AndroidAutofillDebugUtilsKt();
+  }
+
+  public final class AndroidAutofillKt {
+    ctor public AndroidAutofillKt();
+  }
+
+}
+
 package androidx.ui.core {
 
   public final class AndroidCraneView extends android.view.ViewGroup implements androidx.ui.core.Owner androidx.ui.core.SemanticsTreeProvider {
@@ -6,7 +18,10 @@
     method public androidx.ui.core.PxPosition calculatePosition();
     method public void callDraw(androidx.ui.painting.Canvas canvas, androidx.ui.core.ComponentNode node, androidx.ui.core.PxSize parentSize, androidx.ui.core.DensityReceiver densityReceiver);
     method public java.util.List<androidx.ui.core.SemanticsTreeNode> getAllSemanticNodes();
+    method public androidx.ui.autofill.Autofill? getAutofill();
+    method public androidx.ui.autofill.AutofillTree getAutofillTree();
     method public kotlin.jvm.functions.Function0<kotlin.Unit>? getCommitUnsubscribe();
+    method public kotlin.jvm.functions.Function0<kotlin.Unit> getConfigurationChangeObserver();
     method public androidx.ui.core.Constraints getConstraints();
     method public long getMeasureIteration();
     method public androidx.ui.core.Ref<androidx.ui.core.AndroidCraneView>? getRef();
@@ -24,9 +39,13 @@
     method public void onStartMeasure(androidx.ui.core.LayoutNode layoutNode);
     method public void sendEvent(android.view.MotionEvent event);
     method public void setCommitUnsubscribe(kotlin.jvm.functions.Function0<kotlin.Unit>? p);
+    method public void setConfigurationChangeObserver(kotlin.jvm.functions.Function0<kotlin.Unit> p);
     method public void setConstraints(androidx.ui.core.Constraints p);
     method public void setRef(androidx.ui.core.Ref<androidx.ui.core.AndroidCraneView>? value);
+    property public final androidx.ui.autofill.Autofill? autofill;
+    property public final androidx.ui.autofill.AutofillTree autofillTree;
     property public final kotlin.jvm.functions.Function0<kotlin.Unit>? commitUnsubscribe;
+    property public final kotlin.jvm.functions.Function0<kotlin.Unit> configurationChangeObserver;
     property public final androidx.ui.core.Constraints constraints;
     property public long measureIteration;
     property public final androidx.ui.core.Ref<androidx.ui.core.AndroidCraneView>? ref;
@@ -54,8 +73,8 @@
     method public androidx.ui.core.RepaintBoundaryNode? getRepaintBoundary();
     method public final void setDepth(int p);
     method public final void setOwnerData(Object? p);
-    method public final void visitChildren(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
-    method public final void visitChildrenReverse(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
+    method public final inline void visitChildren(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
+    method public final inline void visitChildrenReverse(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
     property protected androidx.ui.core.LayoutNode? containingLayoutNode;
     property public final int count;
     property public final int depth;
@@ -193,83 +212,33 @@
   public final class RepaintBoundaryNode extends androidx.ui.core.ComponentNode {
     ctor public RepaintBoundaryNode(String? name);
     method public boolean getClipToShape();
+    method public androidx.ui.core.Dp getElevation();
     method public String? getName();
     method public float getOpacity();
     method public androidx.ui.engine.geometry.Shape? getShape();
     method public void setClipToShape(boolean value);
+    method public void setElevation(androidx.ui.core.Dp value);
     method public void setOpacity(float value);
     method public void setShape(androidx.ui.engine.geometry.Shape? value);
     property public final boolean clipToShape;
+    property public final androidx.ui.core.Dp elevation;
     property public final float opacity;
     property public androidx.ui.core.RepaintBoundaryNode? repaintBoundary;
     property public final androidx.ui.engine.geometry.Shape? shape;
   }
 
   public final class SemanticsComponentNode extends androidx.ui.core.ComponentNode {
-    ctor public SemanticsComponentNode(boolean container, boolean explicitChildNodes, Boolean? enabled, Boolean? checked, Boolean? selected, Boolean? button, Boolean? header, Boolean? textField, Boolean? focused, Boolean? inMutuallyExclusiveGroup, Boolean? obscured, Boolean? scopesRoute, Boolean? namesRoute, Boolean? hidden, String? label, String? value, String? hint, androidx.ui.text.style.TextDirection? textDirection, String? testTag, java.util.List<? extends androidx.ui.core.semantics.SemanticsAction<?>> actions);
+    ctor public SemanticsComponentNode(androidx.ui.core.semantics.SemanticsConfiguration semanticsConfiguration, boolean container, boolean explicitChildNodes);
     ctor public SemanticsComponentNode();
-    method public java.util.List<androidx.ui.core.semantics.SemanticsAction<?>> getActions();
-    method public Boolean? getButton();
-    method public Boolean? getChecked();
     method public boolean getContainer();
-    method public Boolean? getEnabled();
     method public boolean getExplicitChildNodes();
-    method public Boolean? getFocused();
-    method public Boolean? getHeader();
-    method public Boolean? getHidden();
-    method public String? getHint();
-    method public Boolean? getInMutuallyExclusiveGroup();
-    method public String? getLabel();
-    method public Boolean? getNamesRoute();
-    method public Boolean? getObscured();
-    method public Boolean? getScopesRoute();
-    method public Boolean? getSelected();
     method public androidx.ui.core.semantics.SemanticsConfiguration getSemanticsConfiguration();
-    method public String? getTestTag();
-    method public androidx.ui.text.style.TextDirection? getTextDirection();
-    method public Boolean? getTextField();
-    method public String? getValue();
-    method public void setActions(java.util.List<? extends androidx.ui.core.semantics.SemanticsAction<?>> p);
-    method public void setButton(Boolean? p);
-    method public void setChecked(Boolean? p);
     method public void setContainer(boolean p);
-    method public void setEnabled(Boolean? p);
     method public void setExplicitChildNodes(boolean p);
-    method public void setFocused(Boolean? p);
-    method public void setHeader(Boolean? p);
-    method public void setHidden(Boolean? p);
-    method public void setHint(String? p);
-    method public void setInMutuallyExclusiveGroup(Boolean? p);
-    method public void setLabel(String? p);
-    method public void setNamesRoute(Boolean? p);
-    method public void setObscured(Boolean? p);
-    method public void setScopesRoute(Boolean? p);
-    method public void setSelected(Boolean? p);
-    method public void setTestTag(String? p);
-    method public void setTextDirection(androidx.ui.text.style.TextDirection? p);
-    method public void setTextField(Boolean? p);
-    method public void setValue(String? p);
-    property public final java.util.List<androidx.ui.core.semantics.SemanticsAction<?>> actions;
-    property public final Boolean? button;
-    property public final Boolean? checked;
+    method public void setSemanticsConfiguration(androidx.ui.core.semantics.SemanticsConfiguration p);
     property public final boolean container;
-    property public final Boolean? enabled;
     property public final boolean explicitChildNodes;
-    property public final Boolean? focused;
-    property public final Boolean? header;
-    property public final Boolean? hidden;
-    property public final String? hint;
-    property public final Boolean? inMutuallyExclusiveGroup;
-    property public final String? label;
-    property public final Boolean? namesRoute;
-    property public final Boolean? obscured;
-    property public final Boolean? scopesRoute;
-    property public final Boolean? selected;
     property public final androidx.ui.core.semantics.SemanticsConfiguration semanticsConfiguration;
-    property public final String? testTag;
-    property public final androidx.ui.text.style.TextDirection? textDirection;
-    property public final Boolean? textField;
-    property public final String? value;
   }
 
   public interface SemanticsTreeNode {
@@ -304,22 +273,6 @@
     method public void sendEvent(android.view.MotionEvent event);
   }
 
-  public final class Unicode {
-    field public static final String ALM = "\u061c";
-    field public static final String FSI = "\u2068";
-    field public static final androidx.ui.core.Unicode! INSTANCE;
-    field public static final String LRE = "\u202a";
-    field public static final String LRI = "\u2066";
-    field public static final String LRM = "\u200e";
-    field public static final String LRO = "\u202d";
-    field public static final String PDF = "\u202c";
-    field public static final String PDI = "\u2069";
-    field public static final String RLE = "\u202b";
-    field public static final String RLI = "\u2067";
-    field public static final String RLM = "\u200f";
-    field public static final String RLO = "\u202e";
-  }
-
 }
 
 package androidx.ui.core.input {
@@ -357,138 +310,31 @@
 
 package androidx.ui.core.semantics {
 
-  public final class SemanticsConfiguration {
+  public final class SemanticsConfiguration implements java.lang.Iterable<java.util.Map.Entry<? extends androidx.ui.semantics.SemanticsPropertyKey<?>,?>> kotlin.jvm.internal.markers.KMappedMarker androidx.ui.semantics.SemanticsPropertyReceiver {
     ctor public SemanticsConfiguration();
+    method public operator <T> boolean contains(androidx.ui.semantics.SemanticsPropertyKey<T> key);
     method public androidx.ui.core.semantics.SemanticsConfiguration copy();
-    method public java.util.List<androidx.ui.core.semantics.SemanticsAction<?>> getActions();
+    method public operator <T> T! get(androidx.ui.semantics.SemanticsPropertyKey<T> key);
     method public boolean getExplicitChildNodes();
     method public boolean getHasBeenAnnotated();
-    method public boolean getHasImplicitScrolling();
-    method public String? getHint();
-    method public androidx.ui.core.semantics.SemanticsHintOverrides? getHintOverrides();
-    method public String? getLabel();
-    method public boolean getLiveRegion();
-    method public boolean getNamesRoute();
-    method public boolean getScopesRoute();
-    method public Float? getScrollExtentMax();
-    method public Float? getScrollExtentMin();
-    method public Float? getScrollPosition();
-    method public String? getTestTag();
-    method public androidx.ui.text.style.TextDirection? getTextDirection();
-    method public androidx.ui.text.TextSelection? getTextSelection();
-    method public String? getValue();
-    method public boolean isBlockingSemanticsOfPreviouslyPaintedNodes();
-    method public boolean isButton();
-    method public Boolean? isChecked();
-    method public boolean isCompatibleWith(androidx.ui.core.semantics.SemanticsConfiguration? other);
-    method public Boolean? isEnabled();
-    method public boolean isFocused();
-    method public boolean isHeader();
-    method public boolean isHidden();
-    method public boolean isImage();
-    method public boolean isInMutuallyExclusiveGroup();
+    method public <T> T! getOrElse(androidx.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public <T> T? getOrElseNullable(androidx.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public boolean isMergingSemanticsOfDescendants();
-    method public boolean isObscured();
-    method public boolean isSelected();
     method public boolean isSemanticBoundary();
-    method public boolean isTextField();
-    method public Boolean? isToggled();
-    method public void setActions(java.util.List<? extends androidx.ui.core.semantics.SemanticsAction<?>> value);
-    method public void setBlockingSemanticsOfPreviouslyPaintedNodes(boolean p);
-    method public void setButton(boolean p);
-    method public void setChecked(Boolean? value);
-    method public void setEnabled(Boolean? value);
+    method public java.util.Iterator<java.util.Map.Entry<androidx.ui.semantics.SemanticsPropertyKey<?>,java.lang.Object>> iterator();
+    method public <T> void set(androidx.ui.semantics.SemanticsPropertyKey<T> key, T? value);
     method public void setExplicitChildNodes(boolean p);
-    method public void setFocused(boolean p);
-    method public void setHasBeenAnnotated(boolean p);
-    method public void setHasImplicitScrolling(boolean p);
-    method public void setHeader(boolean p);
-    method public void setHidden(boolean p);
-    method public void setHint(String? p);
-    method public void setHintOverrides(androidx.ui.core.semantics.SemanticsHintOverrides? p);
-    method public void setImage(boolean p);
-    method public void setInMutuallyExclusiveGroup(boolean p);
-    method public void setLabel(String? p);
-    method public void setLiveRegion(boolean p);
     method public void setMergingSemanticsOfDescendants(boolean value);
-    method public void setNamesRoute(boolean p);
-    method public void setObscured(boolean p);
-    method public void setScopesRoute(boolean p);
-    method public void setScrollExtentMax(Float? p);
-    method public void setScrollExtentMin(Float? p);
-    method public void setScrollPosition(Float? p);
-    method public void setSelected(boolean p);
     method public void setSemanticBoundary(boolean value);
-    method public void setTestTag(String? p);
-    method public void setTextDirection(androidx.ui.text.style.TextDirection? p);
-    method public void setTextField(boolean p);
-    method public void setTextSelection(androidx.ui.text.TextSelection? p);
-    method public void setToggled(Boolean? value);
-    method public void setValue(String? p);
-    property public final java.util.List<androidx.ui.core.semantics.SemanticsAction<?>> actions;
     property public final boolean explicitChildNodes;
     property public final boolean hasBeenAnnotated;
-    property public final boolean hasImplicitScrolling;
-    property public final String? hint;
-    property public final androidx.ui.core.semantics.SemanticsHintOverrides? hintOverrides;
-    property public final boolean isBlockingSemanticsOfPreviouslyPaintedNodes;
-    property public final boolean isButton;
-    property public final Boolean? isChecked;
-    property public final Boolean? isEnabled;
-    property public final boolean isFocused;
-    property public final boolean isHeader;
-    property public final boolean isHidden;
-    property public final boolean isImage;
-    property public final boolean isInMutuallyExclusiveGroup;
     property public final boolean isMergingSemanticsOfDescendants;
-    property public final boolean isObscured;
-    property public final boolean isSelected;
     property public final boolean isSemanticBoundary;
-    property public final boolean isTextField;
-    property public final Boolean? isToggled;
-    property public final String? label;
-    property public final boolean liveRegion;
-    property public final boolean namesRoute;
-    property public final boolean scopesRoute;
-    property public final Float? scrollExtentMax;
-    property public final Float? scrollExtentMin;
-    property public final Float? scrollPosition;
-    property public final String? testTag;
-    property public final androidx.ui.text.style.TextDirection? textDirection;
-    property public final androidx.ui.text.TextSelection? textSelection;
-    property public final String? value;
   }
 
   public final class SemanticsConfigurationKt {
     ctor public SemanticsConfigurationKt();
-  }
-
-  public enum SemanticsFlag {
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag HasCheckedState;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag HasEnabledState;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag HasImplicitScrolling;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag HasToggledState;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsButton;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsChecked;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsEnabled;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsFocused;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsHeader;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsHidden;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsImage;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsInMutuallyExclusiveGroup;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsLiveRegion;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsObscured;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsSelected;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsTextField;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag IsToggled;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag NamesRoute;
-    enum_constant public static final androidx.ui.core.semantics.SemanticsFlag ScopesRoute;
-    field public static final androidx.ui.core.semantics.SemanticsFlag.Companion! Companion;
-  }
-
-  public static final class SemanticsFlag.Companion {
-    method public java.util.Map<java.lang.Integer,androidx.ui.core.semantics.SemanticsFlag> getValues();
-    property public final java.util.Map<java.lang.Integer,androidx.ui.core.semantics.SemanticsFlag> values;
+    method public static <T> T? getOrNull(androidx.ui.core.semantics.SemanticsConfiguration, androidx.ui.semantics.SemanticsPropertyKey<T> key);
   }
 
   public final class SemanticsHintOverrides {
@@ -517,7 +363,6 @@
     method public androidx.ui.engine.geometry.Rect? getParentPaintClipRect();
     method public androidx.ui.engine.geometry.Rect? getParentSemanticsClipRect();
     method public androidx.ui.engine.geometry.Rect getRect();
-    method public boolean isDifferentFromCurrentSemanticAnnotation(androidx.ui.core.semantics.SemanticsConfiguration config);
     method public boolean isInvisible();
     method public boolean isMergedIntoParent();
     method public boolean isPartOfNodeMerging();
@@ -557,7 +402,6 @@
 
   public final class SemanticsOwner {
     ctor public SemanticsOwner();
-    method public void performAction(int id, androidx.ui.core.semantics.SemanticsActionType<?> action, Object? args = null);
   }
 
 }
@@ -571,3 +415,23 @@
 
 }
 
+package androidx.ui.internal {
+
+  public final class Unicode {
+    field public static final String ALM = "\u061c";
+    field public static final String FSI = "\u2068";
+    field public static final androidx.ui.internal.Unicode! INSTANCE;
+    field public static final String LRE = "\u202a";
+    field public static final String LRI = "\u2066";
+    field public static final String LRM = "\u200e";
+    field public static final String LRO = "\u202d";
+    field public static final String PDF = "\u202c";
+    field public static final String PDI = "\u2069";
+    field public static final String RLE = "\u202b";
+    field public static final String RLI = "\u2067";
+    field public static final String RLM = "\u200f";
+    field public static final String RLO = "\u202e";
+  }
+
+}
+
diff --git a/ui/ui-platform/src/main/java/androidx/ui/autofill/AndroidAutofill.kt b/ui/ui-platform/src/main/java/androidx/ui/autofill/AndroidAutofill.kt
new file mode 100644
index 0000000..ab83357
--- /dev/null
+++ b/ui/ui-platform/src/main/java/androidx/ui/autofill/AndroidAutofill.kt
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2019 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.ui.autofill
+
+import android.os.Build
+import android.util.Log
+import android.util.SparseArray
+import android.view.View
+import android.view.ViewStructure
+import android.view.autofill.AutofillManager
+import android.view.autofill.AutofillValue
+import androidx.annotation.RequiresApi
+
+/**
+ * Autofill implementation for Android.
+ *
+ * @param view The parent compose view.
+ * @param autofillTree The autofill tree. This will be replaced by a semantic tree (b/138604305).
+ */
+@RequiresApi(Build.VERSION_CODES.O)
+internal class AndroidAutofill(val view: View, val autofillTree: AutofillTree) : Autofill {
+
+    val autofillManager = view.context.getSystemService(AutofillManager::class.java)
+        ?: error("Autofill service could not be located.")
+
+    init { view.importantForAutofill = View.IMPORTANT_FOR_AUTOFILL_YES }
+
+    override fun requestAutofillForNode(autofillNode: AutofillNode) {
+        // TODO(b/138731416): Find out what happens when notifyViewEntered() is called multiple times
+        // before calling notifyViewExited().
+        autofillManager.notifyViewEntered(
+            view,
+            autofillNode.id,
+            autofillNode.boundingBox ?: error("requestAutofill called before onChildPositioned()")
+        )
+    }
+
+    override fun cancelAutofillForNode(autofillNode: AutofillNode) {
+        autofillManager.notifyViewExited(view, autofillNode.id)
+    }
+}
+
+/**
+ * Populates the view structure with autofill information.
+ *
+ * @param root A reference to the view structure of the parent compose view.
+ *
+ * This function populates the view structure using the information in the { AutofillTree }.
+ */
+@RequiresApi(Build.VERSION_CODES.O)
+internal fun AndroidAutofill.populateViewStructure(root: ViewStructure) {
+
+    // Add child nodes. The function returns the index to the first item.
+    var index = root.addChildCount(autofillTree.children.count())
+
+    for ((id, autofillNode) in autofillTree.children) {
+        root.newChild(index)?.apply {
+            setAutofillId(root.autofillId!!, id)
+            setId(id, view.context.packageName, null, null)
+            setAutofillType(View.AUTOFILL_TYPE_TEXT)
+            setAutofillHints(autofillNode.autofillTypes.map {
+                when (it) {
+                    AutofillType.Name -> View.AUTOFILL_HINT_NAME
+                    AutofillType.EmailAddress -> View.AUTOFILL_HINT_EMAIL_ADDRESS
+                    else -> error("Unsupported autofill type")
+                }
+            }.toTypedArray())
+
+            if (autofillNode.boundingBox == null) {
+                // Do we need an exception here? warning? silently ignore? If the boundingbox is
+                // null, the autofill overlay will not be shown.
+                Log.w(
+                    "Autofill Warning",
+                    """Bounding box not set. 
+                        Did you call perform autofillTree before the component was positioned? """
+                )
+            }
+            autofillNode.boundingBox?.run { setDimens(left, top, 0, 0, width(), height()) }
+        }
+        index++
+    }
+}
+
+/**
+ * Triggers onFill() in response to a request from the autofill framework.
+ */
+@RequiresApi(Build.VERSION_CODES.O)
+internal fun AndroidAutofill.performAutofill(values: SparseArray<AutofillValue>) {
+    for (index in 0 until values.size()) {
+        val itemId = values.keyAt(index)
+        val value = values[itemId]
+        when {
+            value.isText -> autofillTree.performAutofill(itemId, value.textValue.toString())
+            value.isDate -> TODO("b/138604541: Add onFill() callback for date")
+            value.isList -> TODO("b/138604541: Add onFill() callback for list")
+            value.isToggle -> TODO("b/138604541:  Add onFill() callback for toggle")
+        }
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-platform/src/main/java/androidx/ui/autofill/AndroidAutofillDebugUtils.kt b/ui/ui-platform/src/main/java/androidx/ui/autofill/AndroidAutofillDebugUtils.kt
new file mode 100644
index 0000000..f4d89f3
--- /dev/null
+++ b/ui/ui-platform/src/main/java/androidx/ui/autofill/AndroidAutofillDebugUtils.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2019 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.ui.autofill
+
+import android.os.Build
+import android.util.Log
+import android.view.autofill.AutofillManager
+import androidx.annotation.RequiresApi
+import androidx.compose.View
+
+/**
+ * Autofill Manager callback.
+ *
+ * This callback is called when we receive autofill events. It adds some logs that can be useful
+ * for debug purposes.
+ */
+private val autofillCallback =
+    @RequiresApi(Build.VERSION_CODES.O)
+    object : AutofillManager.AutofillCallback() {
+        override fun onAutofillEvent(view: View, virtualId: Int, event: Int) {
+            super.onAutofillEvent(view, virtualId, event)
+            Log.d(
+                "Autofill Status",
+                when (event) {
+                    EVENT_INPUT_SHOWN -> "Autofill popup was shown."
+                    EVENT_INPUT_HIDDEN -> "Autofill popup was hidden."
+                    EVENT_INPUT_UNAVAILABLE -> """
+                        |Autofill popup isn't shown because autofill is not available.
+                        |
+                        |Did you set up autofill?
+                        |1. Go to Settings > System > Languages&input > Advanced > Autofill Service
+                        |2. Pick a service
+                        |
+                        |Did you add an account?
+                        |1. Go to Settings > System > Languages&input > Advanced
+                        |2. Click on the settings icon next to the Autofill Service
+                        |3. Add your account
+                        """.trimMargin()
+                    else -> "Unknown status event."
+                }
+            )
+        }
+    }
+
+/**
+ * Registers the autofill debug callback.
+ */
+@RequiresApi(Build.VERSION_CODES.O)
+internal fun AndroidAutofill.registerCallback() {
+    autofillManager.registerCallback(autofillCallback)
+}
+
+/**
+ * Unregisters the autofill debug callback.
+ */
+@RequiresApi(Build.VERSION_CODES.O)
+internal fun AndroidAutofill.unregisterCallback() {
+    autofillManager.unregisterCallback(autofillCallback)
+}
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/AndroidOwner.kt b/ui/ui-platform/src/main/java/androidx/ui/core/AndroidOwner.kt
index 7709a34..cce0ade 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/AndroidOwner.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/AndroidOwner.kt
@@ -17,14 +17,18 @@
 
 import android.annotation.TargetApi
 import android.content.Context
+import android.content.res.Configuration
 import android.graphics.RenderNode
 import android.os.Build
 import android.os.Looper
+import android.util.SparseArray
 import android.view.Choreographer
 import android.view.MotionEvent
 import android.view.View
 import android.view.ViewGroup
 import android.view.ViewOutlineProvider
+import android.view.ViewStructure
+import android.view.autofill.AutofillValue
 import android.view.inputmethod.EditorInfo
 import android.view.inputmethod.InputConnection
 import androidx.annotation.RestrictTo
@@ -46,6 +50,13 @@
 import kotlin.math.roundToInt
 import java.util.TreeSet
 import androidx.compose.trace
+import androidx.ui.autofill.AndroidAutofill
+import androidx.ui.autofill.Autofill
+import androidx.ui.autofill.AutofillTree
+import androidx.ui.autofill.performAutofill
+import androidx.ui.autofill.populateViewStructure
+import androidx.ui.autofill.registerCallback
+import androidx.ui.autofill.unregisterCallback
 
 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
 class AndroidCraneView constructor(context: Context)
@@ -64,6 +75,10 @@
     // Map from model to LayoutNodes that *only* need layout and not measure
     private val relayoutOnly = ObserverMap<Any, LayoutNode>()
 
+    // TODO: Replace with SemanticsTree.
+    //  This is a temporary hack until we have a semantics tree implemented.
+    val autofillTree = AutofillTree()
+
     // RepaintBoundaryNodes that have had their boundary changed. When using Views,
     // the size/position of a View should change during layout, so this list
     // is kept separate from dirtyRepaintBoundaryNodes.
@@ -85,6 +100,14 @@
     // Used for tracking which nodes a frame read is applied to
     internal var currentNode: ComponentNode? = null
 
+    // Used for updating the ConfigurationAmbient when configuration changes - consume the
+    // configuration ambient instead of changing this observer if you are writing a component that
+    // adapts to configuration changes.
+    var configurationChangeObserver: () -> Unit = {}
+
+    private val _autofill = if (autofillSupported()) AndroidAutofill(this, autofillTree) else null
+    val autofill: Autofill? get() = _autofill
+
     override var measureIteration: Long = 1L
         private set
 
@@ -123,6 +146,9 @@
 
     var commitUnsubscribe: (() -> Unit)? = null
 
+    private val elevationCompat: ElevationCompat? =
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) null else ElevationCompat()
+
     init {
         setWillNotDraw(false)
         isFocusable = true
@@ -398,7 +424,17 @@
                     currentNode = previousNode
                 }
                 is RepaintBoundaryNode -> {
-                    node.container.callDraw(canvas)
+                    if (node.elevation > 0.dp) {
+                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+                            canvas.nativeCanvas.enableZ()
+                            node.container.callDraw(canvas)
+                            canvas.nativeCanvas.disableZ()
+                        } else {
+                            elevationCompat!!.drawWithZ(canvas, node)
+                        }
+                    } else {
+                        node.container.callDraw(canvas)
+                    }
                 }
                 is LayoutNode -> {
                     if (node.visible) {
@@ -423,6 +459,18 @@
         }
     }
 
+    override fun drawChild(
+        canvas: android.graphics.Canvas,
+        child: View,
+        drawingTime: Long
+    ): Boolean {
+        val elevationCompat = this.elevationCompat
+        if (elevationCompat != null && elevationCompat.handleDrawChild(canvas, child)) {
+            return false
+        }
+        return super.drawChild(canvas, child, drawingTime)
+    }
+
     internal fun drawChild(canvas: Canvas, view: View, drawingTime: Long) {
         super.drawChild(canvas.nativeCanvas, view, drawingTime)
     }
@@ -465,15 +513,25 @@
     override fun onAttachedToWindow() {
         super.onAttachedToWindow()
         commitUnsubscribe = registerCommitObserver(commitObserver)
+        ifDebug { if (autofillSupported()) _autofill?.registerCallback() }
         root.attach(this)
     }
 
     override fun onDetachedFromWindow() {
         super.onDetachedFromWindow()
         commitUnsubscribe?.invoke()
+        ifDebug { if (autofillSupported()) _autofill?.unregisterCallback() }
         root.detach()
     }
 
+    override fun onProvideAutofillVirtualStructure(structure: ViewStructure?, flags: Int) {
+        if (autofillSupported() && structure != null) _autofill?.populateViewStructure(structure)
+    }
+
+    override fun autofill(values: SparseArray<AutofillValue>) {
+        if (autofillSupported()) _autofill?.performAutofill(values)
+    }
+
     override fun onTouchEvent(event: MotionEvent): Boolean {
         trace("AndroidOwner:onTouch") {
             pointerInputEventProcessor.process(event.toPointerInputEvent())
@@ -524,6 +582,11 @@
         return PxPosition(positionArray[0].ipx, positionArray[1].ipx)
     }
 
+    override fun onConfigurationChanged(newConfig: Configuration?) {
+        super.onConfigurationChanged(newConfig)
+        configurationChangeObserver()
+    }
+
     private fun callMeasure(constraints: Constraints) {
         var maxWidth = 0.ipx
         var maxHeight = 0.ipx
@@ -561,6 +624,54 @@
             }
         }
     }
+
+    private fun autofillSupported() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
+
+    /**
+     * Compatible version of Canvas.enableZ()/disableZ().
+     *
+     * On Q we can just do:
+     * canvas.enableZ()
+     * node.container.callDraw(canvas)
+     * canvas.disableZ()
+     *
+     * But on older versions there is no such methods, but ViewGroup will call
+     * them internally inside dispatchDraw before calling the drawChild method.
+     * We can use this mechanism for our need just to have Canvas with Z enabled.
+     *
+     * So if we add a fake view, then call dispatchDraw manually, remember that
+     * if wasn't called by system(fakeDrawPass) and then when we handle next
+     * drawChild callback we would have a Canvas with z enabled. As we check for
+     * the fakeDrawPass we wouldn't draw other children Views ViewGroup can have.
+     * Then instead of drawing our fake view we draw our stored RepaintBoundary.
+     */
+    private inner class ElevationCompat {
+        private val fakeChild: View = View(context).apply {
+            setWillNotDraw(true)
+            addView(this)
+        }
+        private var fakeDrawPass: Boolean = false
+        private var boundary: RepaintBoundary? = null
+
+        fun drawWithZ(canvas: Canvas, node: RepaintBoundaryNode) {
+            this.boundary = node.container
+            fakeDrawPass = true
+            super@AndroidCraneView.dispatchDraw(canvas.nativeCanvas)
+            fakeDrawPass = false
+        }
+
+        fun handleDrawChild(canvas: android.graphics.Canvas, child: View): Boolean {
+            return if (fakeDrawPass) {
+                if (child === fakeChild) {
+                    boundary?.callDraw(Canvas(canvas))
+                    boundary = null
+                }
+                true
+            } else {
+                false
+            }
+        }
+    }
 }
 
 private class ConstraintRange(val min: IntPx, val max: IntPx)
@@ -618,7 +729,8 @@
         clipChildren = false
         setWillNotDraw(false) // we WILL draw
     }
-    private val outlineResolver = OutlineResolver(Density(context))
+    private val density = Density(context)
+    private val outlineResolver = OutlineResolver(density)
     private val outlineProviderImpl = object : ViewOutlineProvider() {
         override fun getOutline(view: View, outline: android.graphics.Outline) {
             outlineResolver.applyTo(outline)
@@ -658,8 +770,7 @@
     }
 
     override fun detach() {
-        val parent = parent as ViewGroup
-        parent.removeView(this)
+        (parent as? ViewGroup)?.removeView(this)
     }
 
     fun drawChild(canvas: Canvas, child: View, drawingTime: Long) {
@@ -703,6 +814,7 @@
             dirty = true
         }
         alpha = repaintBoundaryNode.opacity
+        elevation = withDensity(density) { repaintBoundaryNode.elevation.toPx().value }
     }
 }
 
@@ -723,7 +835,8 @@
         }
     val renderNode = RenderNode(repaintBoundaryNode.name)
     private val outline = android.graphics.Outline()
-    private val outlineResolver = OutlineResolver(Density(ownerView.context))
+    private val density = Density(ownerView.context)
+    private val outlineResolver = OutlineResolver(density)
     private var clipPath: android.graphics.Path? = null
 
     override fun setSize(width: Int, height: Int) {
@@ -778,6 +891,7 @@
             dirty = true
         }
         renderNode.alpha = repaintBoundaryNode.opacity
+        renderNode.elevation = withDensity(density) { repaintBoundaryNode.elevation.toPx().value }
         ownerView.invalidate()
     }
 }
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/ComponentNodes.kt b/ui/ui-platform/src/main/java/androidx/ui/core/ComponentNodes.kt
index bd000ca..1ce1942 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/ComponentNodes.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/ComponentNodes.kt
@@ -15,11 +15,9 @@
  */
 package androidx.ui.core
 
-import androidx.ui.core.semantics.SemanticsAction
-import androidx.ui.core.semantics.SemanticsConfiguration
-import androidx.ui.text.style.TextDirection
-import androidx.ui.painting.Canvas
 import androidx.compose.Emittable
+import androidx.ui.core.semantics.SemanticsConfiguration
+import androidx.ui.painting.Canvas
 import androidx.ui.engine.geometry.Shape
 import kotlin.properties.ReadWriteProperty
 import kotlin.reflect.KProperty
@@ -166,18 +164,18 @@
     /**
      * Execute [block] on all children of this ComponentNode.
      */
-    fun visitChildren(block: (ComponentNode) -> Unit) {
-        for (i in 0 until children.size) {
-            block(children[i])
+    inline fun visitChildren(block: (ComponentNode) -> Unit) {
+        for (i in 0 until count) {
+            block(this[i])
         }
     }
 
     /**
      * Execute [block] on all children of this ComponentNode in reverse order.
      */
-    fun visitChildrenReverse(block: (ComponentNode) -> Unit) {
-        for (i in children.size - 1 downTo 0) {
-            block(children[i])
+    inline fun visitChildrenReverse(block: (ComponentNode) -> Unit) {
+        for (i in count - 1 downTo 0) {
+            block(this[i])
         }
     }
 
@@ -300,6 +298,17 @@
         }
 
     /**
+     * The z-coordinate at which to place this physical object.
+     */
+    var elevation: Dp = 0.dp
+        set(value) {
+            if (field != value) {
+                field = value
+                owner?.onRepaintBoundaryParamsChange(this)
+            }
+        }
+
+    /**
      * The fraction of children's alpha value.
      */
     var opacity: Float = 1f
@@ -569,6 +578,8 @@
 }
 
 class SemanticsComponentNode(
+    // TODO(ryanmentley): probably take away these default values
+    semanticsConfiguration: SemanticsConfiguration = SemanticsConfiguration(),
     /**
      * If [container] is true, this widget will introduce a new
      * node in the semantics tree. Otherwise, the semantics will be
@@ -597,166 +608,19 @@
      * This setting is often used in combination with [SemanticsConfiguration.isSemanticBoundary]
      * to create semantic boundaries that are either writable or not for children.
      */
-    explicitChildNodes: Boolean = false,
-    enabled: Boolean? = null,
-    checked: Boolean? = null,
-    selected: Boolean? = null,
-    button: Boolean? = null,
-    header: Boolean? = null,
-    textField: Boolean? = null,
-    focused: Boolean? = null,
-    inMutuallyExclusiveGroup: Boolean? = null,
-    obscured: Boolean? = null,
-    scopesRoute: Boolean? = null,
-    namesRoute: Boolean? = null,
-    hidden: Boolean? = null,
-    label: String? = null,
-    value: String? = null,
-    hint: String? = null,
-    textDirection: TextDirection? = null,
-    testTag: String? = null,
-    actions: List<SemanticsAction<*>> = emptyList()
-
+    explicitChildNodes: Boolean = false
 ) : ComponentNode() {
     private var needsSemanticsUpdate = true
-    private var cachedSemanticsConfiguration: SemanticsConfiguration? = null
-    val semanticsConfiguration: SemanticsConfiguration
-        get() {
-            if (cachedSemanticsConfiguration == null) {
-                cachedSemanticsConfiguration = generateNodeLocalSemanticsConfiguration()
-            }
-            return cachedSemanticsConfiguration!!
-        }
-
-    private fun generateNodeLocalSemanticsConfiguration(): SemanticsConfiguration? {
-        return SemanticsConfiguration().also { config ->
-            // TODO(ryanmentley): add more once we enable them in the API
-            enabled?.let { enabled ->
-                config.isEnabled = enabled
-            }
-            checked?.let { checked ->
-                config.isChecked = checked
-            }
-            selected?.let { selected ->
-                config.isSelected = selected
-            }
-            button?.let { button ->
-                config.isButton = button
-            }
-            inMutuallyExclusiveGroup?.let { inMutuallyExclusiveGroup ->
-                config.isInMutuallyExclusiveGroup = inMutuallyExclusiveGroup
-            }
-            hidden?.let { hidden ->
-                config.isHidden = hidden
-            }
-            label?.let { label ->
-                config.label = label
-            }
-            value?.let { value ->
-                config.value = value
-            }
-            textDirection?.let { textDirection ->
-                config.textDirection = textDirection
-            }
-            testTag?.let { testTag ->
-                config.testTag = testTag
-            }
-            config.actions = actions
-        }
-    }
 
     var container: Boolean by InvalidatingProperty(container)
 
     var explicitChildNodes: Boolean by InvalidatingProperty(explicitChildNodes)
 
-    /**
-     * If non-null, sets the [SemanticsNode.hasCheckedState] semantic to true and
-     * the [SemanticsNode.isChecked] semantic to the given value.
-     */
-    var checked: Boolean? by InvalidatingProperty(checked)
-
-    /**
-     * If non-null, sets the [SemanticsNode.hasEnabledState] semantic to true and
-     * the [SemanticsNode.isEnabled] semantic to the given value.
-     */
-    var enabled: Boolean? by InvalidatingProperty(enabled)
-
-    /**
-     * If non-null, sets the [SemanticsNode.isSelected] semantic to the given
-     * value.
-     */
-    var selected: Boolean? by InvalidatingProperty(selected)
-
-    /** If non-null, sets the [SemanticsNode.isButton] semantic to the given value. */
-    var button: Boolean? by InvalidatingProperty(button)
-
-    /** If non-null, sets the [SemanticsNode.isHeader] semantic to the given value. */
-    var header: Boolean? by InvalidatingProperty(header)
-
-    /** If non-null, sets the [SemanticsNode.isTextField] semantic to the given value. */
-    var textField: Boolean? by InvalidatingProperty(textField)
-
-    /** If non-null, sets the [SemanticsNode.isFocused] semantic to the given value. */
-    var focused: Boolean? by InvalidatingProperty(focused)
-
-    /**
-     * If non-null, sets the [SemanticsNode.isInMutuallyExclusiveGroup] semantic
-     * to the given value.
-     */
-    var inMutuallyExclusiveGroup: Boolean? by InvalidatingProperty(inMutuallyExclusiveGroup)
-
-    /**
-     * If non-null, sets the [SemanticsNode.isObscured] semantic to the given
-     * value.
-     */
-    var obscured: Boolean? by InvalidatingProperty(obscured)
-
-    /** If non-null, sets the [SemanticsNode.scopesRoute] semantic to the give value. */
-    var scopesRoute: Boolean? by InvalidatingProperty(scopesRoute)
-
-    /** If non-null, sets the [SemanticsNode.namesRoute] semantic to the give value. */
-    var namesRoute: Boolean? by InvalidatingProperty(namesRoute)
-
-    /**
-     * If non-null, sets the [SemanticsNode.isHidden] semantic to the given
-     * value.
-     */
-    var hidden: Boolean? by InvalidatingProperty(hidden)
-
-    /**
-     * If non-null, sets the [SemanticsNode.label] semantic to the given value.
-     *
-     * The reading direction is given by [textDirection].
-     */
-    var label: String? by InvalidatingProperty(label)
-
-    /**
-     * If non-null, sets the [SemanticsNode.value] semantic to the given value.
-     *
-     * The reading direction is given by [textDirection].
-     */
-    var value: String? by InvalidatingProperty(value)
-
-    /**
-     * If non-null, sets the [SemanticsNode.hint] semantic to the given value.
-     *
-     * The reading direction is given by [textDirection].
-     */
-    var hint: String? by InvalidatingProperty(hint)
-
-    /**
-     * If non-null, sets the [SemanticsNode.textDirection] semantic to the given value.
-     *
-     * This must not be null if [label], [hint], or [value] are not null.
-     */
-    var textDirection: TextDirection? by InvalidatingProperty(textDirection)
-
-    var testTag: String? by InvalidatingProperty(testTag)
-
-    var actions: List<SemanticsAction<*>> by InvalidatingProperty(actions)
+    // TODO(ryanmentley): this should be smarter and invalidate less
+    var semanticsConfiguration: SemanticsConfiguration
+            by InvalidatingProperty(semanticsConfiguration)
 
     internal fun markNeedsSemanticsUpdate() {
-        cachedSemanticsConfiguration = null
         needsSemanticsUpdate = true
     }
 }
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/Unicode.kt b/ui/ui-platform/src/main/java/androidx/ui/core/Unicode.kt
deleted file mode 100644
index bddf65e..0000000
--- a/ui/ui-platform/src/main/java/androidx/ui/core/Unicode.kt
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright 2019 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.ui.core
-
-// TODO(ryanmentley): This should be in platform, except we need it from Semantics,
-// and that puts a loop in the dependency graph.  It should probably not be exposed as public API.
-/**
- * Constants for useful Unicode characters.
- *
- * Currently, these characters are all related to bidirectional text.
- *
- * See also:
- *
- *  * <http://unicode.org/reports/tr9/>, which describes the Unicode
- *    bidirectional text algorithm.
- */
-object Unicode {
-    /**
-     * U+202A LEFT-TO-RIGHT EMBEDDING
-     *
-     * Treat the following text as embedded left-to-right.
-     *
-     * Use [PDF] to end the embedding.
-     */
-    const val LRE = "\u202A"
-
-    /**
-     * U+202B RIGHT-TO-LEFT EMBEDDING
-     *
-     * Treat the following text as embedded right-to-left.
-     *
-     * Use [PDF] to end the embedding.
-     */
-    const val RLE = "\u202B"
-
-    /**
-     * U+202C POP DIRECTIONAL FORMATTING
-     *
-     * End the scope of the last [LRE], [RLE], [RLO], or [LRO].
-     */
-    const val PDF = "\u202C"
-
-    /**
-     * U+202A LEFT-TO-RIGHT OVERRIDE
-     *
-     * Force following characters to be treated as strong left-to-right characters.
-     *
-     * For example, this causes Hebrew text to render backwards.
-     *
-     * Use [PDF] to end the override.
-     */
-    const val LRO = "\u202D"
-
-    /**
-     * U+202B RIGHT-TO-LEFT OVERRIDE
-     *
-     * Force following characters to be treated as strong right-to-left characters.
-     *
-     * For example, this causes English text to render backwards.
-     *
-     * Use [PDF] to end the override.
-     */
-    const val RLO = "\u202E"
-
-    /**
-     * U+2066 LEFT-TO-RIGHT ISOLATE
-     *
-     * Treat the following text as isolated and left-to-right.
-     *
-     * Use [PDI] to end the isolated scope.
-     */
-    const val LRI = "\u2066"
-
-    /**
-     * U+2067 RIGHT-TO-LEFT ISOLATE
-     *
-     * Treat the following text as isolated and right-to-left.
-     *
-     * Use [PDI] to end the isolated scope.
-     */
-    const val RLI = "\u2067"
-
-    /**
-     * U+2068 FIRST STRONG ISOLATE
-     *
-     * Treat the following text as isolated and in the direction of its first
-     * strong directional character that is not inside a nested isolate.
-     *
-     * This essentially "autodetects" the directionality of the text. It is not
-     * 100% reliable. For example, Arabic text that starts with an English quote
-     * will be detected as LTR, not RTL, which will lead to the text being in a
-     * weird order.
-     *
-     * Use [PDI] to end the isolated scope.
-     */
-    const val FSI = "\u2068"
-
-    /**
-     * U+2069 POP DIRECTIONAL ISOLATE
-     *
-     * End the scope of the last [LRI], [RLI], or [FSI].
-     */
-    const val PDI = "\u2069"
-
-    /**
-     * U+200E LEFT-TO-RIGHT MARK
-     *
-     * Left-to-right zero-width character.
-     */
-    const val LRM = "\u200E"
-
-    /**
-     * U+200F RIGHT-TO-LEFT MARK
-     *
-     * Right-to-left zero-width non-Arabic character.
-     */
-    const val RLM = "\u200F"
-
-    /**
-     * U+061C ARABIC LETTER MARK
-     *
-     * Right-to-left zero-width Arabic character.
-     */
-    const val ALM = "\u061C"
-}
\ No newline at end of file
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/input/TextInputServiceAndroid.kt b/ui/ui-platform/src/main/java/androidx/ui/core/input/TextInputServiceAndroid.kt
index e77e070..ebd0826 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/input/TextInputServiceAndroid.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/input/TextInputServiceAndroid.kt
@@ -54,8 +54,7 @@
     /**
      * The editable buffer used for BaseInputConnection.
      */
-    private val imm =
-        view.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+    private lateinit var imm: InputMethodManager
 
     /**
      * Creates new input connection.
@@ -92,6 +91,7 @@
         onEditCommand: (List<EditOperation>) -> Unit,
         onImeActionPerformed: (ImeAction) -> Unit
     ) {
+        imm = view.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
         editorHasFocus = true
         state = initModel.toInputState()
         this.keyboardType = keyboardType
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/semantics/SemanticsConfiguration.kt b/ui/ui-platform/src/main/java/androidx/ui/core/semantics/SemanticsConfiguration.kt
index dc320d9..b5daf47 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/semantics/SemanticsConfiguration.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/semantics/SemanticsConfiguration.kt
@@ -16,11 +16,8 @@
 
 package androidx.ui.core.semantics
 
-import androidx.ui.core.Unicode
-import androidx.ui.text.TextSelection
-import androidx.ui.text.style.TextDirection
-import kotlin.properties.ReadWriteProperty
-import kotlin.reflect.KProperty
+import androidx.ui.semantics.SemanticsPropertyKey
+import androidx.ui.semantics.SemanticsPropertyReceiver
 
 /**
  * Describes the semantic information associated with the owning component
@@ -28,7 +25,47 @@
  * The information provided in the configuration is used to to generate the
  * semantics tree.
  */
-class SemanticsConfiguration {
+class SemanticsConfiguration : SemanticsPropertyReceiver,
+    Iterable<Map.Entry<SemanticsPropertyKey<*>, Any?>> {
+
+    private val props: MutableMap<SemanticsPropertyKey<*>, Any?> = mutableMapOf()
+
+    /**
+     * Retrieves the value for the given property, if one has been set.
+     * If a value has not been set, throws [IllegalStateException]
+     */
+    // Unavoidable, guaranteed by [set]
+    @Suppress("UNCHECKED_CAST")
+    operator fun <T> get(key: SemanticsPropertyKey<T>): T {
+        return props.getOrElse(key) {
+            throw IllegalStateException("Key not present: $key - consider getOrElse or getOrNull")
+        } as T
+    }
+
+    // Unavoidable, guaranteed by [set]
+    @Suppress("UNCHECKED_CAST")
+    fun <T> getOrElse(key: SemanticsPropertyKey<T>, defaultValue: () -> T): T {
+        return props.getOrElse(key, defaultValue) as T
+    }
+
+    // Unavoidable, guaranteed by [set]
+    @Suppress("UNCHECKED_CAST")
+    fun <T> getOrElseNullable(key: SemanticsPropertyKey<T>, defaultValue: () -> T?): T? {
+        return props.getOrElse(key, defaultValue) as T?
+    }
+
+    override fun iterator(): Iterator<Map.Entry<SemanticsPropertyKey<*>, Any?>> {
+        return props.iterator()
+    }
+
+    override fun <T> set(key: SemanticsPropertyKey<T>, value: T) {
+        props[key] = value
+    }
+
+    operator fun <T> contains(key: SemanticsPropertyKey<T>): Boolean {
+        return props.containsKey(key)
+    }
+
     // SEMANTIC BOUNDARY BEHAVIOR
 
     /**
@@ -70,90 +107,6 @@
     var explicitChildNodes = false
 
     /**
-     * Whether the owning component makes other components previously
-     * painted within the same semantic boundary unreachable for accessibility
-     * purposes.
-     *
-     * If set to true, the semantic information for all siblings and cousins of
-     * this node, that are earlier in a depth-first pre-order traversal, are
-     * dropped from the semantics tree up until a semantic boundary (as defined
-     * by [isSemanticBoundary]) is reached.
-     *
-     * If [isSemanticBoundary] and [isBlockingSemanticsOfPreviouslyPaintedNodes]
-     * is set on the same node, all previously painted siblings and cousins up
-     * until the next ancestor that is a semantic boundary are dropped.
-     *
-     * Paint order as established by [visitChildrenForSemantics] is used to
-     * determine if a node is previous to this one.
-     */
-    var isBlockingSemanticsOfPreviouslyPaintedNodes = false
-
-    // SEMANTIC ANNOTATIONS
-    // These will end up on [SemanticNode]s generated from [SemanticsConfiguration]s.
-
-    /**
-     * Whether this configuration is empty.
-     *
-     * An empty configuration doesn't contain any semantic information that it
-     * wants to contribute to the semantics tree.
-     */
-    var hasBeenAnnotated: Boolean = false
-
-    /**
-     * The actions (with associated action handlers) that this configuration
-     * would like to contribute to the semantics tree.
-     *
-     * See also:
-     *
-     * * [addAction] to add an action.
-     */
-    internal var _actions: MutableMap<SemanticsActionType<*>,
-            SemanticsAction<*>> = mutableMapOf()
-
-    var actions: List<SemanticsAction<*>>
-        get() = _actions.values.toList()
-        set(value) {
-            // TODO(ryanmentley): This is naive, we could be smarter
-            actionsAsBits = 0
-            _actions.clear()
-            for (action in value) {
-                addAction(action)
-            }
-        }
-
-    private var actionsAsBits: Int = 0
-
-    /**
-     * Adds an `action` to the semantics tree.
-     *
-     * The provided `handler` is called to respond to the user triggered
-     * `action`.
-     */
-    private fun addAction(action: SemanticsAction<*>) {
-        _actions[action.type] = action
-        actionsAsBits = actionsAsBits or action.type.bitmask
-        hasBeenAnnotated = true
-    }
-
-    /**
-     * A property that marks the configuration as having been annotated
-     * (i.e., containing information)
-     */
-    private class AnnotationProperty<T>(initialValue: T) :
-        ReadWriteProperty<SemanticsConfiguration, T> {
-        private var value = initialValue
-
-        override fun getValue(thisRef: SemanticsConfiguration, property: KProperty<*>): T {
-            return value
-        }
-
-        override fun setValue(thisRef: SemanticsConfiguration, property: KProperty<*>, value: T) {
-            this.value = value
-            thisRef.hasBeenAnnotated = true
-        }
-    }
-
-    /**
      * Whether the semantic information provided by the owning component and
      * all of its descendants should be treated as one logical entity.
      *
@@ -171,337 +124,49 @@
             }
 
             field = value
-            hasBeenAnnotated = true
         }
 
-    var label: String? by AnnotationProperty("")
-
-    var value: String? by AnnotationProperty("")
-
-    // TODO(ryanmentley): Added in API 26 and backported via androidx, integrate this
-    /**
-     * A brief description of the result of performing an action on this node.
-     *
-     * On iOS this is used for the `accessibilityHint` property defined in the
-     * `UIAccessibility` Protocol. On Android it is concatenated together with
-     * [label] and [value] in the following order: [value], [label], [hint].
-     * The concatenated value is then used as the `Text` description.
-     *
-     * The reading direction is given by [textDirection].
-     */
-    var hint: String? by AnnotationProperty("")
+    // SEMANTIC ANNOTATIONS
+    // These will end up on [SemanticNode]s generated from [SemanticsConfiguration]s.
 
     /**
-     * Provides hint values which override the default hints on supported
-     * platforms.
+     * Whether this configuration is empty.
+     *
+     * An empty configuration doesn't contain any semantic information that it
+     * wants to contribute to the semantics tree.
      */
-    var hintOverrides: SemanticsHintOverrides? by AnnotationProperty(null)
-
-    /**
-     * Whether the semantics node is the root of a subtree for which values
-     * should be announced.
-     *
-     * See also:
-     *  * [SemanticsFlag.ScopesRoute], for a full description of route scoping.
-     */
-    var scopesRoute: Boolean by SimpleFlagProperty(SemanticsFlag.ScopesRoute)
-
-    /**
-     * Whether the semantics node contains the label of a route.
-     *
-     * See also:
-     *  * [SemanticsFlag.NamesRoute], for a full description of route naming.
-     */
-    var namesRoute: Boolean by SimpleFlagProperty(SemanticsFlag.NamesRoute)
-
-    /** Whether the semantics node represents an image. */
-    var isImage: Boolean by SimpleFlagProperty(SemanticsFlag.IsImage)
-
-    /**
-     * Whether the semantics node is a live region.
-     *
-     * On Android, when a live region semantics node is first created TalkBack
-     * will make a polite announcement of the current label. This announcement
-     * occurs even if the node is not focused. Subsequent polite announcements
-     * can be made by sending a [UpdateLiveRegionEvent] semantics event. The
-     * announcement will only be made if the node's label has changed since the
-     * last update.
-     *
-     * An example of a live region is the [Snackbar] widget. When it appears
-     * on the screen it may be difficult to focus to read the label. A live
-     * region causes an initial polite announcement to be generated
-     * automatically.
-     *
-     * See also:
-     *
-     *   * [SemanticsFlag.IsLiveRegion], the semantics flag that this setting controls.
-     */
-    var liveRegion: Boolean by SimpleFlagProperty(SemanticsFlag.IsLiveRegion)
-
-    var textDirection: TextDirection? by AnnotationProperty(null)
-
-    var isSelected: Boolean by SimpleFlagProperty(
-        SemanticsFlag.IsSelected
-    )
-
-    var isEnabled: Boolean?
-        get() {
-            return if (hasFlag(SemanticsFlag.HasEnabledState)) {
-                hasFlag(SemanticsFlag.IsEnabled)
-            } else {
-                null
-            }
-        }
-        set(value) {
-            setFlag(SemanticsFlag.HasEnabledState, value != null)
-            setFlag(SemanticsFlag.IsEnabled, value ?: false)
-        }
-
-    var isChecked: Boolean?
-        get() {
-            return if (hasFlag(SemanticsFlag.HasCheckedState)) {
-                hasFlag(SemanticsFlag.IsChecked)
-            } else {
-                null
-            }
-        }
-        set(value) {
-            setFlag(SemanticsFlag.HasCheckedState, value != null)
-            setFlag(SemanticsFlag.IsChecked, value ?: false)
-        }
-
-    /**
-     * If this node has Boolean state that can be controlled by the user, whether
-     * that state is on or off, corresponding to true and false, respectively.
-     *
-     * Do not call the setter for this field if the owning component doesn't
-     * have on/off state that can be controlled by the user.
-     *
-     * The getter returns null if the owning component does not have
-     * on/off state.
-     */
-    var isToggled: Boolean?
-        get() {
-            return if (hasFlag(SemanticsFlag.HasToggledState)) {
-                hasFlag(SemanticsFlag.IsToggled)
-            } else {
-                null
-            }
-        }
-        set(value) {
-            setFlag(SemanticsFlag.HasToggledState, value != null)
-            setFlag(SemanticsFlag.IsToggled, value ?: false)
-        }
-
-    var isInMutuallyExclusiveGroup: Boolean
-            by SimpleFlagProperty(SemanticsFlag.IsInMutuallyExclusiveGroup)
-
-    /** Whether the component represented by this configuration currently holds the user's focus. */
-    var isFocused: Boolean by SimpleFlagProperty(SemanticsFlag.IsFocused)
-
-    var isButton: Boolean by SimpleFlagProperty(SemanticsFlag.IsButton)
-
-    /** Whether the component represented by this configuration is a header (true) or not (false). */
-    var isHeader: Boolean by SimpleFlagProperty(SemanticsFlag.IsHeader)
-
-    /**
-     * Whether the the component represented by this configuration is considered hidden.
-     *
-     * Hidden elements are currently not visible on screen. They may be covered
-     * by other elements or positioned outside of the visible area of a viewport.
-     *
-     * Hidden elements cannot gain accessibility focus though regular touch. The
-     * only way they can be focused is by moving the focus to them via linear
-     * navigation.
-     *
-     * Platforms are free to completely ignore hidden elements and new platforms
-     * are encouraged to do so.
-     *
-     * Instead of marking an element as hidden it should usually be excluded from
-     * the semantics tree altogether. Hidden elements are only included in the
-     * semantics tree to work around platform limitations and they are mainly
-     * used to implement accessibility scrolling on iOS.
-     */
-    var isHidden: Boolean by SimpleFlagProperty(SemanticsFlag.IsHidden)
-
-    /** Whether the owning component is a text field. */
-    var isTextField: Boolean by SimpleFlagProperty(SemanticsFlag.IsTextField)
-
-    /**
-     * Whether the [value] should be obscured.
-     *
-     * This option is usually set in combination with [isTextField] to indicate
-     * that the text field contains a password (or other sensitive information).
-     * Doing so instructs screen readers to not read out the [value].
-     */
-    var isObscured: Boolean by SimpleFlagProperty(SemanticsFlag.IsObscured)
-
-    /**
-     * Whether the platform can scroll the semantics node when the user attempts
-     * to move focus to an offscreen child.
-     *
-     * For example, a [ListView] widget has implicit scrolling so that users can
-     * easily move to the next visible set of children. A [TabBar] widget does
-     * not have implicit scrolling, so that users can navigate into the tab
-     * body when reaching the end of the tab bar.
-     */
-    var hasImplicitScrolling: Boolean by SimpleFlagProperty(SemanticsFlag.HasImplicitScrolling)
-
-    /**
-     * The currently selected text (or the position of the cursor) within [value]
-     * if this node represents a text field.
-     */
-    var textSelection: TextSelection? by AnnotationProperty(null)
-
-    /**
-     * Indicates the current scrolling position in logical pixels if the node is
-     * scrollable.
-     *
-     * The properties [scrollExtentMin] and [scrollExtentMax] indicate the valid
-     * in-range values for this property. The value for [scrollPosition] may
-     * (temporarily) be outside that range, e.g. during an overscroll.
-     *
-     * See also:
-     *
-     *  * [ScrollPosition.pixels], from where this value is usually taken.
-     */
-    var scrollPosition: Float? by AnnotationProperty(null)
-
-    /**
-     * Indicates the maximum in-range value for [scrollPosition] if the node is
-     * scrollable.
-     *
-     * This value may be infinity if the scroll is unbound.
-     *
-     * See also:
-     *
-     *  * [ScrollPosition.maxScrollExtent], from where this value is usually taken.
-     */
-    var scrollExtentMax: Float? by AnnotationProperty(null)
-
-    /**
-     * Indicates the minimum in-range value for [scrollPosition] if the node is
-     * scrollable.
-     *
-     * This value may be infinity if the scroll is unbound.
-     *
-     * See also:
-     *
-     *  * [ScrollPosition.minScrollExtent], from where this value is usually taken.
-     */
-    var scrollExtentMin: Float? by AnnotationProperty(null)
-
-    var testTag: String? by AnnotationProperty(null)
-
-    // INTERNAL FLAG MANAGEMENT
-
-    private var flags = 0
-
-    private fun setFlag(flag: SemanticsFlag, value: Boolean) {
-        flags = if (value) {
-            flags or flag.bitmask
-        } else {
-            flags and flag.bitmask.inv()
-        }
-        hasBeenAnnotated = true
-    }
-
-    private fun hasFlag(flag: SemanticsFlag): Boolean = (flags and flag.bitmask) != 0
-
-    /**
-     * A property that provides an abstraction over [setFlag] and [hasFlag]
-     */
-    private class SimpleFlagProperty(
-        val flag: SemanticsFlag
-    ) : ReadWriteProperty<SemanticsConfiguration, Boolean> {
-        override fun getValue(
-            thisRef: SemanticsConfiguration,
-            property: KProperty<*>
-        ): Boolean {
-            return thisRef.hasFlag(flag)
-        }
-
-        override fun setValue(
-            thisRef: SemanticsConfiguration,
-            property: KProperty<*>,
-            value: Boolean
-        ) {
-            thisRef.setFlag(flag, value)
-        }
-    }
+    val hasBeenAnnotated: Boolean
+        get() = props.isEmpty()
 
     // CONFIGURATION COMBINATION LOGIC
 
     /**
-     * Whether this configuration is compatible with the provided `other` configuration.
-     *
-     * Two configurations are said to be compatible if they can be added to the same [SemanticsNode]
-     * without losing any semantics information.
-     */
-    fun isCompatibleWith(other: SemanticsConfiguration?): Boolean {
-        if (other == null || !other.hasBeenAnnotated || !hasBeenAnnotated) {
-            return true
-        }
-        if (actionsAsBits and other.actionsAsBits != 0) {
-            return false
-        }
-        if ((flags and other.flags) != 0) {
-            return false
-        }
-        if (!value.isNullOrEmpty() && !value.isNullOrEmpty()) {
-            return false
-        }
-        return true
-    }
-
-    /**
      * Absorb the semantic information from `other` into this configuration.
      *
      * This adds the semantic information of both configurations and saves the result in this
      * configuration.
      *
      * Only configurations that have [explicitChildNodes] set to false can absorb other
-     * configurations.  The [other] configuration must be compatible as determined by
-     * [isCompatibleWith].
+     * configurations.  The [other] configuration must not contain any properties that cannot be
+     * merged into this configuration.
      */
     internal fun absorb(other: SemanticsConfiguration) {
         assert(!explicitChildNodes)
-        assert(isCompatibleWith((other)))
 
         if (!other.hasBeenAnnotated) {
             return
         }
 
-        _actions.putAll(other._actions)
-        actionsAsBits = actionsAsBits or other.actionsAsBits
-        flags = flags or other.flags
-
-        textSelection = textSelection ?: other.textSelection
-        scrollPosition = scrollPosition ?: other.scrollPosition
-        scrollExtentMax = scrollExtentMax ?: other.scrollExtentMax
-        scrollExtentMin = scrollExtentMin ?: other.scrollExtentMin
-        hintOverrides = hintOverrides ?: other.hintOverrides
-
-        textDirection = textDirection ?: other.textDirection
-
-        label = concatStrings(
-            thisString = label,
-            thisTextDirection = textDirection,
-            otherString = other.label,
-            otherTextDirection = other.textDirection
-        )
-        if (value.isNullOrEmpty()) {
-            value = other.value
+        for (entry in other.props) {
+            val key = entry.key
+            if (props.containsKey(key)) {
+                @Suppress("UNCHECKED_CAST")
+                key as SemanticsPropertyKey<Any?>
+                props[key] = key.merge(props[key], entry.value)
+            } else {
+                props[key] = entry.value
+            }
         }
-
-        hint = concatStrings(
-            thisString = hint,
-            thisTextDirection = textDirection,
-            otherString = other.hint,
-            otherTextDirection = other.textDirection
-        )
-
-        hasBeenAnnotated = hasBeenAnnotated or other.hasBeenAnnotated
     }
 
     /** Returns an exact copy of this configuration. */
@@ -509,74 +174,12 @@
         val copy = SemanticsConfiguration()
         copy.isSemanticBoundary = isSemanticBoundary
         copy.explicitChildNodes = explicitChildNodes
-        copy.isBlockingSemanticsOfPreviouslyPaintedNodes =
-            isBlockingSemanticsOfPreviouslyPaintedNodes
         copy.isMergingSemanticsOfDescendants = isMergingSemanticsOfDescendants
-        copy.textDirection = textDirection
-        copy.label = label
-        copy.value = value
-        copy.hint = hint
-        copy.hintOverrides = hintOverrides
-        copy.flags = flags
-        copy.textSelection = textSelection
-        copy.scrollPosition = scrollPosition
-        copy.scrollExtentMax = scrollExtentMax
-        copy.scrollExtentMin = scrollExtentMin
-        copy.actionsAsBits = actionsAsBits
-        copy._actions.putAll(_actions)
-        // Do this last so it's not overwritten by setting the other properties
-        copy.hasBeenAnnotated = hasBeenAnnotated
+        copy.props.putAll(props)
         return copy
     }
-
-    /**
-     * Checks that all properties are the same and that the set of actions (though not necessarily
-     * the exact functions implementing them) are the same
-     */
-    internal fun isSemanticallyDifferentFrom(other: SemanticsConfiguration): Boolean {
-        return this.label != other.label ||
-                this.hint != other.hint ||
-                this.value != other.value ||
-                this.flags != other.flags ||
-                this.textDirection != other.textDirection ||
-                this.textSelection != other.textSelection ||
-                this.scrollPosition != other.scrollPosition ||
-                this.scrollExtentMax != other.scrollExtentMax ||
-                this.scrollExtentMin != other.scrollExtentMin ||
-                this.actionsAsBits != other.actionsAsBits
-    }
-
-    internal fun updateWith(sourceConfig: SemanticsConfiguration) {
-        this.label = sourceConfig.label
-        this.value = sourceConfig.value
-        this.hint = sourceConfig.hint
-        this.flags = sourceConfig.flags
-        this.textDirection = sourceConfig.textDirection
-        this._actions = sourceConfig._actions
-        this.actionsAsBits = sourceConfig.actionsAsBits
-        this.textSelection = sourceConfig.textSelection
-        this.scrollPosition = sourceConfig.scrollPosition
-        this.scrollExtentMax = sourceConfig.scrollExtentMax
-        this.scrollExtentMin = sourceConfig.scrollExtentMin
-    }
 }
 
-private fun concatStrings(
-    thisString: String?,
-    otherString: String?,
-    thisTextDirection: TextDirection?,
-    otherTextDirection: TextDirection?
-): String? {
-    if (otherString.isNullOrEmpty())
-        return thisString
-    var nestedLabel = otherString
-    if (thisTextDirection != otherTextDirection && otherTextDirection != null) {
-        nestedLabel = when (otherTextDirection) {
-            TextDirection.Rtl -> "${Unicode.RLE}$nestedLabel${Unicode.PDF}"
-            TextDirection.Ltr -> "${Unicode.LRE}$nestedLabel${Unicode.PDF}"
-        }
-    }
-    if (thisString.isNullOrEmpty())
-        return nestedLabel
-    return "$thisString\n$nestedLabel"
-}
\ No newline at end of file
+fun <T> SemanticsConfiguration.getOrNull(key: SemanticsPropertyKey<T>): T? {
+    return getOrElseNullable(key) { null }
+}
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/semantics/SemanticsFlag.kt b/ui/ui-platform/src/main/java/androidx/ui/core/semantics/SemanticsFlag.kt
deleted file mode 100644
index 24f72e7..0000000
--- a/ui/ui-platform/src/main/java/androidx/ui/core/semantics/SemanticsFlag.kt
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright 2019 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.ui.core.semantics
-
-// TODO(ryanmentley): b/129900044: Could this be an inline class and eliminate a lot of the
-// properties on SemanticsConfiguration?
-/** A Boolean value that can be associated with a [SemanticsNode]. */
-enum class SemanticsFlag {
-    /**
-     * The semantics node has the quality of either being "checked" or "unchecked".
-     *
-     * This flag is mutually exclusive with [HasToggledState].
-     *
-     * For example, a checkbox or a radio button widget has checked state.
-     *
-     * See also:
-     *
-     *   * [SemanticsFlag.IsChecked], which controls whether the node is "checked" or "unchecked".
-     */
-    HasCheckedState,
-
-    /**
-     * Whether a semantics node that [HasCheckedState] is checked.
-     *
-     * If true, the semantics node is "checked". If false, the semantics node is
-     * "unchecked".
-     *
-     * For example, if a checkbox has a visible checkmark, [IsChecked] is true.
-     *
-     * See also:
-     *
-     *   * [SemanticsFlag.HasCheckedState], which enables a checked state.
-     */
-    IsChecked,
-
-    /**
-     * Whether a semantics node is selected.
-     *
-     * If true, the semantics node is "selected". If false, the semantics node is
-     * "unselected".
-     *
-     * For example, the active tab in a tab bar has [IsSelected] set to true.
-     */
-    IsSelected,
-
-    /**
-     * Whether the semantic node represents a button.
-     *
-     * Some platforms have special handling for buttons. For example, iOS's VoiceOver provides an
-     * additional hint when the focused object is a button.
-     */
-    // TODO(ryanmentley): Should we remove this?
-    IsButton,
-
-    /**
-     * Whether the semantic node represents a text field.
-     *
-     * Text fields are announced as such and allow text input via accessibility
-     * affordances.
-     */
-    IsTextField,
-
-    /**
-     * Whether the semantic node currently holds the user's focus.
-     *
-     * The focused element is usually the current receiver of keyboard inputs.
-     */
-    IsFocused,
-
-    /**
-     * The semantics node has the quality of either being "enabled" or
-     * "disabled".
-     *
-     * For example, a button can be enabled or disabled and therefore has an
-     * "enabled" state. Static text is usually neither enabled nor disabled and
-     * therefore does not have an "enabled" state.
-     */
-    HasEnabledState,
-
-    /**
-     * Whether a semantic node that [HasEnabledState] is currently enabled.
-     *
-     * A disabled element does not respond to user interaction. For example, a
-     * button that currently does not respond to user interaction should be
-     * marked as disabled.
-     */
-    IsEnabled,
-
-    /**
-     * Whether a semantic node is in a mutually exclusive group.
-     *
-     * For example, a radio button is in a mutually exclusive group because
-     * only one radio button in that group can be marked as [IsChecked].
-     */
-    IsInMutuallyExclusiveGroup,
-
-    /**
-     * Whether a semantic node is a header that divides content into sections.
-     *
-     * For example, headers can be used to divide a list of alphabetically
-     * sorted words into the sections A, B, C, etc. as can be found in many
-     * address book applications.
-     */
-    IsHeader,
-
-    /**
-     * Whether the value of the semantics node is obscured.
-     *
-     * This is usually used for text fields to indicate that its content
-     * is a password or contains other sensitive information.
-     */
-    IsObscured,
-
-    /**
-     * Whether the semantics node is the root of a subtree for which a route name
-     * should be announced.
-     *
-     * When a node with this flag is removed from the semantics tree, the
-     * framework will select the last in depth-first, paint order node with this
-     * flag.  When a node with this flag is added to the semantics tree, it is
-     * selected automatically, unless there were multiple nodes with this flag
-     * added.  In this case, the last added node in depth-first, paint order
-     * will be selected.
-     *
-     * From this selected node, the framework will search in depth-first, paint
-     * order for the first node with a [NamesRoute] flag and a non-null,
-     * non-empty label. The [NamesRoute] and [ScopesRoute] flags may be on the
-     * same node. The label of the found node will be announced as an edge
-     * transition. If no non-empty, non-null label is found then:
-     *
-     *   * VoiceOver will make a chime announcement.
-     *   * TalkBack will make no announcement
-     *
-     * Semantic nodes annotated with this flag are generally not a11y focusable.
-     *
-     * This is used in widgets such as Routes, Drawers, and Dialogs to
-     * communicate significant changes in the visible screen.
-     */
-    ScopesRoute,
-
-    /**
-     * Whether the semantics node label is the name of a visually distinct
-     * route.
-     *
-     * This is used by certain widgets like Drawers and Dialogs, to indicate
-     * that the node's semantic label can be used to announce an edge triggered
-     * semantics update.
-     *
-     * Semantic nodes annotated with this flag will still recieve a11y focus.
-     *
-     * Updating this label within the same active route subtree will not cause
-     * additional announcements.
-     */
-    NamesRoute,
-
-    /**
-     * Whether the semantics node is considered hidden.
-     *
-     * Hidden elements are currently not visible on screen. They may be covered
-     * by other elements or positioned outside of the visible area of a viewport.
-     *
-     * Hidden elements cannot gain accessibility focus though regular touch. The
-     * only way they can be focused is by moving the focus to them via linear
-     * navigation.
-     *
-     * Platforms are free to completely ignore hidden elements and new platforms
-     * are encouraged to do so.
-     *
-     * Instead of marking an element as hidden it should usually be excluded from
-     * the semantics tree altogether. Hidden elements are only included in the
-     * semantics tree to work around platform limitations and they are mainly
-     * used to implement accessibility scrolling on iOS.
-     */
-    IsHidden,
-
-    /**
-     * Whether the semantics node represents an image.
-     *
-     * Both TalkBack and VoiceOver will inform the user the the semantics node
-     * represents an image.
-     */
-    IsImage,
-
-    /**
-     * Whether the semantics node is a live region.
-     *
-     * A live region indicates that updates to semantics node are important.
-     * Platforms may use this information to make polite announcements to the
-     * user to inform them of updates to this node.
-     *
-     * An example of a live region is a [SnackBar] widget. On Android, A live
-     * region causes a polite announcement to be generated automatically, even
-     * if the user does not have focus of the widget.
-     */
-    IsLiveRegion,
-
-    /**
-     * The semantics node has the quality of either being "on" or "off".
-     *
-     * This flag is mutually exclusive with [hasCheckedState].
-     *
-     * For example, a switch has toggled state.
-     *
-     * See also:
-     *
-     *    * [SemanticsFlag.isToggled], which controls whether the node is "on" or "off".
-     */
-    HasToggledState,
-
-    /**
-     * If true, the semantics node is "on". If false, the semantics node is
-     * "off".
-     *
-     * For example, if a switch is in the on position, [IsToggled] is true.
-     *
-     * See also:
-     *
-     *   * [SemanticsFlag.HasToggledState], which enables a toggled state.
-     */
-    IsToggled,
-
-    /**
-     * Whether the platform can scroll the semantics node when the user attempts
-     * to move focus to an offscreen child.
-     *
-     * For example, a [ListView] widget has implicit scrolling so that users can
-     * easily move to the next visible set of children. A [TabBar] widget does
-     * not have implicit scrolling, so that users can navigate into the tab
-     * body when reaching the end of the tab bar.
-     */
-    HasImplicitScrolling;
-
-    companion object {
-
-        /**
-         * The possible semantics flags.
-         *
-         * The map's key is the [bitmask] of the flag and the value is the flag itself.
-         */
-        val values: Map<Int, SemanticsFlag>
-
-        init {
-            this.values = mutableMapOf()
-            for (flag in SemanticsFlag.values()) {
-                values[flag.bitmask] = flag
-            }
-        }
-    }
-
-    /**
-     * The numerical value for this flag.
-     *
-     * Each flag has one bit set in this bit field.
-     */
-    internal val bitmask: Int
-        get() = 1 shl ordinal
-
-    override fun toString(): String {
-        return "SemanticsFlag.$name"
-    }
-}
\ No newline at end of file
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/semantics/SemanticsNode.kt b/ui/ui-platform/src/main/java/androidx/ui/core/semantics/SemanticsNode.kt
index 6b413d5..21a27e1 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/semantics/SemanticsNode.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/semantics/SemanticsNode.kt
@@ -18,6 +18,8 @@
 
 import androidx.ui.core.ifDebug
 import androidx.ui.engine.geometry.Rect
+import androidx.ui.semantics.AccessibilityAction
+import androidx.ui.semantics.SemanticsPropertyKey
 
 /**
  * Signature for a function that is called for each [SemanticsNode].
@@ -56,6 +58,7 @@
         fun root(
             owner: SemanticsOwner
         ): SemanticsNode {
+            // TODO(ryanmentley): Reconsider whether this should be non-zero, especially for multiple Compose hierachies
             val node = SemanticsNode(0)
             node.attach(owner)
             return node
@@ -349,11 +352,8 @@
         }
     }
 
-    fun isDifferentFromCurrentSemanticAnnotation(config: SemanticsConfiguration): Boolean {
-        return this.config.isSemanticallyDifferentFrom(config) ||
-                mergeAllDescendantsIntoThisNode != config.isMergingSemanticsOfDescendants
-    }
-
-    internal fun canPerformAction(action: SemanticsActionType<*>) =
-        this.config._actions.containsKey(action)
+    internal fun <T : Function<Unit>> canPerformAction(
+        action: SemanticsPropertyKey<AccessibilityAction<T>>
+    ) =
+        this.config.contains(action)
 }
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/semantics/SemanticsOwner.kt b/ui/ui-platform/src/main/java/androidx/ui/core/semantics/SemanticsOwner.kt
index 7ad1184..3ac9846 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/semantics/SemanticsOwner.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/semantics/SemanticsOwner.kt
@@ -16,6 +16,9 @@
 
 package androidx.ui.core.semantics
 
+import androidx.ui.semantics.AccessibilityAction
+import androidx.ui.semantics.SemanticsPropertyKey
+
 // TODO(ryanmentley): Clean up and integrate this (probably with AndroidCraneView)
 
 /**
@@ -41,10 +44,10 @@
         detachedNodes.clear()
     }
 
-    private fun getSemanticsActionHandlerForId(
+    private fun <T : Function<Unit>> getSemanticsActionHandlerForId(
         id: Int,
-        action: SemanticsActionType<*>
-    ): SemanticsAction<*>? {
+        action: SemanticsPropertyKey<AccessibilityAction<T>>
+    ): AccessibilityAction<*>? {
         var result: SemanticsNode? = nodes[id]
         if (result != null && result.isPartOfNodeMerging && !result.canPerformAction(action)) {
             result.visitDescendants { node: SemanticsNode ->
@@ -58,19 +61,6 @@
         if (result?.canPerformAction(action) != true) {
             return null
         }
-        return result!!.config._actions[action]
-    }
-
-    /**
-     * Asks the [SemanticsNode] with the given id to perform the given action.
-     *
-     * If the [SemanticsNode] has not indicated that it can perform the action,
-     * this function does nothing.
-     *
-     * If the given `action` requires arguments they need to be passed in via
-     * the `args` parameter.
-     */
-    fun performAction(id: Int, action: SemanticsActionType<*>, args: Any? = null) {
-        getSemanticsActionHandlerForId(id, action)?.invokeHandler(args)
+        return result!!.config.getOrNull(action)
     }
 }
\ No newline at end of file
diff --git a/ui/ui-platform/src/main/java/androidx/ui/internal/Unicode.kt b/ui/ui-platform/src/main/java/androidx/ui/internal/Unicode.kt
new file mode 100644
index 0000000..f20fb1b
--- /dev/null
+++ b/ui/ui-platform/src/main/java/androidx/ui/internal/Unicode.kt
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2019 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.ui.internal
+// TODO(ryanmentley): This should probably not be exposed as public API.
+/**
+ * Constants for useful Unicode characters.
+ *
+ * Currently, these characters are all related to bidirectional text.
+ *
+ * See also:
+ *
+ *  * <http://unicode.org/reports/tr9/>, which describes the Unicode
+ *    bidirectional text algorithm.
+ */
+object Unicode {
+    /**
+     * U+202A LEFT-TO-RIGHT EMBEDDING
+     *
+     * Treat the following text as embedded left-to-right.
+     *
+     * Use [PDF] to end the embedding.
+     */
+    const val LRE = "\u202A"
+
+    /**
+     * U+202B RIGHT-TO-LEFT EMBEDDING
+     *
+     * Treat the following text as embedded right-to-left.
+     *
+     * Use [PDF] to end the embedding.
+     */
+    const val RLE = "\u202B"
+
+    /**
+     * U+202C POP DIRECTIONAL FORMATTING
+     *
+     * End the scope of the last [LRE], [RLE], [RLO], or [LRO].
+     */
+    const val PDF = "\u202C"
+
+    /**
+     * U+202A LEFT-TO-RIGHT OVERRIDE
+     *
+     * Force following characters to be treated as strong left-to-right characters.
+     *
+     * For example, this causes Hebrew text to render backwards.
+     *
+     * Use [PDF] to end the override.
+     */
+    const val LRO = "\u202D"
+
+    /**
+     * U+202B RIGHT-TO-LEFT OVERRIDE
+     *
+     * Force following characters to be treated as strong right-to-left characters.
+     *
+     * For example, this causes English text to render backwards.
+     *
+     * Use [PDF] to end the override.
+     */
+    const val RLO = "\u202E"
+
+    /**
+     * U+2066 LEFT-TO-RIGHT ISOLATE
+     *
+     * Treat the following text as isolated and left-to-right.
+     *
+     * Use [PDI] to end the isolated scope.
+     */
+    const val LRI = "\u2066"
+
+    /**
+     * U+2067 RIGHT-TO-LEFT ISOLATE
+     *
+     * Treat the following text as isolated and right-to-left.
+     *
+     * Use [PDI] to end the isolated scope.
+     */
+    const val RLI = "\u2067"
+
+    /**
+     * U+2068 FIRST STRONG ISOLATE
+     *
+     * Treat the following text as isolated and in the direction of its first
+     * strong directional character that is not inside a nested isolate.
+     *
+     * This essentially "autodetects" the directionality of the text. It is not
+     * 100% reliable. For example, Arabic text that starts with an English quote
+     * will be detected as LTR, not RTL, which will lead to the text being in a
+     * weird order.
+     *
+     * Use [PDI] to end the isolated scope.
+     */
+    const val FSI = "\u2068"
+
+    /**
+     * U+2069 POP DIRECTIONAL ISOLATE
+     *
+     * End the scope of the last [LRI], [RLI], or [FSI].
+     */
+    const val PDI = "\u2069"
+
+    /**
+     * U+200E LEFT-TO-RIGHT MARK
+     *
+     * Left-to-right zero-width character.
+     */
+    const val LRM = "\u200E"
+
+    /**
+     * U+200F RIGHT-TO-LEFT MARK
+     *
+     * Right-to-left zero-width non-Arabic character.
+     */
+    const val RLM = "\u200F"
+
+    /**
+     * U+061C ARABIC LETTER MARK
+     *
+     * Right-to-left zero-width Arabic character.
+     */
+    const val ALM = "\u061C"
+}
\ No newline at end of file
diff --git a/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidAutofillTest.kt b/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidAutofillTest.kt
new file mode 100644
index 0000000..a135080
--- /dev/null
+++ b/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidAutofillTest.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2019 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.ui.autofill
+
+import android.content.Context
+import android.graphics.Rect
+import android.view.View
+import android.view.autofill.AutofillManager
+import androidx.test.filters.SmallTest
+import com.nhaarman.mockitokotlin2.eq
+import com.nhaarman.mockitokotlin2.mock
+import com.nhaarman.mockitokotlin2.whenever
+import com.nhaarman.mockitokotlin2.times
+import com.nhaarman.mockitokotlin2.verify
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.ExpectedException
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class AndroidAutofillTest {
+
+    @get:Rule
+    val expectedException = ExpectedException.none()!!
+
+    private lateinit var androidAutofill: AndroidAutofill
+    private lateinit var autofillManager: AutofillManager
+    private lateinit var view: View
+    private val autofillTree = AutofillTree()
+
+    @Before
+    fun setup() {
+        autofillManager = mock()
+
+        val context: Context = mock()
+        whenever(context.getSystemService(eq(AutofillManager::class.java)))
+            .thenReturn(autofillManager)
+
+        view = mock()
+        whenever(view.context).thenReturn(context)
+
+        androidAutofill = AndroidAutofill(view, autofillTree)
+    }
+
+    @Test
+    fun importantForAutofill_is_yes() {
+        verify(view).setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_YES)
+    }
+
+    @Test
+    fun requestAutofillForNode_calls_notifyViewEntered() {
+        // Arrange.
+        val autofillNode = AutofillNode(onFill = {}, boundingBox = Rect(0, 0, 0, 0))
+
+        // Act.
+        androidAutofill.requestAutofillForNode(autofillNode)
+
+        // Assert.
+        verify(autofillManager, times(1))
+            .notifyViewEntered(view, autofillNode.id, autofillNode.boundingBox!!)
+    }
+
+    @Test
+    fun requestAutofillForNode_beforeComposableIsPositioned_throwsError() {
+        // Arrange - Before the composable is positioned, the boundingBox is null.
+        val autofillNode = AutofillNode(onFill = {})
+
+        // Assert.
+        expectedException.expectMessage("requestAutofill called before onChildPositioned()")
+
+        // Act.
+        androidAutofill.requestAutofillForNode(autofillNode)
+    }
+
+    @Test
+    fun cancelAutofillForNode_calls_notifyViewExited() {
+        // Arrange.
+        val autofillNode = AutofillNode(onFill = {})
+
+        // Act.
+        androidAutofill.cancelAutofillForNode(autofillNode)
+
+        // Assert.
+        verify(autofillManager, times(1)).notifyViewExited(view, autofillNode.id)
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidFakes.kt b/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidFakes.kt
new file mode 100644
index 0000000..0d539e3
--- /dev/null
+++ b/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidFakes.kt
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2019 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.ui.autofill
+
+import android.graphics.Matrix
+import android.graphics.Rect
+import android.os.Bundle
+import android.os.LocaleList
+import android.util.SparseArray
+import android.view.View
+import android.view.ViewStructure
+import android.view.autofill.AutofillId
+import android.view.autofill.AutofillValue
+import com.nhaarman.mockitokotlin2.mock
+
+/**
+ * A fake implementation of { SparseArray } to use in tests.
+ */
+internal class FakeSparseArray : SparseArray<AutofillValue>() {
+
+    private val map = mutableMapOf<Int, AutofillValue>()
+
+    override fun append(key: Int, value: AutofillValue?) {
+        value?.let { map.putIfAbsent(key, it) }
+    }
+
+    override fun size() = map.count()
+
+    override fun keyAt(index: Int) = map.asSequence().elementAt(index).component1()
+
+    override fun get(key: Int) = map[key] ?: error("no element for the specified key")
+}
+
+/**
+ * A fake implementation of { ViewStructure } to use in tests.
+ */
+internal data class FakeViewStructure(
+    var virtualId: Int = 0,
+    var packageName: String? = null,
+    var typeName: String? = null,
+    var entryName: String? = null,
+    var children: MutableList<FakeViewStructure> = mutableListOf(),
+    var bounds: Rect? = null,
+    private val autofillId: AutofillId? = mock(),
+    private var autofillType: Int = View.AUTOFILL_TYPE_NONE,
+    private var autofillHints: Array<out String> = arrayOf()
+) : ViewStructure() {
+
+    override fun getChildCount() = children.count()
+
+    override fun addChildCount(childCount: Int): Int {
+        repeat(childCount) { children.add(FakeViewStructure()) }
+        return children.count() - childCount
+    }
+
+    override fun newChild(index: Int): FakeViewStructure {
+        if (index >= children.count()) error("Call addChildCount() before calling newChild()")
+        return children[index]
+    }
+
+    override fun getAutofillId() = autofillId
+
+    override fun setAutofillId(rootId: AutofillId, virtualId: Int) {
+        this.virtualId = virtualId
+    }
+
+    override fun setId(
+        virtualId: Int,
+        packageName: String?,
+        typeName: String?,
+        entryName: String?
+    ) {
+        this.virtualId = virtualId
+        this.packageName = packageName
+        this.typeName = typeName
+        this.entryName = entryName
+    }
+
+    override fun setAutofillType(autofillType: Int) {
+        this.autofillType = autofillType
+    }
+
+    override fun setAutofillHints(autofillHints: Array<out String>?) {
+        autofillHints?.let { this.autofillHints = it }
+    }
+
+    override fun setDimens(left: Int, top: Int, x: Int, y: Int, width: Int, height: Int) {
+        this.bounds = Rect(left, top, width - left, height - top)
+    }
+
+    override fun equals(other: Any?) = other is FakeViewStructure &&
+            other.virtualId == virtualId &&
+            other.packageName == packageName &&
+            other.typeName == typeName &&
+            other.entryName == entryName &&
+            other.autofillType == autofillType &&
+            other.autofillHints.contentEquals(autofillHints) &&
+            other.bounds.contentEquals(bounds) &&
+            other.children == children
+
+    override fun hashCode() = super.hashCode()
+
+    // Unimplemented methods.
+
+    override fun setOpaque(p0: Boolean) { TODO("not implemented") }
+
+    override fun setHint(p0: CharSequence?) { TODO("not implemented") }
+
+    override fun setElevation(p0: Float) { TODO("not implemented") }
+
+    override fun getText(): CharSequence { TODO("not implemented") }
+
+    override fun setText(p0: CharSequence?) { TODO("not implemented") }
+
+    override fun setText(p0: CharSequence?, p1: Int, p2: Int) { TODO("not implemented") }
+
+    override fun asyncCommit() { TODO("not implemented") }
+
+    override fun setEnabled(p0: Boolean) { TODO("not implemented") }
+
+    override fun setLocaleList(p0: LocaleList?) { TODO("not implemented") }
+
+    override fun setChecked(p0: Boolean) { TODO("not implemented") }
+
+    override fun setContextClickable(p0: Boolean) { TODO("not implemented") }
+
+    override fun setAccessibilityFocused(p0: Boolean) { TODO("not implemented") }
+
+    override fun setAlpha(p0: Float) { TODO("not implemented") }
+
+    override fun setTransformation(p0: Matrix?) { TODO("not implemented") }
+
+    override fun setClassName(p0: String?) { TODO("not implemented") }
+
+    override fun setLongClickable(p0: Boolean) { TODO("not implemented") }
+
+    override fun getHint(): CharSequence { TODO("not implemented") }
+
+    override fun setInputType(p0: Int) { TODO("not implemented") }
+
+    override fun setWebDomain(p0: String?) { TODO("not implemented") }
+
+    override fun setAutofillOptions(p0: Array<out CharSequence>?) { TODO("not implemented") }
+
+    override fun setTextStyle(p0: Float, p1: Int, p2: Int, p3: Int) { TODO("not implemented") }
+
+    override fun setVisibility(p0: Int) { TODO("not implemented") }
+
+    override fun setHtmlInfo(p0: HtmlInfo) { TODO("not implemented") }
+
+    override fun setTextLines(p0: IntArray?, p1: IntArray?) { TODO("not implemented") }
+
+    override fun getExtras(): Bundle { TODO("not implemented") }
+
+    override fun setClickable(p0: Boolean) { TODO("not implemented") }
+
+    override fun newHtmlInfoBuilder(p0: String): HtmlInfo.Builder { TODO("not implemented") }
+
+    override fun getTextSelectionEnd(): Int { TODO("not implemented") }
+
+    override fun setAutofillId(p0: AutofillId) { TODO("not implemented") }
+
+    override fun hasExtras(): Boolean { TODO("not implemented") }
+
+    override fun setActivated(p0: Boolean) { TODO("not implemented") }
+
+    override fun setFocused(p0: Boolean) { TODO("not implemented") }
+
+    override fun getTextSelectionStart(): Int { TODO("not implemented") }
+
+    override fun setChildCount(p0: Int) { TODO("not implemented") }
+
+    override fun setAutofillValue(p0: AutofillValue?) { TODO("not implemented") }
+
+    override fun setContentDescription(p0: CharSequence?) { TODO("not implemented") }
+
+    override fun setFocusable(p0: Boolean) { TODO("not implemented") }
+
+    override fun setCheckable(p0: Boolean) { TODO("not implemented") }
+
+    override fun asyncNewChild(p0: Int): ViewStructure { TODO("not implemented") }
+
+    override fun setSelected(p0: Boolean) { TODO("not implemented") }
+
+    override fun setDataIsSensitive(p0: Boolean) { TODO("not implemented") }
+}
+
+private fun Rect?.contentEquals(other: Rect?) = when {
+    (other == null && this == null) -> true
+    (other == null || this == null) -> false
+    else -> other.left == left &&
+            other.right == right &&
+            other.bottom == bottom &&
+            other.top == top
+}
\ No newline at end of file
diff --git a/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidPerformAutofillTest.kt b/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidPerformAutofillTest.kt
new file mode 100644
index 0000000..6acec9c
--- /dev/null
+++ b/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidPerformAutofillTest.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2019 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.ui.autofill
+
+import android.content.Context
+import android.graphics.Rect
+import android.view.View
+import android.view.autofill.AutofillManager
+import android.view.autofill.AutofillValue
+import androidx.test.filters.SmallTest
+import com.nhaarman.mockitokotlin2.eq
+import com.nhaarman.mockitokotlin2.mock
+import com.nhaarman.mockitokotlin2.times
+import com.nhaarman.mockitokotlin2.verify
+import com.nhaarman.mockitokotlin2.whenever
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class AndroidPerformAutofillTest {
+    private val autofillTree = AutofillTree()
+    private lateinit var androidAutofill: AndroidAutofill
+
+    @Before
+    fun setup() {
+        val autofillManager: AutofillManager = mock()
+
+        val context: Context = mock()
+        whenever(context.getSystemService(eq(AutofillManager::class.java)))
+            .thenReturn(autofillManager)
+
+        val view: View = mock()
+        whenever(view.context).thenReturn(context)
+
+        androidAutofill = AndroidAutofill(view, autofillTree)
+    }
+
+    @Test
+    fun performAutofill_name() {
+        // Arrange.
+        val onFill: (String) -> Unit = mock()
+        val autofillNode = AutofillNode(
+            onFill = onFill,
+            autofillTypes = listOf(AutofillType.Name),
+            boundingBox = Rect(0, 0, 0, 0)
+        )
+        autofillTree += autofillNode
+
+        val autofillValue: AutofillValue = mock()
+        whenever(autofillValue.isText).thenReturn(true)
+        whenever(autofillValue.textValue).thenReturn("First Name")
+
+        val autofillValues = FakeSparseArray().apply { append(autofillNode.id, autofillValue) }
+
+        // Act.
+        androidAutofill.performAutofill(autofillValues)
+
+        // Assert.
+        verify(onFill, times(1)).invoke("First Name")
+    }
+
+    @Test
+    fun performAutofill_email() {
+        // Arrange.
+        val onFill: (String) -> Unit = mock()
+        val autofillNode = AutofillNode(
+            onFill = onFill,
+            autofillTypes = listOf(AutofillType.EmailAddress),
+            boundingBox = Rect(0, 0, 0, 0)
+        )
+        autofillTree += autofillNode
+
+        val autofillValue: AutofillValue = mock()
+        whenever(autofillValue.isText).thenReturn(true)
+        whenever(autofillValue.textValue).thenReturn("email@google.com")
+
+        val autofillValues = FakeSparseArray().apply { append(autofillNode.id, autofillValue) }
+
+        // Act.
+        androidAutofill.performAutofill(autofillValues)
+
+        // Assert.
+        verify(onFill, times(1)).invoke("email@google.com")
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidPopulateViewStructureTest.kt b/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidPopulateViewStructureTest.kt
new file mode 100644
index 0000000..db8c641
--- /dev/null
+++ b/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidPopulateViewStructureTest.kt
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2019 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.ui.autofill
+
+import android.content.Context
+import android.graphics.Rect
+import android.view.View
+import android.view.ViewStructure
+import android.view.autofill.AutofillManager
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import com.nhaarman.mockitokotlin2.eq
+import com.nhaarman.mockitokotlin2.mock
+import com.nhaarman.mockitokotlin2.whenever
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class AndroidPopulateViewStructureTest {
+    private val autofillTree = AutofillTree()
+    private lateinit var androidAutofill: AndroidAutofill
+
+    @Before
+    fun setup() {
+        val autofillManager: AutofillManager = mock()
+
+        val context: Context = mock()
+        whenever(context.getSystemService(eq(AutofillManager::class.java)))
+            .thenReturn(autofillManager)
+        whenever(context.packageName).thenReturn("com.google.testpackage")
+
+        val view: View = mock()
+        whenever(view.context).thenReturn(context)
+
+        androidAutofill = AndroidAutofill(view, autofillTree)
+    }
+
+    @Test
+    fun populateViewStructure_emptyAutofillTree() {
+        // Arrange.
+        val viewStructure: ViewStructure = FakeViewStructure()
+
+        // Act.
+        androidAutofill.populateViewStructure(viewStructure)
+
+        // Assert.
+        assertThat(viewStructure.childCount).isEqualTo(0)
+    }
+
+    @Test
+    fun populateViewStructure_oneChild() {
+        // Arrange.
+        val autofillNode = AutofillNode(
+            onFill = {},
+            autofillTypes = listOf(AutofillType.Name),
+            boundingBox = Rect(0, 0, 0, 0)
+        )
+        autofillTree += autofillNode
+
+        // Act.
+        val viewStructure = FakeViewStructure()
+        androidAutofill.populateViewStructure(viewStructure)
+
+        // Assert.
+        assertThat(viewStructure).isEqualTo(FakeViewStructure().apply {
+            children.add(FakeViewStructure().apply {
+                virtualId = autofillNode.id
+                packageName = "com.google.testpackage"
+                setAutofillType(View.AUTOFILL_TYPE_TEXT)
+                setAutofillHints(arrayOf(View.AUTOFILL_HINT_NAME))
+                setDimens(0, 0, 0, 0, 0, 0)
+            })
+        })
+    }
+
+    @Test
+    fun populateViewStructure_twoChildren() {
+        // Arrange.
+        val nameAutofillNode = AutofillNode(
+            onFill = {},
+            autofillTypes = listOf(AutofillType.Name),
+            boundingBox = Rect(0, 0, 0, 0)
+        )
+        autofillTree += nameAutofillNode
+
+        val emailAutofillNode = AutofillNode(
+            onFill = {},
+            autofillTypes = listOf(AutofillType.EmailAddress),
+            boundingBox = Rect(0, 0, 0, 0)
+        )
+        autofillTree += emailAutofillNode
+
+        // Act.
+        val viewStructure: ViewStructure = FakeViewStructure()
+        androidAutofill.populateViewStructure(viewStructure)
+
+        // Assert.
+        assertThat(viewStructure).isEqualTo(FakeViewStructure().apply {
+            children.add(FakeViewStructure().apply {
+                virtualId = nameAutofillNode.id
+                packageName = "com.google.testpackage"
+                setAutofillType(View.AUTOFILL_TYPE_TEXT)
+                setAutofillHints(arrayOf(View.AUTOFILL_HINT_NAME))
+                setDimens(0, 0, 0, 0, 0, 0)
+            })
+            children.add(FakeViewStructure().apply {
+                virtualId = emailAutofillNode.id
+                packageName = "com.google.testpackage"
+                setAutofillType(View.AUTOFILL_TYPE_TEXT)
+                setAutofillHints(arrayOf(View.AUTOFILL_HINT_EMAIL_ADDRESS))
+                setDimens(0, 0, 0, 0, 0, 0)
+            })
+        })
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-test/api/1.0.0-alpha01.txt b/ui/ui-test/api/1.0.0-alpha01.txt
index 89f2433..9fd8bf1 100644
--- a/ui/ui-test/api/1.0.0-alpha01.txt
+++ b/ui/ui-test/api/1.0.0-alpha01.txt
@@ -13,14 +13,15 @@
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsChecked(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsHidden(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsInMutuallyExclusiveGroup(androidx.ui.test.SemanticsNodeInteraction);
-    method public static androidx.ui.test.SemanticsNodeInteraction assertIsNotChecked(androidx.ui.test.SemanticsNodeInteraction);
-    method public static androidx.ui.test.SemanticsNodeInteraction assertIsNotSelected(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsSelected(androidx.ui.test.SemanticsNodeInteraction);
+    method public static androidx.ui.test.SemanticsNodeInteraction assertIsUnchecked(androidx.ui.test.SemanticsNodeInteraction);
+    method public static androidx.ui.test.SemanticsNodeInteraction assertIsUnselected(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsVisible(androidx.ui.test.SemanticsNodeInteraction);
     method public static void assertNoLongerExists(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertSemanticsIsEqualTo(androidx.ui.test.SemanticsNodeInteraction, androidx.ui.core.semantics.SemanticsConfiguration expectedProperties);
     method public static void assertStillExists(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertValueEquals(androidx.ui.test.SemanticsNodeInteraction, String value);
+    method public static void verify(androidx.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.String> assertionMessage, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> condition);
   }
 
   public final class CollectedSizes {
@@ -59,13 +60,15 @@
 
   public final class FiltersKt {
     ctor public FiltersKt();
-    method public static boolean isCheckable(androidx.ui.core.semantics.SemanticsConfiguration);
+    method public static boolean isInMutuallyExclusiveGroup(androidx.ui.core.semantics.SemanticsConfiguration);
+    method public static boolean isToggleable(androidx.ui.core.semantics.SemanticsConfiguration);
   }
 
   public final class FindersKt {
     ctor public FindersKt();
     method public static androidx.ui.test.SemanticsNodeInteraction find(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
     method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAll(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
+    method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAllByTag(String testTag);
     method public static androidx.ui.test.SemanticsNodeInteraction findByTag(String testTag);
     method public static androidx.ui.test.SemanticsNodeInteraction findByText(String text, boolean ignoreCase = false);
   }
@@ -74,7 +77,7 @@
     ctor public GoldenSemanticsKt();
     method public static void assertEquals(androidx.ui.core.semantics.SemanticsConfiguration, androidx.ui.core.semantics.SemanticsConfiguration expected);
     method public static androidx.ui.core.semantics.SemanticsConfiguration copyWith(androidx.ui.core.semantics.SemanticsConfiguration, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,kotlin.Unit> diff);
-    method public static androidx.ui.core.semantics.SemanticsConfiguration createFullSemantics(Boolean? isEnabled = null, Boolean? isChecked = null, boolean isSelected = false, boolean isButton = false, boolean inMutuallyExclusiveGroup = false);
+    method public static androidx.ui.core.semantics.SemanticsConfiguration createFullSemantics(Boolean? isEnabled = null, String? value = null, androidx.ui.foundation.selection.ToggleableState? toggleableState = null, Boolean? inMutuallyExclusiveGroup = null, Boolean? isSelected = null);
   }
 
   public final class OutputKt {
diff --git a/ui/ui-test/api/current.txt b/ui/ui-test/api/current.txt
index 89f2433..9fd8bf1 100644
--- a/ui/ui-test/api/current.txt
+++ b/ui/ui-test/api/current.txt
@@ -13,14 +13,15 @@
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsChecked(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsHidden(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsInMutuallyExclusiveGroup(androidx.ui.test.SemanticsNodeInteraction);
-    method public static androidx.ui.test.SemanticsNodeInteraction assertIsNotChecked(androidx.ui.test.SemanticsNodeInteraction);
-    method public static androidx.ui.test.SemanticsNodeInteraction assertIsNotSelected(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsSelected(androidx.ui.test.SemanticsNodeInteraction);
+    method public static androidx.ui.test.SemanticsNodeInteraction assertIsUnchecked(androidx.ui.test.SemanticsNodeInteraction);
+    method public static androidx.ui.test.SemanticsNodeInteraction assertIsUnselected(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsVisible(androidx.ui.test.SemanticsNodeInteraction);
     method public static void assertNoLongerExists(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertSemanticsIsEqualTo(androidx.ui.test.SemanticsNodeInteraction, androidx.ui.core.semantics.SemanticsConfiguration expectedProperties);
     method public static void assertStillExists(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertValueEquals(androidx.ui.test.SemanticsNodeInteraction, String value);
+    method public static void verify(androidx.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.String> assertionMessage, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> condition);
   }
 
   public final class CollectedSizes {
@@ -59,13 +60,15 @@
 
   public final class FiltersKt {
     ctor public FiltersKt();
-    method public static boolean isCheckable(androidx.ui.core.semantics.SemanticsConfiguration);
+    method public static boolean isInMutuallyExclusiveGroup(androidx.ui.core.semantics.SemanticsConfiguration);
+    method public static boolean isToggleable(androidx.ui.core.semantics.SemanticsConfiguration);
   }
 
   public final class FindersKt {
     ctor public FindersKt();
     method public static androidx.ui.test.SemanticsNodeInteraction find(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
     method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAll(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
+    method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAllByTag(String testTag);
     method public static androidx.ui.test.SemanticsNodeInteraction findByTag(String testTag);
     method public static androidx.ui.test.SemanticsNodeInteraction findByText(String text, boolean ignoreCase = false);
   }
@@ -74,7 +77,7 @@
     ctor public GoldenSemanticsKt();
     method public static void assertEquals(androidx.ui.core.semantics.SemanticsConfiguration, androidx.ui.core.semantics.SemanticsConfiguration expected);
     method public static androidx.ui.core.semantics.SemanticsConfiguration copyWith(androidx.ui.core.semantics.SemanticsConfiguration, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,kotlin.Unit> diff);
-    method public static androidx.ui.core.semantics.SemanticsConfiguration createFullSemantics(Boolean? isEnabled = null, Boolean? isChecked = null, boolean isSelected = false, boolean isButton = false, boolean inMutuallyExclusiveGroup = false);
+    method public static androidx.ui.core.semantics.SemanticsConfiguration createFullSemantics(Boolean? isEnabled = null, String? value = null, androidx.ui.foundation.selection.ToggleableState? toggleableState = null, Boolean? inMutuallyExclusiveGroup = null, Boolean? isSelected = null);
   }
 
   public final class OutputKt {
diff --git a/ui/ui-test/api/restricted_1.0.0-alpha01.txt b/ui/ui-test/api/restricted_1.0.0-alpha01.txt
index 89f2433..9fd8bf1 100644
--- a/ui/ui-test/api/restricted_1.0.0-alpha01.txt
+++ b/ui/ui-test/api/restricted_1.0.0-alpha01.txt
@@ -13,14 +13,15 @@
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsChecked(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsHidden(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsInMutuallyExclusiveGroup(androidx.ui.test.SemanticsNodeInteraction);
-    method public static androidx.ui.test.SemanticsNodeInteraction assertIsNotChecked(androidx.ui.test.SemanticsNodeInteraction);
-    method public static androidx.ui.test.SemanticsNodeInteraction assertIsNotSelected(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsSelected(androidx.ui.test.SemanticsNodeInteraction);
+    method public static androidx.ui.test.SemanticsNodeInteraction assertIsUnchecked(androidx.ui.test.SemanticsNodeInteraction);
+    method public static androidx.ui.test.SemanticsNodeInteraction assertIsUnselected(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsVisible(androidx.ui.test.SemanticsNodeInteraction);
     method public static void assertNoLongerExists(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertSemanticsIsEqualTo(androidx.ui.test.SemanticsNodeInteraction, androidx.ui.core.semantics.SemanticsConfiguration expectedProperties);
     method public static void assertStillExists(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertValueEquals(androidx.ui.test.SemanticsNodeInteraction, String value);
+    method public static void verify(androidx.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.String> assertionMessage, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> condition);
   }
 
   public final class CollectedSizes {
@@ -59,13 +60,15 @@
 
   public final class FiltersKt {
     ctor public FiltersKt();
-    method public static boolean isCheckable(androidx.ui.core.semantics.SemanticsConfiguration);
+    method public static boolean isInMutuallyExclusiveGroup(androidx.ui.core.semantics.SemanticsConfiguration);
+    method public static boolean isToggleable(androidx.ui.core.semantics.SemanticsConfiguration);
   }
 
   public final class FindersKt {
     ctor public FindersKt();
     method public static androidx.ui.test.SemanticsNodeInteraction find(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
     method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAll(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
+    method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAllByTag(String testTag);
     method public static androidx.ui.test.SemanticsNodeInteraction findByTag(String testTag);
     method public static androidx.ui.test.SemanticsNodeInteraction findByText(String text, boolean ignoreCase = false);
   }
@@ -74,7 +77,7 @@
     ctor public GoldenSemanticsKt();
     method public static void assertEquals(androidx.ui.core.semantics.SemanticsConfiguration, androidx.ui.core.semantics.SemanticsConfiguration expected);
     method public static androidx.ui.core.semantics.SemanticsConfiguration copyWith(androidx.ui.core.semantics.SemanticsConfiguration, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,kotlin.Unit> diff);
-    method public static androidx.ui.core.semantics.SemanticsConfiguration createFullSemantics(Boolean? isEnabled = null, Boolean? isChecked = null, boolean isSelected = false, boolean isButton = false, boolean inMutuallyExclusiveGroup = false);
+    method public static androidx.ui.core.semantics.SemanticsConfiguration createFullSemantics(Boolean? isEnabled = null, String? value = null, androidx.ui.foundation.selection.ToggleableState? toggleableState = null, Boolean? inMutuallyExclusiveGroup = null, Boolean? isSelected = null);
   }
 
   public final class OutputKt {
diff --git a/ui/ui-test/api/restricted_current.txt b/ui/ui-test/api/restricted_current.txt
index 89f2433..9fd8bf1 100644
--- a/ui/ui-test/api/restricted_current.txt
+++ b/ui/ui-test/api/restricted_current.txt
@@ -13,14 +13,15 @@
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsChecked(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsHidden(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsInMutuallyExclusiveGroup(androidx.ui.test.SemanticsNodeInteraction);
-    method public static androidx.ui.test.SemanticsNodeInteraction assertIsNotChecked(androidx.ui.test.SemanticsNodeInteraction);
-    method public static androidx.ui.test.SemanticsNodeInteraction assertIsNotSelected(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsSelected(androidx.ui.test.SemanticsNodeInteraction);
+    method public static androidx.ui.test.SemanticsNodeInteraction assertIsUnchecked(androidx.ui.test.SemanticsNodeInteraction);
+    method public static androidx.ui.test.SemanticsNodeInteraction assertIsUnselected(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertIsVisible(androidx.ui.test.SemanticsNodeInteraction);
     method public static void assertNoLongerExists(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertSemanticsIsEqualTo(androidx.ui.test.SemanticsNodeInteraction, androidx.ui.core.semantics.SemanticsConfiguration expectedProperties);
     method public static void assertStillExists(androidx.ui.test.SemanticsNodeInteraction);
     method public static androidx.ui.test.SemanticsNodeInteraction assertValueEquals(androidx.ui.test.SemanticsNodeInteraction, String value);
+    method public static void verify(androidx.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.String> assertionMessage, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> condition);
   }
 
   public final class CollectedSizes {
@@ -59,13 +60,15 @@
 
   public final class FiltersKt {
     ctor public FiltersKt();
-    method public static boolean isCheckable(androidx.ui.core.semantics.SemanticsConfiguration);
+    method public static boolean isInMutuallyExclusiveGroup(androidx.ui.core.semantics.SemanticsConfiguration);
+    method public static boolean isToggleable(androidx.ui.core.semantics.SemanticsConfiguration);
   }
 
   public final class FindersKt {
     ctor public FindersKt();
     method public static androidx.ui.test.SemanticsNodeInteraction find(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
     method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAll(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
+    method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAllByTag(String testTag);
     method public static androidx.ui.test.SemanticsNodeInteraction findByTag(String testTag);
     method public static androidx.ui.test.SemanticsNodeInteraction findByText(String text, boolean ignoreCase = false);
   }
@@ -74,7 +77,7 @@
     ctor public GoldenSemanticsKt();
     method public static void assertEquals(androidx.ui.core.semantics.SemanticsConfiguration, androidx.ui.core.semantics.SemanticsConfiguration expected);
     method public static androidx.ui.core.semantics.SemanticsConfiguration copyWith(androidx.ui.core.semantics.SemanticsConfiguration, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,kotlin.Unit> diff);
-    method public static androidx.ui.core.semantics.SemanticsConfiguration createFullSemantics(Boolean? isEnabled = null, Boolean? isChecked = null, boolean isSelected = false, boolean isButton = false, boolean inMutuallyExclusiveGroup = false);
+    method public static androidx.ui.core.semantics.SemanticsConfiguration createFullSemantics(Boolean? isEnabled = null, String? value = null, androidx.ui.foundation.selection.ToggleableState? toggleableState = null, Boolean? inMutuallyExclusiveGroup = null, Boolean? isSelected = null);
   }
 
   public final class OutputKt {
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/FindAllTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/FindAllTest.kt
index a3f0036..188d2786 100644
--- a/ui/ui-test/src/androidTest/java/androidx/ui/test/FindAllTest.kt
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/FindAllTest.kt
@@ -20,6 +20,9 @@
 import androidx.compose.state
 import androidx.compose.unaryPlus
 import androidx.test.filters.MediumTest
+import androidx.ui.core.semantics.getOrNull
+import androidx.ui.foundation.selection.ToggleableState
+import androidx.ui.foundation.semantics.FoundationSemanticsProperties
 import androidx.ui.layout.Column
 import androidx.ui.material.Checkbox
 import androidx.ui.material.MaterialTheme
@@ -49,7 +52,10 @@
             }
         }
 
-        findAll { isCheckable() && isChecked == true }
+        findAll {
+            getOrNull(FoundationSemanticsProperties.ToggleableState) == ToggleableState.Checked
+        }
+            .assertCountEquals(2)
             .forEach {
                 it.assertIsChecked()
             }
@@ -76,7 +82,8 @@
             }
         }
 
-        findAll { isCheckable() }
+        findAll { isToggleable }
+            .assertCountEquals(2)
             .forEach {
                 it.doClick()
                 it.assertIsChecked()
@@ -84,7 +91,7 @@
     }
 
     @Test
-    fun findAllTest_noCheckedComponent() {
+    fun findAllTest_noNonCheckedComponent() {
         composeTestRule.setContent {
             MaterialTheme {
                 Surface {
@@ -96,7 +103,9 @@
             }
         }
 
-        findAll { isCheckable() && isChecked == false }
+        findAll {
+            getOrNull(FoundationSemanticsProperties.ToggleableState) != ToggleableState.Checked
+        }
             .assertCountEquals(0)
     }
 
@@ -122,12 +131,12 @@
             }
         }
 
-        findAll { isCheckable() }.apply {
+        findAll { isToggleable }.apply {
             get(0)
                 .doClick()
                 .assertIsChecked()
             get(1)
-                .assertIsNotChecked()
+                .assertIsUnchecked()
         }.assertCountEquals(2)
     }
 
@@ -161,16 +170,16 @@
             }
         }
 
-        findAll { isCheckable() }.apply {
+        findAll { isToggleable }.assertCountEquals(2).apply {
             get(0)
-                .assertIsNotChecked()
+                .assertIsUnchecked()
                 .doClick()
                 .assertIsChecked()
         }
 
-        findAll { isCheckable() }.apply {
+        findAll { isToggleable }.assertCountEquals(3).apply {
             get(2)
-                .assertIsNotChecked()
+                .assertIsUnchecked()
         }
     }
 
@@ -199,9 +208,9 @@
             }
         }
 
-        findAll { isCheckable() }.apply {
+        findAll { isToggleable }.assertCountEquals(2).apply {
             get(0)
-                .assertIsNotChecked()
+                .assertIsUnchecked()
                 .doClick()
                 .assertIsChecked()
             get(1)
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/MultipleComposeRootsTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/MultipleComposeRootsTest.kt
index 9f77236..f8684d7 100644
--- a/ui/ui-test/src/androidTest/java/androidx/ui/test/MultipleComposeRootsTest.kt
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/MultipleComposeRootsTest.kt
@@ -19,8 +19,8 @@
 import android.widget.FrameLayout
 import android.widget.LinearLayout
 import android.widget.TextView
-import androidx.compose.composer
 import androidx.compose.Model
+import androidx.compose.composer
 import androidx.test.espresso.Espresso
 import androidx.test.espresso.assertion.ViewAssertions.matches
 import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
@@ -157,14 +157,14 @@
             .assertIsChecked()
 
         findByTag("checkbox2")
-            .assertIsNotChecked()
+            .assertIsUnchecked()
 
         Espresso.onView(withText("Compose 1 - Checked")).check(matches(isDisplayed()))
         Espresso.onView(withText("Compose 2 - Unchecked")).check(matches(isDisplayed()))
 
         findByTag("checkbox2")
             .doClick()
-            .assertIsNotChecked()
+            .assertIsUnchecked()
 
         findByTag("checkbox1")
             .assertIsChecked()
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/Assertions.kt b/ui/ui-test/src/main/java/androidx/ui/test/Assertions.kt
index 4e44b90..7f0debd 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/Assertions.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/Assertions.kt
@@ -17,6 +17,11 @@
 package androidx.ui.test
 
 import androidx.ui.core.semantics.SemanticsConfiguration
+import androidx.ui.core.semantics.getOrNull
+import androidx.ui.foundation.selection.ToggleableState
+import androidx.ui.foundation.semantics.FoundationSemanticsProperties
+import androidx.ui.semantics.SemanticsProperties
+import androidx.ui.semantics.accessibilityValue
 
 /**
  * Asserts no items found given a criteria, throws [AssertionError] otherwise.
@@ -38,7 +43,7 @@
 // TODO(b/123702531): Provide guarantees of being visible VS being actually displayed
 fun SemanticsNodeInteraction.assertIsVisible(): SemanticsNodeInteraction {
     verify({ "The component is not visible!" }) {
-        !it.isHidden
+        it.getOrNull(SemanticsProperties.Hidden) != true
     }
     return this
 }
@@ -50,7 +55,7 @@
  */
 fun SemanticsNodeInteraction.assertIsHidden(): SemanticsNodeInteraction {
     verify({ "The component is visible!" }) {
-        it.isHidden
+        it.getOrNull(SemanticsProperties.Hidden) == true
     }
 
     return this
@@ -77,46 +82,57 @@
 
 /**
  * Asserts that the current component is checked.
+ *
+ * Throws [AssertionError] if the component is not unchecked, indeterminate, or not toggleable.
  */
 fun SemanticsNodeInteraction.assertIsChecked(): SemanticsNodeInteraction {
-        // TODO(pavlis): Throw exception if component is not checkable
-    verify({ "The component is not checked!" }) {
-        it.isChecked == true
+    verify({ "Component is toggled off, expected it to be toggled on" }) {
+        it.getOrElse(FoundationSemanticsProperties.ToggleableState) {
+            throw AssertionError("Component is not toggleable")
+        } == ToggleableState.Checked
     }
     return this
 }
 
 /**
- * Asserts that the current component is not checked.
+ * Asserts that the current component is unchecked.
+ *
+ * Throws [AssertionError] if the component is checked, indeterminate, or not toggleable.
  */
-fun SemanticsNodeInteraction.assertIsNotChecked(): SemanticsNodeInteraction {
-        // TODO(pavlis): Throw exception if component is not checkable
-    verify({ "The component is checked!" }) {
-        it.isChecked != true
+fun SemanticsNodeInteraction.assertIsUnchecked(): SemanticsNodeInteraction {
+    verify({ "Component is toggled on, expected it to be toggled off" }) {
+        it.getOrElse(FoundationSemanticsProperties.ToggleableState) {
+            throw AssertionError("Component is not toggleable")
+        } == ToggleableState.Unchecked
     }
+
     return this
 }
 
 /**
  * Asserts that the current component is selected.
+ *
+ * Throws [AssertionError] if the component is unselected or not selectable.
  */
 fun SemanticsNodeInteraction.assertIsSelected(): SemanticsNodeInteraction {
-        // TODO(pavlis): Throw exception if component is not selectable
-    verify(
-        { "The component is expected to be selected" }) {
-        it.isSelected == true
+    verify({ "Component is unselected, expected it to be selected" }) {
+        it.getOrElse(FoundationSemanticsProperties.Selected) {
+            throw AssertionError("Component is not selectable")
+        }
     }
     return this
 }
 
 /**
- * Asserts that the current component is not selected.
+ * Asserts that the current component is unselected.
+ *
+ * Throws [AssertionError] if the component is selected or not selectable.
  */
-fun SemanticsNodeInteraction.assertIsNotSelected(): SemanticsNodeInteraction {
-    // TODO(pavlis): Throw exception if component is not selectable
-    verify(
-        { "The component is expected to not be selected!" }) {
-        it.isSelected == false
+fun SemanticsNodeInteraction.assertIsUnselected(): SemanticsNodeInteraction {
+    verify({ "Component is selected, expected it to be unselected" }) {
+        !it.getOrElse(FoundationSemanticsProperties.Selected) {
+            throw AssertionError("Component is not selectable")
+        }
     }
     return this
 }
@@ -129,7 +145,7 @@
 fun SemanticsNodeInteraction.assertIsInMutuallyExclusiveGroup(): SemanticsNodeInteraction {
     // TODO(pavlis): Throw exception if component is not selectable
     verify(
-        { "The component is expected to be mutually exclusive group, but it's not!" }) {
+        { "The component is expected to be in a mutually exclusive group, but it's not!" }) {
         it.isInMutuallyExclusiveGroup
     }
     return this
@@ -138,11 +154,14 @@
 /**
  * Asserts the component's value equals the given value. This is used by
  * [CircularProgressIndicator] to check progress.
- * For further details please check [SemanticsConfiguration.value].
+ * For further details please check [SemanticsConfiguration.accessibilityValue].
+ * Throws [AssertionError] if the node's value is not equal to `value`, or if the node has no value
  */
 fun SemanticsNodeInteraction.assertValueEquals(value: String): SemanticsNodeInteraction {
-    verify({ node -> "Expected value: $value Actual value: ${node.value}" }) {
-        it.value == value
+    verify({ node -> "Expected value: $value, Actual value: ${node.accessibilityValue}" }) {
+        it.getOrElse(SemanticsProperties.AccessibilityValue) {
+            throw AssertionError("Expected value: $value, but had none")
+        } == value
     }
     return this
 }
@@ -174,7 +193,11 @@
     return this
 }
 
-internal fun SemanticsNodeInteraction.verify(
+/**
+ * Verifies that the provided condition is true.
+ * Throws [AssertionError] if it is not.
+ */
+fun SemanticsNodeInteraction.verify(
     assertionMessage: (SemanticsConfiguration) -> String,
     condition: (SemanticsConfiguration) -> Boolean
 ) {
@@ -184,4 +207,4 @@
         // TODO(b/133217292)
         throw AssertionError("Assert failed: ${assertionMessage(semanticsTreeNode.data)}")
     }
-}
\ No newline at end of file
+}
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/Filters.kt b/ui/ui-test/src/main/java/androidx/ui/test/Filters.kt
index 428708a..3f3d8cb 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/Filters.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/Filters.kt
@@ -17,10 +17,20 @@
 package androidx.ui.test
 
 import androidx.ui.core.semantics.SemanticsConfiguration
+import androidx.ui.core.semantics.getOrNull
+import androidx.ui.foundation.semantics.FoundationSemanticsProperties
 
 /**
  * Verifies that a component is checkable.
  */
-fun SemanticsConfiguration.isCheckable(): Boolean {
-    return isChecked != null
-}
\ No newline at end of file
+val SemanticsConfiguration.isToggleable: Boolean
+    get() = contains(FoundationSemanticsProperties.ToggleableState)
+
+// TODO(ryanmentley/pavlis): Do we want these convenience functions?
+/**
+ * Verifies that a component is in a mutually exclusive group - that is,
+ * that [FoundationSemanticsProperties.InMutuallyExclusiveGroup] is set to true
+ *
+ */
+val SemanticsConfiguration.isInMutuallyExclusiveGroup: Boolean
+    get() = getOrNull(FoundationSemanticsProperties.InMutuallyExclusiveGroup) == true
\ No newline at end of file
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/Finders.kt b/ui/ui-test/src/main/java/androidx/ui/test/Finders.kt
index 12f0c78..fdb1cf8 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/Finders.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/Finders.kt
@@ -17,6 +17,8 @@
 package androidx.ui.test
 
 import androidx.ui.core.semantics.SemanticsConfiguration
+import androidx.ui.core.semantics.getOrNull
+import androidx.ui.semantics.SemanticsProperties
 
 /**
  * Extension methods that provide the entry point for the testing APIs.
@@ -29,7 +31,18 @@
  */
 fun findByTag(testTag: String): SemanticsNodeInteraction {
     return find {
-        this.testTag == testTag
+        getOrNull(SemanticsProperties.TestTag) == testTag
+    }
+}
+
+/**
+ * Finds all components identified by the given tag.
+ *
+ * For usage patterns see [SemanticsNodeInteraction]
+ */
+fun findAllByTag(testTag: String): List<SemanticsNodeInteraction> {
+    return findAll {
+        getOrNull(SemanticsProperties.TestTag) == testTag
     }
 }
 
@@ -40,7 +53,7 @@
  */
 fun findByText(text: String, ignoreCase: Boolean = false): SemanticsNodeInteraction {
     return find {
-        label.equals(text, ignoreCase)
+        getOrNull(SemanticsProperties.AccessibilityLabel).equals(text, ignoreCase)
     }
 }
 
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/GoldenSemantics.kt b/ui/ui-test/src/main/java/androidx/ui/test/GoldenSemantics.kt
index 87c1cba..85e1411 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/GoldenSemantics.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/GoldenSemantics.kt
@@ -17,6 +17,12 @@
 package androidx.ui.test
 
 import androidx.ui.core.semantics.SemanticsConfiguration
+import androidx.ui.foundation.selection.ToggleableState
+import androidx.ui.foundation.semantics.inMutuallyExclusiveGroup
+import androidx.ui.foundation.semantics.selected
+import androidx.ui.foundation.semantics.toggleableState
+import androidx.ui.semantics.enabled
+import androidx.ui.semantics.accessibilityValue
 
 /**
  * Ensures the created [SemanticsConfiguration] object doesn't have any default values set.
@@ -27,17 +33,19 @@
 // TODO(b/131309551): investigate the structure of this API
 fun createFullSemantics(
     isEnabled: Boolean? = null,
-    isChecked: Boolean? = null,
-    isSelected: Boolean = false,
-    isButton: Boolean = false,
-    inMutuallyExclusiveGroup: Boolean = false
+    value: String? = null,
+    toggleableState: ToggleableState? = null,
+    inMutuallyExclusiveGroup: Boolean? = null,
+    isSelected: Boolean? = null
 ): SemanticsConfiguration {
     return SemanticsConfiguration().also {
-        it.isEnabled = isEnabled
-        it.isChecked = isChecked
-        it.isInMutuallyExclusiveGroup = inMutuallyExclusiveGroup
-        it.isSelected = isSelected
-        it.isButton = isButton
+        isEnabled?.also { isEnabled -> it.enabled = isEnabled }
+        value?.also { value -> it.accessibilityValue = value }
+        toggleableState?.also { toggleableState -> it.toggleableState = toggleableState }
+        inMutuallyExclusiveGroup?.also {
+                inMutuallyExclusiveGroup -> it.inMutuallyExclusiveGroup = inMutuallyExclusiveGroup
+        }
+        isSelected?.also { selected -> it.selected = selected }
     }
 }
 
@@ -55,32 +63,22 @@
 fun SemanticsConfiguration.assertEquals(expected: SemanticsConfiguration) {
     val assertMessage = StringBuilder()
 
-    if (isEnabled != expected.isEnabled) {
-        assertMessage.append("\n- expected 'isEnabled' = ${expected.isEnabled} but was $isEnabled")
+    for ((key, expectedValue) in expected) {
+        if (this.contains(key)) {
+            val thisValue = this[key]
+            if (thisValue == expectedValue) {
+                continue
+            } else {
+                assertMessage.append("\n- expected ${key.name}" +
+                        " = '$expectedValue', but was $thisValue")
+            }
+        } else {
+            assertMessage.append("\n- expected ${key.name} = '$expectedValue', but was missing")
+        }
     }
 
-    if (isChecked != expected.isChecked) {
-        assertMessage.append("\n- expected 'isChecked' = ${expected.isChecked} but was $isChecked")
-    }
-
-    if (isInMutuallyExclusiveGroup != expected.isInMutuallyExclusiveGroup) {
-        assertMessage.append(
-            "\n- expected 'inMutuallyExclusiveGroup' = ${expected.isInMutuallyExclusiveGroup} " +
-                    "but was $isInMutuallyExclusiveGroup"
-        )
-    }
-
-    if (isSelected != expected.isSelected) {
-        assertMessage.append(
-            "\n- expected 'isSelected' = ${expected.isSelected} but was $isSelected"
-        )
-    }
-
-    if (isButton != expected.isButton) {
-        assertMessage.append(
-            "\n- expected 'isButton' = ${expected.isButton} but was $isButton"
-        )
-    }
+    // TODO(pavlis/ryanmentley): Should we also check that there are no _extra_ semantics?
+    //  I think the correct answer here is "no", but we should confirm
 
     if (assertMessage.isNotEmpty()) {
         throw AssertionError(
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/Output.kt b/ui/ui-test/src/main/java/androidx/ui/test/Output.kt
index c702554..31e9fea 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/Output.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/Output.kt
@@ -16,6 +16,7 @@
 
 package androidx.ui.test
 
+import androidx.ui.semantics.testTag
 // TODO(b/133217292)
 fun SemanticsNodeInteraction.dumpSemantics(consumer: (String) -> Unit) {
     val builder = StringBuilder()
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/SemanticsNodeInteraction.kt b/ui/ui-test/src/main/java/androidx/ui/test/SemanticsNodeInteraction.kt
index fd29f23..64fcc18 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/SemanticsNodeInteraction.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/SemanticsNodeInteraction.kt
@@ -20,7 +20,7 @@
 
 /**
  * Represents a component with which one can interact with the hierarchy.
- * Examples of interactions include [findByTag], [isCheckable], [assertIsChecked], [doClick]
+ * Examples of interactions include [findByTag], [isToggleable], [assertIsChecked], [doClick]
  *
  * Example usage:
  * findByTag("myCheckbox")
diff --git a/ui/ui-test/src/test/java/androidx/ui/test/AssertsTests.kt b/ui/ui-test/src/test/java/androidx/ui/test/AssertsTests.kt
index 9ea85c0..c3da838 100644
--- a/ui/ui-test/src/test/java/androidx/ui/test/AssertsTests.kt
+++ b/ui/ui-test/src/test/java/androidx/ui/test/AssertsTests.kt
@@ -21,6 +21,12 @@
 import androidx.ui.core.dp
 import androidx.ui.core.ipx
 import androidx.ui.core.semantics.SemanticsConfiguration
+import androidx.ui.foundation.selection.ToggleableState
+import androidx.ui.foundation.semantics.inMutuallyExclusiveGroup
+import androidx.ui.foundation.semantics.selected
+import androidx.ui.foundation.semantics.toggleableState
+import androidx.ui.semantics.hidden
+import androidx.ui.semantics.testTag
 import androidx.ui.test.helpers.FakeSemanticsTreeInteraction
 import org.junit.Test
 
@@ -32,7 +38,7 @@
             FakeSemanticsTreeInteraction(selector)
                 .withProperties(SemanticsConfiguration().also {
                     it.testTag = "test"
-                    it.isHidden = false
+                    it.hidden = false
                 })
         }
 
@@ -46,7 +52,7 @@
             FakeSemanticsTreeInteraction(selector)
                 .withProperties(SemanticsConfiguration().also {
                     it.testTag = "test"
-                    it.isHidden = true
+                    it.hidden = true
                 })
         }
 
@@ -60,7 +66,7 @@
             FakeSemanticsTreeInteraction(selector)
                 .withProperties(SemanticsConfiguration().also {
                     it.testTag = "test"
-                    it.isHidden = true
+                    it.hidden = true
                 })
         }
 
@@ -74,7 +80,7 @@
             FakeSemanticsTreeInteraction(selector)
                 .withProperties(SemanticsConfiguration().also {
                     it.testTag = "test"
-                    it.isHidden = false
+                    it.hidden = false
                 })
         }
 
@@ -88,7 +94,7 @@
             FakeSemanticsTreeInteraction(selector)
                 .withProperties(SemanticsConfiguration().also {
                     it.testTag = "test"
-                    it.isChecked = true
+                    it.toggleableState = ToggleableState.Checked
                 })
         }
 
@@ -97,17 +103,71 @@
     }
 
     @Test(expected = AssertionError::class)
-    fun assertIsChecked_forNotCheckedElement_throwsError() {
+    fun assertIsChecked_forUncheckedElement_throwsError() {
         semanticsTreeInteractionFactory = { selector ->
             FakeSemanticsTreeInteraction(selector)
                 .withProperties(SemanticsConfiguration().also {
                     it.testTag = "test"
-                    it.isChecked = false
+                    it.toggleableState = ToggleableState.Unchecked
                 })
         }
 
         findByTag("test")
-            .assertIsHidden()
+            .assertIsChecked()
+    }
+
+    @Test(expected = AssertionError::class)
+    fun assertIsChecked_forNotToggleableElement_throwsError() {
+        semanticsTreeInteractionFactory = { selector ->
+            FakeSemanticsTreeInteraction(selector)
+                .withProperties(SemanticsConfiguration().also {
+                    it.testTag = "test"
+                })
+        }
+
+        findByTag("test")
+            .assertIsChecked()
+    }
+
+    @Test(expected = AssertionError::class)
+    fun assertIsUnchecked_forCheckedElement_throwsError() {
+        semanticsTreeInteractionFactory = { selector ->
+            FakeSemanticsTreeInteraction(selector)
+                .withProperties(SemanticsConfiguration().also {
+                    it.testTag = "test"
+                    it.toggleableState = ToggleableState.Checked
+                })
+        }
+
+        findByTag("test")
+            .assertIsUnchecked()
+    }
+
+    @Test
+    fun assertIsUnchecked_forUncheckedElement_isOk() {
+        semanticsTreeInteractionFactory = { selector ->
+            FakeSemanticsTreeInteraction(selector)
+                .withProperties(SemanticsConfiguration().also {
+                    it.testTag = "test"
+                    it.toggleableState = ToggleableState.Unchecked
+                })
+        }
+
+        findByTag("test")
+            .assertIsUnchecked()
+    }
+
+    @Test(expected = AssertionError::class)
+    fun assertIsUnchecked_forNotToggleableElement_throwsError() {
+        semanticsTreeInteractionFactory = { selector ->
+            FakeSemanticsTreeInteraction(selector)
+                .withProperties(SemanticsConfiguration().also {
+                    it.testTag = "test"
+                })
+        }
+
+        findByTag("test")
+            .assertIsUnchecked()
     }
 
     @Test(expected = AssertionError::class)
@@ -116,7 +176,7 @@
             FakeSemanticsTreeInteraction(selector)
                 .withProperties(SemanticsConfiguration().also {
                     it.testTag = "test"
-                    it.isSelected = false
+                    it.selected = false
                 })
         }
 
@@ -130,7 +190,7 @@
             FakeSemanticsTreeInteraction(selector)
                 .withProperties(SemanticsConfiguration().also {
                     it.testTag = "test"
-                    it.isSelected = true
+                    it.selected = true
                 })
         }
 
@@ -139,31 +199,57 @@
     }
 
     @Test(expected = AssertionError::class)
-    fun assertIsNotSelected_forSelectedElement_throwsError() {
+    fun assertIsSelected_forNotSelectableElement_throwsError() {
         semanticsTreeInteractionFactory = { selector ->
             FakeSemanticsTreeInteraction(selector)
                 .withProperties(SemanticsConfiguration().also {
                     it.testTag = "test"
-                    it.isSelected = true
                 })
         }
 
         findByTag("test")
-            .assertIsNotSelected()
+            .assertIsSelected()
+    }
+
+    @Test(expected = AssertionError::class)
+    fun assertIsUnselected_forSelectedElement_throwsError() {
+        semanticsTreeInteractionFactory = { selector ->
+            FakeSemanticsTreeInteraction(selector)
+                .withProperties(SemanticsConfiguration().also {
+                    it.testTag = "test"
+                    it.selected = true
+                })
+        }
+
+        findByTag("test")
+            .assertIsUnselected()
     }
 
     @Test
-    fun assertIsNotSelected_forNotSelectedElement_isOk() {
+    fun assertIsUnselected_forUnselectedElement_isOk() {
         semanticsTreeInteractionFactory = { selector ->
             FakeSemanticsTreeInteraction(selector)
                 .withProperties(SemanticsConfiguration().also {
                     it.testTag = "test"
-                    it.isSelected = false
+                    it.selected = false
                 })
         }
 
         findByTag("test")
-            .assertIsNotSelected()
+            .assertIsUnselected()
+    }
+
+    @Test(expected = AssertionError::class)
+    fun assertIsUnselected_forNotSelectableElement_throwsError() {
+        semanticsTreeInteractionFactory = { selector ->
+            FakeSemanticsTreeInteraction(selector)
+                .withProperties(SemanticsConfiguration().also {
+                    it.testTag = "test"
+                })
+        }
+
+        findByTag("test")
+            .assertIsUnselected()
     }
 
     @Test(expected = AssertionError::class)
@@ -172,7 +258,20 @@
             FakeSemanticsTreeInteraction(selector)
                 .withProperties(SemanticsConfiguration().also {
                     it.testTag = "test"
-                    it.isInMutuallyExclusiveGroup = false
+                    it.inMutuallyExclusiveGroup = false
+                })
+        }
+
+        findByTag("test")
+            .assertIsInMutuallyExclusiveGroup()
+    }
+
+    @Test(expected = AssertionError::class)
+    fun assertItemInExclusiveGroup_forItemWithoutProperty_throwsError() {
+        semanticsTreeInteractionFactory = { selector ->
+            FakeSemanticsTreeInteraction(selector)
+                .withProperties(SemanticsConfiguration().also {
+                    it.testTag = "test"
                 })
         }
 
@@ -186,7 +285,7 @@
             FakeSemanticsTreeInteraction(selector)
                 .withProperties(SemanticsConfiguration().also {
                     it.testTag = "test"
-                    it.isInMutuallyExclusiveGroup = true
+                    it.inMutuallyExclusiveGroup = true
                 })
         }
 
diff --git a/ui/ui-test/src/test/java/androidx/ui/test/FindersTests.kt b/ui/ui-test/src/test/java/androidx/ui/test/FindersTests.kt
index 9fc5aca..deb6f9c 100644
--- a/ui/ui-test/src/test/java/androidx/ui/test/FindersTests.kt
+++ b/ui/ui-test/src/test/java/androidx/ui/test/FindersTests.kt
@@ -18,10 +18,14 @@
 
 import androidx.ui.core.SemanticsTreeNode
 import androidx.ui.core.semantics.SemanticsConfiguration
+import androidx.ui.core.semantics.getOrNull
+import androidx.ui.semantics.SemanticsProperties
+import androidx.ui.semantics.testTag
 import androidx.ui.test.helpers.FakeSemanticsTreeInteraction
 import com.google.common.truth.Truth
 import org.junit.Test
 
+// TODO(b/138167927): findByTag_* tests do not call findByTag
 class FindersTests {
     @Test
     fun findByTag_zeroOutOfOne_findsNone() {
@@ -34,7 +38,7 @@
                 ))
         }
 
-        val foundNodes = findAll { testTag == "myTestTag" }
+        val foundNodes = findAll { getOrNull(SemanticsProperties.TestTag) == "myTestTag" }
         Truth.assertThat(foundNodes).isEmpty()
     }
 
@@ -52,7 +56,7 @@
                 .withSemantics(node1, node2)
         }
 
-        val foundNodes = findAll { testTag == "myTestTag" }
+        val foundNodes = findAll { getOrNull(SemanticsProperties.TestTag) == "myTestTag" }
         Truth.assertThat(foundNodes.map { it.semanticsTreeNode }).containsExactly(node1)
     }
 
@@ -74,7 +78,7 @@
                 .withSemantics(node1, node2)
         }
 
-        val foundNodes = findAll { testTag == "myTestTag" }
+        val foundNodes = findAll { getOrNull(SemanticsProperties.TestTag) == "myTestTag" }
         Truth.assertThat(foundNodes.map { it.semanticsTreeNode }).containsExactly(node1, node2)
     }
 
diff --git a/ui/ui-text/api/1.0.0-alpha01.txt b/ui/ui-text/api/1.0.0-alpha01.txt
index a37b2f2..881f4a4 100644
--- a/ui/ui-text/api/1.0.0-alpha01.txt
+++ b/ui/ui-text/api/1.0.0-alpha01.txt
@@ -11,6 +11,18 @@
     property public final String text;
   }
 
+  public final class EditorStyle {
+    ctor public EditorStyle(androidx.ui.text.TextStyle? textStyle, androidx.ui.graphics.Color compositionColor, androidx.ui.graphics.Color selectionColor);
+    ctor public EditorStyle();
+    method public androidx.ui.text.TextStyle? component1();
+    method public androidx.ui.graphics.Color component2();
+    method public androidx.ui.graphics.Color component3();
+    method public androidx.ui.input.EditorStyle copy(androidx.ui.text.TextStyle? textStyle, androidx.ui.graphics.Color compositionColor, androidx.ui.graphics.Color selectionColor);
+    method public androidx.ui.graphics.Color getCompositionColor();
+    method public androidx.ui.graphics.Color getSelectionColor();
+    method public androidx.ui.text.TextStyle? getTextStyle();
+  }
+
   public enum ImeAction {
     enum_constant public static final androidx.ui.input.ImeAction Done;
     enum_constant public static final androidx.ui.input.ImeAction Go;
@@ -33,19 +45,52 @@
     enum_constant public static final androidx.ui.input.KeyboardType Uri;
   }
 
+  public interface OffsetMap {
+    method public int originalToTransformed(int offset);
+    method public int transformedToOriginal(int offset);
+  }
+
+  public final class PasswordVisualTransformation implements androidx.ui.input.VisualTransformation {
+    ctor public PasswordVisualTransformation(char mask);
+    ctor public PasswordVisualTransformation();
+    method public androidx.ui.input.TransformedText filter(androidx.ui.text.AnnotatedString text);
+    method public char getMask();
+  }
+
+  public final class TransformedText {
+    ctor public TransformedText(androidx.ui.text.AnnotatedString transformedText, androidx.ui.input.OffsetMap offsetMap);
+    method public androidx.ui.text.AnnotatedString component1();
+    method public androidx.ui.input.OffsetMap component2();
+    method public androidx.ui.input.TransformedText copy(androidx.ui.text.AnnotatedString transformedText, androidx.ui.input.OffsetMap offsetMap);
+    method public androidx.ui.input.OffsetMap getOffsetMap();
+    method public androidx.ui.text.AnnotatedString getTransformedText();
+  }
+
+  public interface VisualTransformation {
+    method public androidx.ui.input.TransformedText filter(androidx.ui.text.AnnotatedString text);
+  }
+
+  public final class VisualTransformationKt {
+    ctor public VisualTransformationKt();
+  }
+
 }
 
 package androidx.ui.text {
 
   public final class AnnotatedString {
     ctor public AnnotatedString(String text, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.TextStyle>> textStyles, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.ParagraphStyle>> paragraphStyles);
+    method public androidx.ui.text.AnnotatedString capitalize(java.util.Locale locale = Locale.getDefault());
     method public String component1();
     method public java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.TextStyle>> component2();
     method public java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.ParagraphStyle>> component3();
     method public androidx.ui.text.AnnotatedString copy(String text, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.TextStyle>> textStyles, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.ParagraphStyle>> paragraphStyles);
+    method public androidx.ui.text.AnnotatedString decapitalize(java.util.Locale locale = Locale.getDefault());
     method public java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.ParagraphStyle>> getParagraphStyles();
     method public String getText();
     method public java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.TextStyle>> getTextStyles();
+    method public androidx.ui.text.AnnotatedString toLowerCase(java.util.Locale locale = Locale.getDefault());
+    method public androidx.ui.text.AnnotatedString toUpperCase(java.util.Locale locale = Locale.getDefault());
   }
 
   public static final class AnnotatedString.Item<T> {
@@ -59,25 +104,6 @@
     method public T! getStyle();
   }
 
-  public final class Locale {
-    ctor public Locale(String _languageCode, String? _countryCode);
-    method public String component1();
-    method public String? component2();
-    method public androidx.ui.text.Locale copy(String _languageCode, String? _countryCode);
-    method public String! getCountryCode();
-    method public String getLanguageCode();
-    method public String? get_countryCode();
-    method public String get_languageCode();
-    property public final String! countryCode;
-    property public final String languageCode;
-    field public static final androidx.ui.text.Locale.Companion! Companion;
-  }
-
-  public static final class Locale.Companion {
-    method public String _canonicalizeLanguageCode(String languageCode);
-    method public String _canonicalizeRegionCode(String regionCode);
-  }
-
   public final class MultiParagraphKt {
     ctor public MultiParagraphKt();
   }
@@ -136,43 +162,8 @@
     method public androidx.ui.text.ParagraphStyle merge(androidx.ui.text.ParagraphStyle? other = null);
   }
 
-  public final class TextPainter {
-    ctor public TextPainter(androidx.ui.text.AnnotatedString? text, androidx.ui.text.TextStyle? style, androidx.ui.text.ParagraphStyle? paragraphStyle, Integer? maxLines, boolean softWrap, androidx.ui.text.style.TextOverflow overflow, androidx.ui.text.Locale? locale, androidx.ui.core.Density density, androidx.ui.text.font.Font.ResourceLoader resourceLoader);
-    method public androidx.ui.core.Density getDensity();
-    method public boolean getDidExceedMaxLines();
-    method public float getHeight();
-    method public androidx.ui.text.Locale? getLocale();
-    method public float getMaxIntrinsicWidth();
-    method public Integer? getMaxLines();
-    method public float getMinIntrinsicWidth();
-    method public int getOffsetForPosition(androidx.ui.core.PxPosition position);
-    method public androidx.ui.text.style.TextOverflow getOverflow();
-    method public androidx.ui.text.ParagraphStyle? getParagraphStyle();
-    method public float getPreferredLineHeight();
-    method public androidx.ui.text.font.Font.ResourceLoader getResourceLoader();
-    method public androidx.ui.engine.geometry.Size getSize();
-    method public boolean getSoftWrap();
-    method public androidx.ui.text.TextStyle? getStyle();
-    method public androidx.ui.text.AnnotatedString? getText();
-    method public float getWidth();
-    method public androidx.ui.text.TextRange getWordBoundary(int offset);
-    method public void layout(androidx.ui.core.Constraints constraints);
-    method public void paint(androidx.ui.painting.Canvas canvas);
-    method public void paintBackground(int start, int end, androidx.ui.graphics.Color color, androidx.ui.painting.Canvas canvas);
-    method public void paintCursor(int offset, androidx.ui.painting.Canvas canvas);
-    method public void setText(androidx.ui.text.AnnotatedString? value);
-    property public final boolean didExceedMaxLines;
-    property public final float height;
-    property public final float maxIntrinsicWidth;
-    property public final float minIntrinsicWidth;
-    property public final float preferredLineHeight;
-    property public final androidx.ui.engine.geometry.Size size;
-    property public final androidx.ui.text.AnnotatedString? text;
-    property public final float width;
-  }
-
-  public final class TextPainterKt {
-    ctor public TextPainterKt();
+  public final class TextDelegateKt {
+    ctor public TextDelegateKt();
   }
 
   public final class TextSpanKt {
@@ -180,12 +171,12 @@
   }
 
   public final class TextStyle {
-    ctor public TextStyle(androidx.ui.graphics.Color? color, androidx.ui.core.Sp? fontSize, Float? fontSizeScale, androidx.ui.text.font.FontWeight? fontWeight, androidx.ui.text.font.FontStyle? fontStyle, androidx.ui.text.font.FontSynthesis? fontSynthesis, androidx.ui.text.font.FontFamily? fontFamily, String? fontFeatureSettings, Float? letterSpacing, androidx.ui.text.style.BaselineShift? baselineShift, androidx.ui.text.style.TextGeometricTransform? textGeometricTransform, androidx.ui.text.Locale? locale, androidx.ui.graphics.Color? background, androidx.ui.text.style.TextDecoration? decoration, androidx.ui.painting.Shadow? shadow);
+    ctor public TextStyle(androidx.ui.graphics.Color? color, androidx.ui.core.Sp? fontSize, Float? fontSizeScale, androidx.ui.text.font.FontWeight? fontWeight, androidx.ui.text.font.FontStyle? fontStyle, androidx.ui.text.font.FontSynthesis? fontSynthesis, androidx.ui.text.font.FontFamily? fontFamily, String? fontFeatureSettings, Float? letterSpacing, androidx.ui.text.style.BaselineShift? baselineShift, androidx.ui.text.style.TextGeometricTransform? textGeometricTransform, java.util.Locale? locale, androidx.ui.graphics.Color? background, androidx.ui.text.style.TextDecoration? decoration, androidx.ui.painting.Shadow? shadow);
     ctor public TextStyle();
     method public androidx.ui.graphics.Color? component1();
     method public androidx.ui.text.style.BaselineShift? component10();
     method public androidx.ui.text.style.TextGeometricTransform? component11();
-    method public androidx.ui.text.Locale? component12();
+    method public java.util.Locale? component12();
     method public androidx.ui.graphics.Color? component13();
     method public androidx.ui.text.style.TextDecoration? component14();
     method public androidx.ui.painting.Shadow? component15();
@@ -197,7 +188,7 @@
     method public androidx.ui.text.font.FontFamily? component7();
     method public String? component8();
     method public Float? component9();
-    method public androidx.ui.text.TextStyle copy(androidx.ui.graphics.Color? color, androidx.ui.core.Sp? fontSize, Float? fontSizeScale, androidx.ui.text.font.FontWeight? fontWeight, androidx.ui.text.font.FontStyle? fontStyle, androidx.ui.text.font.FontSynthesis? fontSynthesis, androidx.ui.text.font.FontFamily? fontFamily, String? fontFeatureSettings, Float? letterSpacing, androidx.ui.text.style.BaselineShift? baselineShift, androidx.ui.text.style.TextGeometricTransform? textGeometricTransform, androidx.ui.text.Locale? locale, androidx.ui.graphics.Color? background, androidx.ui.text.style.TextDecoration? decoration, androidx.ui.painting.Shadow? shadow);
+    method public androidx.ui.text.TextStyle copy(androidx.ui.graphics.Color? color, androidx.ui.core.Sp? fontSize, Float? fontSizeScale, androidx.ui.text.font.FontWeight? fontWeight, androidx.ui.text.font.FontStyle? fontStyle, androidx.ui.text.font.FontSynthesis? fontSynthesis, androidx.ui.text.font.FontFamily? fontFamily, String? fontFeatureSettings, Float? letterSpacing, androidx.ui.text.style.BaselineShift? baselineShift, androidx.ui.text.style.TextGeometricTransform? textGeometricTransform, java.util.Locale? locale, androidx.ui.graphics.Color? background, androidx.ui.text.style.TextDecoration? decoration, androidx.ui.painting.Shadow? shadow);
     method public androidx.ui.graphics.Color? getBackground();
     method public androidx.ui.text.style.BaselineShift? getBaselineShift();
     method public androidx.ui.graphics.Color? getColor();
@@ -210,7 +201,7 @@
     method public androidx.ui.text.font.FontSynthesis? getFontSynthesis();
     method public androidx.ui.text.font.FontWeight? getFontWeight();
     method public Float? getLetterSpacing();
-    method public androidx.ui.text.Locale? getLocale();
+    method public java.util.Locale? getLocale();
     method public androidx.ui.painting.Shadow? getShadow();
     method public androidx.ui.text.style.TextGeometricTransform? getTextGeometricTransform();
     method public androidx.ui.text.TextStyle merge(androidx.ui.text.TextStyle? other = null);
diff --git a/ui/ui-text/api/api_lint.ignore b/ui/ui-text/api/api_lint.ignore
index 26f0fc9..8d78f05 100644
--- a/ui/ui-text/api/api_lint.ignore
+++ b/ui/ui-text/api/api_lint.ignore
@@ -9,21 +9,17 @@
     Must avoid boxed primitives (`java.lang.Float`)
 AutoBoxing: androidx.ui.text.ParagraphStyle#getLineHeight():
     Must avoid boxed primitives (`java.lang.Float`)
-AutoBoxing: androidx.ui.text.TextPainter#TextPainter(androidx.ui.text.AnnotatedString, androidx.ui.text.TextStyle, androidx.ui.text.ParagraphStyle, Integer, boolean, androidx.ui.text.style.TextOverflow, androidx.ui.text.Locale, androidx.ui.core.Density, androidx.ui.text.font.Font.ResourceLoader) parameter #3:
-    Must avoid boxed primitives (`java.lang.Integer`)
-AutoBoxing: androidx.ui.text.TextPainter#getMaxLines():
-    Must avoid boxed primitives (`java.lang.Integer`)
-AutoBoxing: androidx.ui.text.TextStyle#TextStyle(androidx.ui.graphics.Color, androidx.ui.core.Sp, Float, androidx.ui.text.font.FontWeight, androidx.ui.text.font.FontStyle, androidx.ui.text.font.FontSynthesis, androidx.ui.text.font.FontFamily, String, Float, androidx.ui.text.style.BaselineShift, androidx.ui.text.style.TextGeometricTransform, androidx.ui.text.Locale, androidx.ui.graphics.Color, androidx.ui.text.style.TextDecoration, androidx.ui.painting.Shadow) parameter #2:
+AutoBoxing: androidx.ui.text.TextStyle#TextStyle(androidx.ui.graphics.Color, androidx.ui.core.Sp, Float, androidx.ui.text.font.FontWeight, androidx.ui.text.font.FontStyle, androidx.ui.text.font.FontSynthesis, androidx.ui.text.font.FontFamily, String, Float, androidx.ui.text.style.BaselineShift, androidx.ui.text.style.TextGeometricTransform, java.util.Locale, androidx.ui.graphics.Color, androidx.ui.text.style.TextDecoration, androidx.ui.painting.Shadow) parameter #2:
     Must avoid boxed primitives (`java.lang.Float`)
-AutoBoxing: androidx.ui.text.TextStyle#TextStyle(androidx.ui.graphics.Color, androidx.ui.core.Sp, Float, androidx.ui.text.font.FontWeight, androidx.ui.text.font.FontStyle, androidx.ui.text.font.FontSynthesis, androidx.ui.text.font.FontFamily, String, Float, androidx.ui.text.style.BaselineShift, androidx.ui.text.style.TextGeometricTransform, androidx.ui.text.Locale, androidx.ui.graphics.Color, androidx.ui.text.style.TextDecoration, androidx.ui.painting.Shadow) parameter #8:
+AutoBoxing: androidx.ui.text.TextStyle#TextStyle(androidx.ui.graphics.Color, androidx.ui.core.Sp, Float, androidx.ui.text.font.FontWeight, androidx.ui.text.font.FontStyle, androidx.ui.text.font.FontSynthesis, androidx.ui.text.font.FontFamily, String, Float, androidx.ui.text.style.BaselineShift, androidx.ui.text.style.TextGeometricTransform, java.util.Locale, androidx.ui.graphics.Color, androidx.ui.text.style.TextDecoration, androidx.ui.painting.Shadow) parameter #8:
     Must avoid boxed primitives (`java.lang.Float`)
 AutoBoxing: androidx.ui.text.TextStyle#component3():
     Must avoid boxed primitives (`java.lang.Float`)
 AutoBoxing: androidx.ui.text.TextStyle#component9():
     Must avoid boxed primitives (`java.lang.Float`)
-AutoBoxing: androidx.ui.text.TextStyle#copy(androidx.ui.graphics.Color, androidx.ui.core.Sp, Float, androidx.ui.text.font.FontWeight, androidx.ui.text.font.FontStyle, androidx.ui.text.font.FontSynthesis, androidx.ui.text.font.FontFamily, String, Float, androidx.ui.text.style.BaselineShift, androidx.ui.text.style.TextGeometricTransform, androidx.ui.text.Locale, androidx.ui.graphics.Color, androidx.ui.text.style.TextDecoration, androidx.ui.painting.Shadow) parameter #2:
+AutoBoxing: androidx.ui.text.TextStyle#copy(androidx.ui.graphics.Color, androidx.ui.core.Sp, Float, androidx.ui.text.font.FontWeight, androidx.ui.text.font.FontStyle, androidx.ui.text.font.FontSynthesis, androidx.ui.text.font.FontFamily, String, Float, androidx.ui.text.style.BaselineShift, androidx.ui.text.style.TextGeometricTransform, java.util.Locale, androidx.ui.graphics.Color, androidx.ui.text.style.TextDecoration, androidx.ui.painting.Shadow) parameter #2:
     Must avoid boxed primitives (`java.lang.Float`)
-AutoBoxing: androidx.ui.text.TextStyle#copy(androidx.ui.graphics.Color, androidx.ui.core.Sp, Float, androidx.ui.text.font.FontWeight, androidx.ui.text.font.FontStyle, androidx.ui.text.font.FontSynthesis, androidx.ui.text.font.FontFamily, String, Float, androidx.ui.text.style.BaselineShift, androidx.ui.text.style.TextGeometricTransform, androidx.ui.text.Locale, androidx.ui.graphics.Color, androidx.ui.text.style.TextDecoration, androidx.ui.painting.Shadow) parameter #8:
+AutoBoxing: androidx.ui.text.TextStyle#copy(androidx.ui.graphics.Color, androidx.ui.core.Sp, Float, androidx.ui.text.font.FontWeight, androidx.ui.text.font.FontStyle, androidx.ui.text.font.FontSynthesis, androidx.ui.text.font.FontFamily, String, Float, androidx.ui.text.style.BaselineShift, androidx.ui.text.style.TextGeometricTransform, java.util.Locale, androidx.ui.graphics.Color, androidx.ui.text.style.TextDecoration, androidx.ui.painting.Shadow) parameter #8:
     Must avoid boxed primitives (`java.lang.Float`)
 AutoBoxing: androidx.ui.text.TextStyle#getFontSizeScale():
     Must avoid boxed primitives (`java.lang.Float`)
@@ -53,3 +49,13 @@
     Note that adding the `operator` keyword would allow calling this method using operator syntax
 KotlinOperator: androidx.ui.text.style.TextDecoration#contains(androidx.ui.text.style.TextDecoration):
     Note that adding the `operator` keyword would allow calling this method using operator syntax
+
+
+MissingNullability: androidx.ui.text.font.FontWeight#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.text.font.FontWeight`
+MissingNullability: androidx.ui.text.style.BaselineShift#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.text.style.BaselineShift`
+MissingNullability: androidx.ui.text.style.TextDecoration#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.text.style.TextDecoration`
+MissingNullability: androidx.ui.text.style.TextGeometricTransform#Companion:
+    Missing nullability on field `Companion` in class `class androidx.ui.text.style.TextGeometricTransform`
diff --git a/ui/ui-text/api/current.txt b/ui/ui-text/api/current.txt
index a37b2f2..881f4a4 100644
--- a/ui/ui-text/api/current.txt
+++ b/ui/ui-text/api/current.txt
@@ -11,6 +11,18 @@
     property public final String text;
   }
 
+  public final class EditorStyle {
+    ctor public EditorStyle(androidx.ui.text.TextStyle? textStyle, androidx.ui.graphics.Color compositionColor, androidx.ui.graphics.Color selectionColor);
+    ctor public EditorStyle();
+    method public androidx.ui.text.TextStyle? component1();
+    method public androidx.ui.graphics.Color component2();
+    method public androidx.ui.graphics.Color component3();
+    method public androidx.ui.input.EditorStyle copy(androidx.ui.text.TextStyle? textStyle, androidx.ui.graphics.Color compositionColor, androidx.ui.graphics.Color selectionColor);
+    method public androidx.ui.graphics.Color getCompositionColor();
+    method public androidx.ui.graphics.Color getSelectionColor();
+    method public androidx.ui.text.TextStyle? getTextStyle();
+  }
+
   public enum ImeAction {
     enum_constant public static final androidx.ui.input.ImeAction Done;
     enum_constant public static final androidx.ui.input.ImeAction Go;
@@ -33,19 +45,52 @@
     enum_constant public static final androidx.ui.input.KeyboardType Uri;
   }
 
+  public interface OffsetMap {
+    method public int originalToTransformed(int offset);
+    method public int transformedToOriginal(int offset);
+  }
+
+  public final class PasswordVisualTransformation implements androidx.ui.input.VisualTransformation {
+    ctor public PasswordVisualTransformation(char mask);
+    ctor public PasswordVisualTransformation();
+    method public androidx.ui.input.TransformedText filter(androidx.ui.text.AnnotatedString text);
+    method public char getMask();
+  }
+
+  public final class TransformedText {
+    ctor public TransformedText(androidx.ui.text.AnnotatedString transformedText, androidx.ui.input.OffsetMap offsetMap);
+    method public androidx.ui.text.AnnotatedString component1();
+    method public androidx.ui.input.OffsetMap component2();
+    method public androidx.ui.input.TransformedText copy(androidx.ui.text.AnnotatedString transformedText, androidx.ui.input.OffsetMap offsetMap);
+    method public androidx.ui.input.OffsetMap getOffsetMap();
+    method public androidx.ui.text.AnnotatedString getTransformedText();
+  }
+
+  public interface VisualTransformation {
+    method public androidx.ui.input.TransformedText filter(androidx.ui.text.AnnotatedString text);
+  }
+
+  public final class VisualTransformationKt {
+    ctor public VisualTransformationKt();
+  }
+
 }
 
 package androidx.ui.text {
 
   public final class AnnotatedString {
     ctor public AnnotatedString(String text, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.TextStyle>> textStyles, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.ParagraphStyle>> paragraphStyles);
+    method public androidx.ui.text.AnnotatedString capitalize(java.util.Locale locale = Locale.getDefault());
     method public String component1();
     method public java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.TextStyle>> component2();
     method public java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.ParagraphStyle>> component3();
     method public androidx.ui.text.AnnotatedString copy(String text, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.TextStyle>> textStyles, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.ParagraphStyle>> paragraphStyles);
+    method public androidx.ui.text.AnnotatedString decapitalize(java.util.Locale locale = Locale.getDefault());
     method public java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.ParagraphStyle>> getParagraphStyles();
     method public String getText();
     method public java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.TextStyle>> getTextStyles();
+    method public androidx.ui.text.AnnotatedString toLowerCase(java.util.Locale locale = Locale.getDefault());
+    method public androidx.ui.text.AnnotatedString toUpperCase(java.util.Locale locale = Locale.getDefault());
   }
 
   public static final class AnnotatedString.Item<T> {
@@ -59,25 +104,6 @@
     method public T! getStyle();
   }
 
-  public final class Locale {
-    ctor public Locale(String _languageCode, String? _countryCode);
-    method public String component1();
-    method public String? component2();
-    method public androidx.ui.text.Locale copy(String _languageCode, String? _countryCode);
-    method public String! getCountryCode();
-    method public String getLanguageCode();
-    method public String? get_countryCode();
-    method public String get_languageCode();
-    property public final String! countryCode;
-    property public final String languageCode;
-    field public static final androidx.ui.text.Locale.Companion! Companion;
-  }
-
-  public static final class Locale.Companion {
-    method public String _canonicalizeLanguageCode(String languageCode);
-    method public String _canonicalizeRegionCode(String regionCode);
-  }
-
   public final class MultiParagraphKt {
     ctor public MultiParagraphKt();
   }
@@ -136,43 +162,8 @@
     method public androidx.ui.text.ParagraphStyle merge(androidx.ui.text.ParagraphStyle? other = null);
   }
 
-  public final class TextPainter {
-    ctor public TextPainter(androidx.ui.text.AnnotatedString? text, androidx.ui.text.TextStyle? style, androidx.ui.text.ParagraphStyle? paragraphStyle, Integer? maxLines, boolean softWrap, androidx.ui.text.style.TextOverflow overflow, androidx.ui.text.Locale? locale, androidx.ui.core.Density density, androidx.ui.text.font.Font.ResourceLoader resourceLoader);
-    method public androidx.ui.core.Density getDensity();
-    method public boolean getDidExceedMaxLines();
-    method public float getHeight();
-    method public androidx.ui.text.Locale? getLocale();
-    method public float getMaxIntrinsicWidth();
-    method public Integer? getMaxLines();
-    method public float getMinIntrinsicWidth();
-    method public int getOffsetForPosition(androidx.ui.core.PxPosition position);
-    method public androidx.ui.text.style.TextOverflow getOverflow();
-    method public androidx.ui.text.ParagraphStyle? getParagraphStyle();
-    method public float getPreferredLineHeight();
-    method public androidx.ui.text.font.Font.ResourceLoader getResourceLoader();
-    method public androidx.ui.engine.geometry.Size getSize();
-    method public boolean getSoftWrap();
-    method public androidx.ui.text.TextStyle? getStyle();
-    method public androidx.ui.text.AnnotatedString? getText();
-    method public float getWidth();
-    method public androidx.ui.text.TextRange getWordBoundary(int offset);
-    method public void layout(androidx.ui.core.Constraints constraints);
-    method public void paint(androidx.ui.painting.Canvas canvas);
-    method public void paintBackground(int start, int end, androidx.ui.graphics.Color color, androidx.ui.painting.Canvas canvas);
-    method public void paintCursor(int offset, androidx.ui.painting.Canvas canvas);
-    method public void setText(androidx.ui.text.AnnotatedString? value);
-    property public final boolean didExceedMaxLines;
-    property public final float height;
-    property public final float maxIntrinsicWidth;
-    property public final float minIntrinsicWidth;
-    property public final float preferredLineHeight;
-    property public final androidx.ui.engine.geometry.Size size;
-    property public final androidx.ui.text.AnnotatedString? text;
-    property public final float width;
-  }
-
-  public final class TextPainterKt {
-    ctor public TextPainterKt();
+  public final class TextDelegateKt {
+    ctor public TextDelegateKt();
   }
 
   public final class TextSpanKt {
@@ -180,12 +171,12 @@
   }
 
   public final class TextStyle {
-    ctor public TextStyle(androidx.ui.graphics.Color? color, androidx.ui.core.Sp? fontSize, Float? fontSizeScale, androidx.ui.text.font.FontWeight? fontWeight, androidx.ui.text.font.FontStyle? fontStyle, androidx.ui.text.font.FontSynthesis? fontSynthesis, androidx.ui.text.font.FontFamily? fontFamily, String? fontFeatureSettings, Float? letterSpacing, androidx.ui.text.style.BaselineShift? baselineShift, androidx.ui.text.style.TextGeometricTransform? textGeometricTransform, androidx.ui.text.Locale? locale, androidx.ui.graphics.Color? background, androidx.ui.text.style.TextDecoration? decoration, androidx.ui.painting.Shadow? shadow);
+    ctor public TextStyle(androidx.ui.graphics.Color? color, androidx.ui.core.Sp? fontSize, Float? fontSizeScale, androidx.ui.text.font.FontWeight? fontWeight, androidx.ui.text.font.FontStyle? fontStyle, androidx.ui.text.font.FontSynthesis? fontSynthesis, androidx.ui.text.font.FontFamily? fontFamily, String? fontFeatureSettings, Float? letterSpacing, androidx.ui.text.style.BaselineShift? baselineShift, androidx.ui.text.style.TextGeometricTransform? textGeometricTransform, java.util.Locale? locale, androidx.ui.graphics.Color? background, androidx.ui.text.style.TextDecoration? decoration, androidx.ui.painting.Shadow? shadow);
     ctor public TextStyle();
     method public androidx.ui.graphics.Color? component1();
     method public androidx.ui.text.style.BaselineShift? component10();
     method public androidx.ui.text.style.TextGeometricTransform? component11();
-    method public androidx.ui.text.Locale? component12();
+    method public java.util.Locale? component12();
     method public androidx.ui.graphics.Color? component13();
     method public androidx.ui.text.style.TextDecoration? component14();
     method public androidx.ui.painting.Shadow? component15();
@@ -197,7 +188,7 @@
     method public androidx.ui.text.font.FontFamily? component7();
     method public String? component8();
     method public Float? component9();
-    method public androidx.ui.text.TextStyle copy(androidx.ui.graphics.Color? color, androidx.ui.core.Sp? fontSize, Float? fontSizeScale, androidx.ui.text.font.FontWeight? fontWeight, androidx.ui.text.font.FontStyle? fontStyle, androidx.ui.text.font.FontSynthesis? fontSynthesis, androidx.ui.text.font.FontFamily? fontFamily, String? fontFeatureSettings, Float? letterSpacing, androidx.ui.text.style.BaselineShift? baselineShift, androidx.ui.text.style.TextGeometricTransform? textGeometricTransform, androidx.ui.text.Locale? locale, androidx.ui.graphics.Color? background, androidx.ui.text.style.TextDecoration? decoration, androidx.ui.painting.Shadow? shadow);
+    method public androidx.ui.text.TextStyle copy(androidx.ui.graphics.Color? color, androidx.ui.core.Sp? fontSize, Float? fontSizeScale, androidx.ui.text.font.FontWeight? fontWeight, androidx.ui.text.font.FontStyle? fontStyle, androidx.ui.text.font.FontSynthesis? fontSynthesis, androidx.ui.text.font.FontFamily? fontFamily, String? fontFeatureSettings, Float? letterSpacing, androidx.ui.text.style.BaselineShift? baselineShift, androidx.ui.text.style.TextGeometricTransform? textGeometricTransform, java.util.Locale? locale, androidx.ui.graphics.Color? background, androidx.ui.text.style.TextDecoration? decoration, androidx.ui.painting.Shadow? shadow);
     method public androidx.ui.graphics.Color? getBackground();
     method public androidx.ui.text.style.BaselineShift? getBaselineShift();
     method public androidx.ui.graphics.Color? getColor();
@@ -210,7 +201,7 @@
     method public androidx.ui.text.font.FontSynthesis? getFontSynthesis();
     method public androidx.ui.text.font.FontWeight? getFontWeight();
     method public Float? getLetterSpacing();
-    method public androidx.ui.text.Locale? getLocale();
+    method public java.util.Locale? getLocale();
     method public androidx.ui.painting.Shadow? getShadow();
     method public androidx.ui.text.style.TextGeometricTransform? getTextGeometricTransform();
     method public androidx.ui.text.TextStyle merge(androidx.ui.text.TextStyle? other = null);
diff --git a/ui/ui-text/api/restricted_1.0.0-alpha01.txt b/ui/ui-text/api/restricted_1.0.0-alpha01.txt
index d02f68726..d351ab5 100644
--- a/ui/ui-text/api/restricted_1.0.0-alpha01.txt
+++ b/ui/ui-text/api/restricted_1.0.0-alpha01.txt
@@ -18,6 +18,18 @@
     property public final String text;
   }
 
+  public final class EditorStyle {
+    ctor public EditorStyle(androidx.ui.text.TextStyle? textStyle, androidx.ui.graphics.Color compositionColor, androidx.ui.graphics.Color selectionColor);
+    ctor public EditorStyle();
+    method public androidx.ui.text.TextStyle? component1();
+    method public androidx.ui.graphics.Color component2();
+    method public androidx.ui.graphics.Color component3();
+    method public androidx.ui.input.EditorStyle copy(androidx.ui.text.TextStyle? textStyle, androidx.ui.graphics.Color compositionColor, androidx.ui.graphics.Color selectionColor);
+    method public androidx.ui.graphics.Color getCompositionColor();
+    method public androidx.ui.graphics.Color getSelectionColor();
+    method public androidx.ui.text.TextStyle? getTextStyle();
+  }
+
 
   public enum ImeAction {
     enum_constant public static final androidx.ui.input.ImeAction Done;
@@ -43,23 +55,56 @@
   }
 
 
+  public interface OffsetMap {
+    method public int originalToTransformed(int offset);
+    method public int transformedToOriginal(int offset);
+  }
+
+  public final class PasswordVisualTransformation implements androidx.ui.input.VisualTransformation {
+    ctor public PasswordVisualTransformation(char mask);
+    ctor public PasswordVisualTransformation();
+    method public androidx.ui.input.TransformedText filter(androidx.ui.text.AnnotatedString text);
+    method public char getMask();
+  }
 
 
 
 
+
+  public final class TransformedText {
+    ctor public TransformedText(androidx.ui.text.AnnotatedString transformedText, androidx.ui.input.OffsetMap offsetMap);
+    method public androidx.ui.text.AnnotatedString component1();
+    method public androidx.ui.input.OffsetMap component2();
+    method public androidx.ui.input.TransformedText copy(androidx.ui.text.AnnotatedString transformedText, androidx.ui.input.OffsetMap offsetMap);
+    method public androidx.ui.input.OffsetMap getOffsetMap();
+    method public androidx.ui.text.AnnotatedString getTransformedText();
+  }
+
+  public interface VisualTransformation {
+    method public androidx.ui.input.TransformedText filter(androidx.ui.text.AnnotatedString text);
+  }
+
+  public final class VisualTransformationKt {
+    ctor public VisualTransformationKt();
+  }
+
 }
 
 package androidx.ui.text {
 
   public final class AnnotatedString {
     ctor public AnnotatedString(String text, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.TextStyle>> textStyles, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.ParagraphStyle>> paragraphStyles);
+    method public androidx.ui.text.AnnotatedString capitalize(java.util.Locale locale = Locale.getDefault());
     method public String component1();
     method public java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.TextStyle>> component2();
     method public java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.ParagraphStyle>> component3();
     method public androidx.ui.text.AnnotatedString copy(String text, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.TextStyle>> textStyles, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.ParagraphStyle>> paragraphStyles);
+    method public androidx.ui.text.AnnotatedString decapitalize(java.util.Locale locale = Locale.getDefault());
     method public java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.ParagraphStyle>> getParagraphStyles();
     method public String getText();
     method public java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.TextStyle>> getTextStyles();
+    method public androidx.ui.text.AnnotatedString toLowerCase(java.util.Locale locale = Locale.getDefault());
+    method public androidx.ui.text.AnnotatedString toUpperCase(java.util.Locale locale = Locale.getDefault());
   }
 
   public static final class AnnotatedString.Item<T> {
@@ -73,25 +118,6 @@
     method public T! getStyle();
   }
 
-  public final class Locale {
-    ctor public Locale(String _languageCode, String? _countryCode);
-    method public String component1();
-    method public String? component2();
-    method public androidx.ui.text.Locale copy(String _languageCode, String? _countryCode);
-    method public String! getCountryCode();
-    method public String getLanguageCode();
-    method public String? get_countryCode();
-    method public String get_languageCode();
-    property public final String! countryCode;
-    property public final String languageCode;
-    field public static final androidx.ui.text.Locale.Companion! Companion;
-  }
-
-  public static final class Locale.Companion {
-    method public String _canonicalizeLanguageCode(String languageCode);
-    method public String _canonicalizeRegionCode(String regionCode);
-  }
-
   public final class MultiParagraphKt {
     ctor public MultiParagraphKt();
   }
@@ -150,43 +176,9 @@
     method public androidx.ui.text.ParagraphStyle merge(androidx.ui.text.ParagraphStyle? other = null);
   }
 
-  public final class TextPainter {
-    ctor public TextPainter(androidx.ui.text.AnnotatedString? text, androidx.ui.text.TextStyle? style, androidx.ui.text.ParagraphStyle? paragraphStyle, Integer? maxLines, boolean softWrap, androidx.ui.text.style.TextOverflow overflow, androidx.ui.text.Locale? locale, androidx.ui.core.Density density, androidx.ui.text.font.Font.ResourceLoader resourceLoader);
-    method public androidx.ui.core.Density getDensity();
-    method public boolean getDidExceedMaxLines();
-    method public float getHeight();
-    method public androidx.ui.text.Locale? getLocale();
-    method public float getMaxIntrinsicWidth();
-    method public Integer? getMaxLines();
-    method public float getMinIntrinsicWidth();
-    method public int getOffsetForPosition(androidx.ui.core.PxPosition position);
-    method public androidx.ui.text.style.TextOverflow getOverflow();
-    method public androidx.ui.text.ParagraphStyle? getParagraphStyle();
-    method public float getPreferredLineHeight();
-    method public androidx.ui.text.font.Font.ResourceLoader getResourceLoader();
-    method public androidx.ui.engine.geometry.Size getSize();
-    method public boolean getSoftWrap();
-    method public androidx.ui.text.TextStyle? getStyle();
-    method public androidx.ui.text.AnnotatedString? getText();
-    method public float getWidth();
-    method public androidx.ui.text.TextRange getWordBoundary(int offset);
-    method public void layout(androidx.ui.core.Constraints constraints);
-    method public void paint(androidx.ui.painting.Canvas canvas);
-    method public void paintBackground(int start, int end, androidx.ui.graphics.Color color, androidx.ui.painting.Canvas canvas);
-    method public void paintCursor(int offset, androidx.ui.painting.Canvas canvas);
-    method public void setText(androidx.ui.text.AnnotatedString? value);
-    property public final boolean didExceedMaxLines;
-    property public final float height;
-    property public final float maxIntrinsicWidth;
-    property public final float minIntrinsicWidth;
-    property public final float preferredLineHeight;
-    property public final androidx.ui.engine.geometry.Size size;
-    property public final androidx.ui.text.AnnotatedString? text;
-    property public final float width;
-  }
 
-  public final class TextPainterKt {
-    ctor public TextPainterKt();
+  public final class TextDelegateKt {
+    ctor public TextDelegateKt();
   }
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final class TextSpan {
@@ -205,12 +197,12 @@
   }
 
   public final class TextStyle {
-    ctor public TextStyle(androidx.ui.graphics.Color? color, androidx.ui.core.Sp? fontSize, Float? fontSizeScale, androidx.ui.text.font.FontWeight? fontWeight, androidx.ui.text.font.FontStyle? fontStyle, androidx.ui.text.font.FontSynthesis? fontSynthesis, androidx.ui.text.font.FontFamily? fontFamily, String? fontFeatureSettings, Float? letterSpacing, androidx.ui.text.style.BaselineShift? baselineShift, androidx.ui.text.style.TextGeometricTransform? textGeometricTransform, androidx.ui.text.Locale? locale, androidx.ui.graphics.Color? background, androidx.ui.text.style.TextDecoration? decoration, androidx.ui.painting.Shadow? shadow);
+    ctor public TextStyle(androidx.ui.graphics.Color? color, androidx.ui.core.Sp? fontSize, Float? fontSizeScale, androidx.ui.text.font.FontWeight? fontWeight, androidx.ui.text.font.FontStyle? fontStyle, androidx.ui.text.font.FontSynthesis? fontSynthesis, androidx.ui.text.font.FontFamily? fontFamily, String? fontFeatureSettings, Float? letterSpacing, androidx.ui.text.style.BaselineShift? baselineShift, androidx.ui.text.style.TextGeometricTransform? textGeometricTransform, java.util.Locale? locale, androidx.ui.graphics.Color? background, androidx.ui.text.style.TextDecoration? decoration, androidx.ui.painting.Shadow? shadow);
     ctor public TextStyle();
     method public androidx.ui.graphics.Color? component1();
     method public androidx.ui.text.style.BaselineShift? component10();
     method public androidx.ui.text.style.TextGeometricTransform? component11();
-    method public androidx.ui.text.Locale? component12();
+    method public java.util.Locale? component12();
     method public androidx.ui.graphics.Color? component13();
     method public androidx.ui.text.style.TextDecoration? component14();
     method public androidx.ui.painting.Shadow? component15();
@@ -222,7 +214,7 @@
     method public androidx.ui.text.font.FontFamily? component7();
     method public String? component8();
     method public Float? component9();
-    method public androidx.ui.text.TextStyle copy(androidx.ui.graphics.Color? color, androidx.ui.core.Sp? fontSize, Float? fontSizeScale, androidx.ui.text.font.FontWeight? fontWeight, androidx.ui.text.font.FontStyle? fontStyle, androidx.ui.text.font.FontSynthesis? fontSynthesis, androidx.ui.text.font.FontFamily? fontFamily, String? fontFeatureSettings, Float? letterSpacing, androidx.ui.text.style.BaselineShift? baselineShift, androidx.ui.text.style.TextGeometricTransform? textGeometricTransform, androidx.ui.text.Locale? locale, androidx.ui.graphics.Color? background, androidx.ui.text.style.TextDecoration? decoration, androidx.ui.painting.Shadow? shadow);
+    method public androidx.ui.text.TextStyle copy(androidx.ui.graphics.Color? color, androidx.ui.core.Sp? fontSize, Float? fontSizeScale, androidx.ui.text.font.FontWeight? fontWeight, androidx.ui.text.font.FontStyle? fontStyle, androidx.ui.text.font.FontSynthesis? fontSynthesis, androidx.ui.text.font.FontFamily? fontFamily, String? fontFeatureSettings, Float? letterSpacing, androidx.ui.text.style.BaselineShift? baselineShift, androidx.ui.text.style.TextGeometricTransform? textGeometricTransform, java.util.Locale? locale, androidx.ui.graphics.Color? background, androidx.ui.text.style.TextDecoration? decoration, androidx.ui.painting.Shadow? shadow);
     method public androidx.ui.graphics.Color? getBackground();
     method public androidx.ui.text.style.BaselineShift? getBaselineShift();
     method public androidx.ui.graphics.Color? getColor();
@@ -235,7 +227,7 @@
     method public androidx.ui.text.font.FontSynthesis? getFontSynthesis();
     method public androidx.ui.text.font.FontWeight? getFontWeight();
     method public Float? getLetterSpacing();
-    method public androidx.ui.text.Locale? getLocale();
+    method public java.util.Locale? getLocale();
     method public androidx.ui.painting.Shadow? getShadow();
     method public androidx.ui.text.style.TextGeometricTransform? getTextGeometricTransform();
     method public androidx.ui.text.TextStyle merge(androidx.ui.text.TextStyle? other = null);
diff --git a/ui/ui-text/api/restricted_current.txt b/ui/ui-text/api/restricted_current.txt
index d02f68726..d351ab5 100644
--- a/ui/ui-text/api/restricted_current.txt
+++ b/ui/ui-text/api/restricted_current.txt
@@ -18,6 +18,18 @@
     property public final String text;
   }
 
+  public final class EditorStyle {
+    ctor public EditorStyle(androidx.ui.text.TextStyle? textStyle, androidx.ui.graphics.Color compositionColor, androidx.ui.graphics.Color selectionColor);
+    ctor public EditorStyle();
+    method public androidx.ui.text.TextStyle? component1();
+    method public androidx.ui.graphics.Color component2();
+    method public androidx.ui.graphics.Color component3();
+    method public androidx.ui.input.EditorStyle copy(androidx.ui.text.TextStyle? textStyle, androidx.ui.graphics.Color compositionColor, androidx.ui.graphics.Color selectionColor);
+    method public androidx.ui.graphics.Color getCompositionColor();
+    method public androidx.ui.graphics.Color getSelectionColor();
+    method public androidx.ui.text.TextStyle? getTextStyle();
+  }
+
 
   public enum ImeAction {
     enum_constant public static final androidx.ui.input.ImeAction Done;
@@ -43,23 +55,56 @@
   }
 
 
+  public interface OffsetMap {
+    method public int originalToTransformed(int offset);
+    method public int transformedToOriginal(int offset);
+  }
+
+  public final class PasswordVisualTransformation implements androidx.ui.input.VisualTransformation {
+    ctor public PasswordVisualTransformation(char mask);
+    ctor public PasswordVisualTransformation();
+    method public androidx.ui.input.TransformedText filter(androidx.ui.text.AnnotatedString text);
+    method public char getMask();
+  }
 
 
 
 
+
+  public final class TransformedText {
+    ctor public TransformedText(androidx.ui.text.AnnotatedString transformedText, androidx.ui.input.OffsetMap offsetMap);
+    method public androidx.ui.text.AnnotatedString component1();
+    method public androidx.ui.input.OffsetMap component2();
+    method public androidx.ui.input.TransformedText copy(androidx.ui.text.AnnotatedString transformedText, androidx.ui.input.OffsetMap offsetMap);
+    method public androidx.ui.input.OffsetMap getOffsetMap();
+    method public androidx.ui.text.AnnotatedString getTransformedText();
+  }
+
+  public interface VisualTransformation {
+    method public androidx.ui.input.TransformedText filter(androidx.ui.text.AnnotatedString text);
+  }
+
+  public final class VisualTransformationKt {
+    ctor public VisualTransformationKt();
+  }
+
 }
 
 package androidx.ui.text {
 
   public final class AnnotatedString {
     ctor public AnnotatedString(String text, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.TextStyle>> textStyles, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.ParagraphStyle>> paragraphStyles);
+    method public androidx.ui.text.AnnotatedString capitalize(java.util.Locale locale = Locale.getDefault());
     method public String component1();
     method public java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.TextStyle>> component2();
     method public java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.ParagraphStyle>> component3();
     method public androidx.ui.text.AnnotatedString copy(String text, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.TextStyle>> textStyles, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.ParagraphStyle>> paragraphStyles);
+    method public androidx.ui.text.AnnotatedString decapitalize(java.util.Locale locale = Locale.getDefault());
     method public java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.ParagraphStyle>> getParagraphStyles();
     method public String getText();
     method public java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.TextStyle>> getTextStyles();
+    method public androidx.ui.text.AnnotatedString toLowerCase(java.util.Locale locale = Locale.getDefault());
+    method public androidx.ui.text.AnnotatedString toUpperCase(java.util.Locale locale = Locale.getDefault());
   }
 
   public static final class AnnotatedString.Item<T> {
@@ -73,25 +118,6 @@
     method public T! getStyle();
   }
 
-  public final class Locale {
-    ctor public Locale(String _languageCode, String? _countryCode);
-    method public String component1();
-    method public String? component2();
-    method public androidx.ui.text.Locale copy(String _languageCode, String? _countryCode);
-    method public String! getCountryCode();
-    method public String getLanguageCode();
-    method public String? get_countryCode();
-    method public String get_languageCode();
-    property public final String! countryCode;
-    property public final String languageCode;
-    field public static final androidx.ui.text.Locale.Companion! Companion;
-  }
-
-  public static final class Locale.Companion {
-    method public String _canonicalizeLanguageCode(String languageCode);
-    method public String _canonicalizeRegionCode(String regionCode);
-  }
-
   public final class MultiParagraphKt {
     ctor public MultiParagraphKt();
   }
@@ -150,43 +176,9 @@
     method public androidx.ui.text.ParagraphStyle merge(androidx.ui.text.ParagraphStyle? other = null);
   }
 
-  public final class TextPainter {
-    ctor public TextPainter(androidx.ui.text.AnnotatedString? text, androidx.ui.text.TextStyle? style, androidx.ui.text.ParagraphStyle? paragraphStyle, Integer? maxLines, boolean softWrap, androidx.ui.text.style.TextOverflow overflow, androidx.ui.text.Locale? locale, androidx.ui.core.Density density, androidx.ui.text.font.Font.ResourceLoader resourceLoader);
-    method public androidx.ui.core.Density getDensity();
-    method public boolean getDidExceedMaxLines();
-    method public float getHeight();
-    method public androidx.ui.text.Locale? getLocale();
-    method public float getMaxIntrinsicWidth();
-    method public Integer? getMaxLines();
-    method public float getMinIntrinsicWidth();
-    method public int getOffsetForPosition(androidx.ui.core.PxPosition position);
-    method public androidx.ui.text.style.TextOverflow getOverflow();
-    method public androidx.ui.text.ParagraphStyle? getParagraphStyle();
-    method public float getPreferredLineHeight();
-    method public androidx.ui.text.font.Font.ResourceLoader getResourceLoader();
-    method public androidx.ui.engine.geometry.Size getSize();
-    method public boolean getSoftWrap();
-    method public androidx.ui.text.TextStyle? getStyle();
-    method public androidx.ui.text.AnnotatedString? getText();
-    method public float getWidth();
-    method public androidx.ui.text.TextRange getWordBoundary(int offset);
-    method public void layout(androidx.ui.core.Constraints constraints);
-    method public void paint(androidx.ui.painting.Canvas canvas);
-    method public void paintBackground(int start, int end, androidx.ui.graphics.Color color, androidx.ui.painting.Canvas canvas);
-    method public void paintCursor(int offset, androidx.ui.painting.Canvas canvas);
-    method public void setText(androidx.ui.text.AnnotatedString? value);
-    property public final boolean didExceedMaxLines;
-    property public final float height;
-    property public final float maxIntrinsicWidth;
-    property public final float minIntrinsicWidth;
-    property public final float preferredLineHeight;
-    property public final androidx.ui.engine.geometry.Size size;
-    property public final androidx.ui.text.AnnotatedString? text;
-    property public final float width;
-  }
 
-  public final class TextPainterKt {
-    ctor public TextPainterKt();
+  public final class TextDelegateKt {
+    ctor public TextDelegateKt();
   }
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final class TextSpan {
@@ -205,12 +197,12 @@
   }
 
   public final class TextStyle {
-    ctor public TextStyle(androidx.ui.graphics.Color? color, androidx.ui.core.Sp? fontSize, Float? fontSizeScale, androidx.ui.text.font.FontWeight? fontWeight, androidx.ui.text.font.FontStyle? fontStyle, androidx.ui.text.font.FontSynthesis? fontSynthesis, androidx.ui.text.font.FontFamily? fontFamily, String? fontFeatureSettings, Float? letterSpacing, androidx.ui.text.style.BaselineShift? baselineShift, androidx.ui.text.style.TextGeometricTransform? textGeometricTransform, androidx.ui.text.Locale? locale, androidx.ui.graphics.Color? background, androidx.ui.text.style.TextDecoration? decoration, androidx.ui.painting.Shadow? shadow);
+    ctor public TextStyle(androidx.ui.graphics.Color? color, androidx.ui.core.Sp? fontSize, Float? fontSizeScale, androidx.ui.text.font.FontWeight? fontWeight, androidx.ui.text.font.FontStyle? fontStyle, androidx.ui.text.font.FontSynthesis? fontSynthesis, androidx.ui.text.font.FontFamily? fontFamily, String? fontFeatureSettings, Float? letterSpacing, androidx.ui.text.style.BaselineShift? baselineShift, androidx.ui.text.style.TextGeometricTransform? textGeometricTransform, java.util.Locale? locale, androidx.ui.graphics.Color? background, androidx.ui.text.style.TextDecoration? decoration, androidx.ui.painting.Shadow? shadow);
     ctor public TextStyle();
     method public androidx.ui.graphics.Color? component1();
     method public androidx.ui.text.style.BaselineShift? component10();
     method public androidx.ui.text.style.TextGeometricTransform? component11();
-    method public androidx.ui.text.Locale? component12();
+    method public java.util.Locale? component12();
     method public androidx.ui.graphics.Color? component13();
     method public androidx.ui.text.style.TextDecoration? component14();
     method public androidx.ui.painting.Shadow? component15();
@@ -222,7 +214,7 @@
     method public androidx.ui.text.font.FontFamily? component7();
     method public String? component8();
     method public Float? component9();
-    method public androidx.ui.text.TextStyle copy(androidx.ui.graphics.Color? color, androidx.ui.core.Sp? fontSize, Float? fontSizeScale, androidx.ui.text.font.FontWeight? fontWeight, androidx.ui.text.font.FontStyle? fontStyle, androidx.ui.text.font.FontSynthesis? fontSynthesis, androidx.ui.text.font.FontFamily? fontFamily, String? fontFeatureSettings, Float? letterSpacing, androidx.ui.text.style.BaselineShift? baselineShift, androidx.ui.text.style.TextGeometricTransform? textGeometricTransform, androidx.ui.text.Locale? locale, androidx.ui.graphics.Color? background, androidx.ui.text.style.TextDecoration? decoration, androidx.ui.painting.Shadow? shadow);
+    method public androidx.ui.text.TextStyle copy(androidx.ui.graphics.Color? color, androidx.ui.core.Sp? fontSize, Float? fontSizeScale, androidx.ui.text.font.FontWeight? fontWeight, androidx.ui.text.font.FontStyle? fontStyle, androidx.ui.text.font.FontSynthesis? fontSynthesis, androidx.ui.text.font.FontFamily? fontFamily, String? fontFeatureSettings, Float? letterSpacing, androidx.ui.text.style.BaselineShift? baselineShift, androidx.ui.text.style.TextGeometricTransform? textGeometricTransform, java.util.Locale? locale, androidx.ui.graphics.Color? background, androidx.ui.text.style.TextDecoration? decoration, androidx.ui.painting.Shadow? shadow);
     method public androidx.ui.graphics.Color? getBackground();
     method public androidx.ui.text.style.BaselineShift? getBaselineShift();
     method public androidx.ui.graphics.Color? getColor();
@@ -235,7 +227,7 @@
     method public androidx.ui.text.font.FontSynthesis? getFontSynthesis();
     method public androidx.ui.text.font.FontWeight? getFontWeight();
     method public Float? getLetterSpacing();
-    method public androidx.ui.text.Locale? getLocale();
+    method public java.util.Locale? getLocale();
     method public androidx.ui.painting.Shadow? getShadow();
     method public androidx.ui.text.style.TextGeometricTransform? getTextGeometricTransform();
     method public androidx.ui.text.TextStyle merge(androidx.ui.text.TextStyle? other = null);
diff --git a/ui/ui-text/integration-tests/text-demos/src/main/java/androidx/ui/text/demos/CraneInputField.kt b/ui/ui-text/integration-tests/text-demos/src/main/java/androidx/ui/text/demos/CraneInputField.kt
index b345b40..a775fd1 100644
--- a/ui/ui-text/integration-tests/text-demos/src/main/java/androidx/ui/text/demos/CraneInputField.kt
+++ b/ui/ui-text/integration-tests/text-demos/src/main/java/androidx/ui/text/demos/CraneInputField.kt
@@ -20,9 +20,9 @@
 import androidx.compose.Composable
 import androidx.compose.state
 import androidx.compose.unaryPlus
-import androidx.ui.core.EditorStyle
 import androidx.ui.core.TextField
 import androidx.ui.input.EditorModel
+import androidx.ui.input.EditorStyle
 import androidx.ui.input.ImeAction
 import androidx.ui.input.KeyboardType
 import androidx.ui.layout.Column
diff --git a/ui/ui-text/integration-tests/text-demos/src/main/java/androidx/ui/text/demos/CraneText.kt b/ui/ui-text/integration-tests/text-demos/src/main/java/androidx/ui/text/demos/CraneText.kt
index a0e9bda..e9af896 100644
--- a/ui/ui-text/integration-tests/text-demos/src/main/java/androidx/ui/text/demos/CraneText.kt
+++ b/ui/ui-text/integration-tests/text-demos/src/main/java/androidx/ui/text/demos/CraneText.kt
@@ -33,7 +33,6 @@
 import androidx.ui.text.style.TextDecoration
 import androidx.ui.text.style.TextDirection
 import androidx.ui.text.font.FontFamily
-import androidx.ui.text.Locale
 import androidx.ui.graphics.Color
 import androidx.ui.graphics.lerp
 import androidx.ui.layout.Column
@@ -49,6 +48,7 @@
 import androidx.ui.core.sp
 import androidx.ui.text.AnnotatedString
 import androidx.ui.text.style.TextIndent
+import java.util.Locale
 
 val displayText = "Text Demo"
 val displayTextChinese = "文本演示"
@@ -280,10 +280,12 @@
     // This group of text widgets show different letterSpacing.
     Text {
         Span(text = "$displayText   ", style = TextStyle(fontSize = fontSize8))
-        Span(text = displayText, style = TextStyle(
-            fontSize = fontSize8,
-            letterSpacing = 0.5f
-        )
+        Span(
+            text = displayText,
+            style = TextStyle(
+                fontSize = fontSize8,
+                letterSpacing = 0.5f
+            )
         )
     }
 }
@@ -292,7 +294,6 @@
 fun TextDemoBaselineShift() {
     Text {
         Span(text = displayText, style = TextStyle(fontSize = fontSize8)) {
-
             Span(
                 text = "superscript",
                 style = TextStyle(
@@ -376,7 +377,7 @@
             text = "$text   ",
             style = TextStyle(
                 fontSize = fontSize8,
-                locale = Locale(_languageCode = "ja", _countryCode = "JP")
+                locale = Locale("ja", "JP")
             )
         )
 
@@ -384,7 +385,7 @@
             text = "$text   ",
             style = TextStyle(
                 fontSize = fontSize8,
-                locale = Locale(_languageCode = "zh", _countryCode = "CN")
+                locale = Locale("zh", "CN")
             )
         )
 
@@ -392,7 +393,7 @@
             text = text,
             style = TextStyle(
                 fontSize = fontSize8,
-                locale = Locale(_languageCode = "zh", _countryCode = "TW")
+                locale = Locale("zh", "TW")
             )
         )
     }
@@ -402,7 +403,7 @@
 fun TextDemoTextAlign() {
     // This group of text widgets show different TextAligns: LEFT, RIGHT, CENTER, JUSTIFY, START for
     // LTR and RTL, END for LTR and RTL.
-    var text: String = ""
+    var text = ""
     for (i in 1..10) {
         text = "$text$displayText "
     }
@@ -470,7 +471,7 @@
 @Composable
 fun TextDemoSoftWrap() {
     // This group of text widgets show difference between softWrap is true and false.
-    var text: String = ""
+    var text = ""
     for (i in 1..10) {
         text = "$text$displayText"
     }
@@ -493,7 +494,7 @@
 fun TexDemoTextOverflowFade() {
     var text = ""
     for (i in 1..15) {
-        text = text + displayText
+        text += displayText
     }
     val textSytle =
         TextStyle(fontSize = fontSize8, color = Color(0xFFFF0000.toInt()))
@@ -602,7 +603,7 @@
         Color(0xFF0000FF.toInt()),
         Color(0xFF00FF00.toInt()),
         Color(0xFFFF0000.toInt())
-        )
+    )
 
     val selection = +state<Selection?> { null }
     SelectionContainer(
@@ -651,7 +652,8 @@
     SelectionContainer(
         selection = selection.value,
         onSelectionChange = { selection.value = it },
-        mode = SelectionMode.Horizontal) {
+        mode = SelectionMode.Horizontal
+    ) {
         Column {
             for (i in 0..2) {
                 Row {
diff --git a/ui/ui-text/integration-tests/text-demos/src/main/java/androidx/ui/text/demos/CraneVariousInputField.kt b/ui/ui-text/integration-tests/text-demos/src/main/java/androidx/ui/text/demos/CraneVariousInputField.kt
index 47b3abb..05cfca9 100644
--- a/ui/ui-text/integration-tests/text-demos/src/main/java/androidx/ui/text/demos/CraneVariousInputField.kt
+++ b/ui/ui-text/integration-tests/text-demos/src/main/java/androidx/ui/text/demos/CraneVariousInputField.kt
@@ -20,17 +20,17 @@
 import androidx.compose.Composable
 import androidx.compose.state
 import androidx.compose.unaryPlus
-import androidx.ui.core.EditorStyle
 import androidx.ui.core.Layout
-import androidx.ui.core.OffsetMap
-import androidx.ui.core.PasswordVisualTransformation
+import androidx.ui.input.OffsetMap
+import androidx.ui.input.PasswordVisualTransformation
 import androidx.ui.core.Text
 import androidx.ui.core.TextField
-import androidx.ui.core.TransformedText
-import androidx.ui.core.VisualTransformation
+import androidx.ui.input.TransformedText
+import androidx.ui.input.VisualTransformation
 import androidx.ui.core.ipx
 import androidx.ui.graphics.Color
 import androidx.ui.input.EditorModel
+import androidx.ui.input.EditorStyle
 import androidx.ui.input.ImeAction
 import androidx.ui.input.KeyboardType
 import androidx.ui.layout.Column
@@ -41,7 +41,7 @@
 import java.util.Locale
 
 /**
- * The offset translater used for credit card input field.
+ * The offset translator used for credit card input field.
  *
  * @see creditCardFilter
  */
@@ -272,16 +272,13 @@
     if (state.value.text.isNotEmpty()) {
         inputField()
     } else {
-        Layout(
-            childrenArray = arrayOf(inputField, hintText),
-            layoutBlock = { measurable, constraints ->
-                val inputfieldPlacable = measurable[inputField].first().measure(constraints)
-                val hintTextPlacable = measurable[hintText].first().measure(constraints)
-                layout(inputfieldPlacable.width, inputfieldPlacable.height) {
-                    inputfieldPlacable.place(0.ipx, 0.ipx)
-                    hintTextPlacable.place(0.ipx, 0.ipx)
-                }
+        Layout(inputField, hintText) { measurable, constraints ->
+            val inputfieldPlacable = measurable[inputField].first().measure(constraints)
+            val hintTextPlacable = measurable[hintText].first().measure(constraints)
+            layout(inputfieldPlacable.width, inputfieldPlacable.height) {
+                inputfieldPlacable.place(0.ipx, 0.ipx)
+                hintTextPlacable.place(0.ipx, 0.ipx)
             }
-        )
+        }
     }
 }
\ No newline at end of file
diff --git a/ui/ui-text/src/androidTest/java/androidx/ui/text/MultiParagraphIntegrationTest.kt b/ui/ui-text/src/androidTest/java/androidx/ui/text/MultiParagraphIntegrationTest.kt
index 75c21b6..96f43d1 100644
--- a/ui/ui-text/src/androidTest/java/androidx/ui/text/MultiParagraphIntegrationTest.kt
+++ b/ui/ui-text/src/androidTest/java/androidx/ui/text/MultiParagraphIntegrationTest.kt
@@ -40,6 +40,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
+import java.util.Locale
 
 @RunWith(JUnit4::class)
 @SmallTest
diff --git a/ui/ui-text/src/androidTest/java/androidx/ui/text/ParagraphIntegrationTest.kt b/ui/ui-text/src/androidTest/java/androidx/ui/text/ParagraphIntegrationTest.kt
index 9718437..a134e26 100644
--- a/ui/ui-text/src/androidTest/java/androidx/ui/text/ParagraphIntegrationTest.kt
+++ b/ui/ui-text/src/androidTest/java/androidx/ui/text/ParagraphIntegrationTest.kt
@@ -35,19 +35,25 @@
 import androidx.ui.text.font.FontFamily
 import androidx.ui.text.font.asFontFamily
 import androidx.ui.graphics.Color
+import androidx.ui.painting.Canvas
+import androidx.ui.painting.Image
+import androidx.ui.painting.ImageConfig
 import androidx.ui.text.matchers.equalToBitmap
 import androidx.ui.painting.Path
 import androidx.ui.painting.PathOperation
 import androidx.ui.painting.Shadow
 import androidx.ui.text.style.TextAlign
 import androidx.ui.text.style.TextIndent
-import com.nhaarman.mockitokotlin2.mock
 import org.hamcrest.Matchers.equalTo
+import org.hamcrest.Matchers.greaterThan
 import org.hamcrest.Matchers.not
 import org.junit.Assert.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
+import java.util.Locale
+import org.mockito.Mockito.mock
+import kotlin.math.roundToInt
 
 @RunWith(JUnit4::class)
 @SmallTest
@@ -1000,10 +1006,10 @@
             val fontSizeInPx = fontSize.toPx().value
             val locales = arrayOf(
                 // duplicate ja is on purpose
-                Locale(_languageCode = "ja"),
-                Locale(_languageCode = "ja"),
-                Locale(_languageCode = "zh", _countryCode = "CN"),
-                Locale(_languageCode = "zh", _countryCode = "TW")
+                Locale("ja"),
+                Locale("ja"),
+                Locale("zh", "CN"),
+                Locale("zh", "TW")
             )
 
             val bitmaps = locales.map { locale ->
@@ -1115,6 +1121,51 @@
     }
 
     @Test
+    fun maxLines_paintDifferently() {
+        withDensity(defaultDensity) {
+            val text = "a\na\na"
+            val fontSize = 100.sp
+            val fontSizeInPx = fontSize.toPx().value
+            val maxLines = 1
+
+            val paragraphWithMaxLine = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                maxLines = maxLines
+            )
+            paragraphWithMaxLine.layout(ParagraphConstraints(width = fontSizeInPx))
+
+            val paragraphNoMaxLine = simpleParagraph(
+                text = text,
+                fontSize = fontSize
+            )
+            paragraphNoMaxLine.layout(ParagraphConstraints(width = fontSizeInPx))
+
+            // Make sure the maxLine is applied correctly
+            assertThat(paragraphNoMaxLine.height, greaterThan(paragraphWithMaxLine.height))
+
+            val imageNoMaxLine = Image(
+                paragraphNoMaxLine.width.roundToInt(),
+                paragraphNoMaxLine.height.roundToInt(),
+                ImageConfig.Argb8888
+            )
+            // Same size with imageNoMaxLine for comparison
+            val imageWithMaxLine = Image(
+                paragraphNoMaxLine.width.roundToInt(),
+                paragraphNoMaxLine.height.roundToInt(),
+                ImageConfig.Argb8888
+            )
+
+            paragraphNoMaxLine.paint(Canvas(imageNoMaxLine))
+            paragraphWithMaxLine.paint(Canvas(imageWithMaxLine))
+            assertThat(
+                imageNoMaxLine.nativeImage,
+                not(equalToBitmap(imageWithMaxLine.nativeImage))
+            )
+        }
+    }
+
+    @Test
     fun didExceedMaxLines_withMaxLinesSmallerThanTextLines_returnsTrue() {
         val text = "aaa\naa"
         val maxLines = text.lines().size - 1
@@ -2496,7 +2547,7 @@
     fun paint_throws_exception_if_layout_is_not_called() {
         val paragraph = simpleParagraph()
 
-        paragraph.paint(mock())
+        paragraph.paint(mock(Canvas::class.java))
     }
 
     @Test(expected = IllegalStateException::class)
diff --git a/ui/ui-text/src/androidTest/java/androidx/ui/text/TextDelegateIntegrationTest.kt b/ui/ui-text/src/androidTest/java/androidx/ui/text/TextDelegateIntegrationTest.kt
new file mode 100644
index 0000000..c69e186
--- /dev/null
+++ b/ui/ui-text/src/androidTest/java/androidx/ui/text/TextDelegateIntegrationTest.kt
@@ -0,0 +1,703 @@
+/*
+ * Copyright 2019 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.ui.text
+
+import android.graphics.Bitmap
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.ui.core.Constraints
+import androidx.ui.core.Density
+import androidx.ui.core.PxPosition
+import androidx.ui.core.ipx
+import androidx.ui.core.px
+import androidx.ui.core.sp
+import androidx.ui.core.withDensity
+import androidx.ui.engine.geometry.Rect
+import androidx.ui.engine.geometry.Size
+import androidx.ui.text.FontTestData.Companion.BASIC_MEASURE_FONT
+import androidx.ui.text.style.TextDirection
+import androidx.ui.text.font.asFontFamily
+import androidx.ui.graphics.Color
+import androidx.ui.text.matchers.equalToBitmap
+import androidx.ui.painting.Canvas
+import androidx.ui.painting.Paint
+import androidx.ui.text.style.TextOverflow
+import com.google.common.truth.Truth.assertThat
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import kotlin.math.ceil
+
+@RunWith(JUnit4::class)
+@SmallTest
+class TextDelegateIntegrationTest {
+
+    private val fontFamily = BASIC_MEASURE_FONT.asFontFamily()
+    private val density = Density(density = 1f)
+    private val context = InstrumentationRegistry.getInstrumentation().context
+    private val resourceLoader = TestFontResourceLoader(context)
+
+    // TODO(Migration/qqd): The default font size should be 14.0 but it returns 15.0. Need further
+    // investigation. It is being changed in the native level, and probably related to the font.
+//    @Test
+//    fun preferredLineHeight_style_not_set() {
+//        val defaultTextStyle = TextStyle(fontFamily = fontFamily)
+//        val textPainter = TextDelegate(style = defaultTextStyle)
+//
+//        val prefferedHeight = textPainter.preferredLineHeight
+//
+//        assertThat(prefferedHeight).isEqualTo(14.0)
+//    }
+
+    @Test
+    fun minIntrinsicWidth_getter() {
+        val fontSize = 20.sp
+        val text = "Hello"
+        val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
+        val annotatedString = AnnotatedString(
+            text = text,
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+        )
+        val textPainter = TextDelegate(
+            text = annotatedString,
+            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
+            density = density,
+            resourceLoader = resourceLoader
+        )
+
+        textPainter.layout(Constraints())
+
+        assertThat(textPainter.minIntrinsicWidth).isEqualTo(0.0f)
+    }
+
+    @Test
+    fun maxIntrinsicWidth_getter() {
+        withDensity(density) {
+            val fontSize = 20.sp
+            val text = "Hello"
+            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
+            val annotatedString = AnnotatedString(
+                text = text,
+                textStyles = listOf(
+                    AnnotatedString.Item(
+                        textStyle,
+                        0,
+                        text.length
+                    )
+                )
+            )
+            val textPainter = TextDelegate(
+                text = annotatedString,
+                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
+                density = density,
+                resourceLoader = resourceLoader
+            )
+
+            textPainter.layout(Constraints())
+
+            assertThat(textPainter.maxIntrinsicWidth).isEqualTo(fontSize.toPx().value * text.length)
+        }
+    }
+
+    @Test
+    fun width_getter() {
+        withDensity(density) {
+            val fontSize = 20.sp
+            val text = "Hello"
+            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
+            val annotatedString = AnnotatedString(
+                text = text,
+                textStyles = listOf(
+                    AnnotatedString.Item(
+                        textStyle,
+                        0,
+                        text.length
+                    )
+                )
+            )
+            val textPainter = TextDelegate(
+                text = annotatedString,
+                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
+                density = density,
+                resourceLoader = resourceLoader
+            )
+
+            textPainter.layout(Constraints(0.ipx, 200.ipx))
+
+            assertThat(textPainter.width).isEqualTo(fontSize.toPx().value * text.length)
+        }
+    }
+
+    @Test
+    fun width_getter_with_small_width() {
+        val text = "Hello"
+        val width = 80.ipx
+        val textStyle = TextStyle(fontSize = 20.sp, fontFamily = fontFamily)
+        val annotatedString = AnnotatedString(
+            text = text,
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+        )
+        val textPainter = TextDelegate(
+            text = annotatedString,
+            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
+            density = density,
+            resourceLoader = resourceLoader
+        )
+
+        textPainter.layout(Constraints(maxWidth = width))
+
+        assertThat(textPainter.width).isEqualTo(width.value.toFloat())
+    }
+
+    @Test
+    fun height_getter() {
+        withDensity(density) {
+            val fontSize = 20.sp
+            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
+            val text = "hello"
+            val annotatedString = AnnotatedString(
+                text = text,
+                textStyles = listOf(
+                    AnnotatedString.Item(
+                        textStyle,
+                        0,
+                        text.length
+                    )
+                )
+            )
+            val textPainter = TextDelegate(
+                text = annotatedString,
+                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
+                density = density,
+                resourceLoader = resourceLoader
+            )
+
+            textPainter.layout(Constraints())
+
+            assertThat(textPainter.height).isEqualTo(fontSize.toPx().value)
+        }
+    }
+
+    @Test
+    fun size_getter() {
+        withDensity(density) {
+            val fontSize = 20.sp
+            val fontSizeInPx = fontSize.toPx().value
+            val text = "Hello"
+            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
+            val annotatedString = AnnotatedString(
+                text = text,
+                textStyles = listOf(
+                    AnnotatedString.Item(
+                        textStyle,
+                        0,
+                        text.length
+                    )
+                )
+            )
+            val textPainter = TextDelegate(
+                text = annotatedString,
+                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
+                density = density,
+                resourceLoader = resourceLoader
+            )
+
+            textPainter.layout(Constraints())
+
+            assertThat(textPainter.size).isEqualTo(
+                Size(
+                    width = fontSizeInPx * text.length,
+                    height = fontSizeInPx
+                )
+            )
+        }
+    }
+
+    @Test
+    fun didExceedMaxLines_exceed() {
+        var text = ""
+        for (i in 1..50) text += " Hello"
+        val annotatedString = AnnotatedString(text = text)
+        val textPainter = TextDelegate(
+            text = annotatedString,
+            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
+            maxLines = 2,
+            density = density,
+            resourceLoader = resourceLoader
+        )
+
+        textPainter.layout(Constraints(0.ipx, 200.ipx))
+
+        assertThat(textPainter.didExceedMaxLines).isTrue()
+    }
+
+    @Test
+    fun didExceedMaxLines_not_exceed() {
+        val text = "Hello"
+        val annotatedString = AnnotatedString(text = text)
+        val textPainter = TextDelegate(
+            text = annotatedString,
+            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
+            maxLines = 2,
+            density = density,
+            resourceLoader = resourceLoader
+        )
+
+        textPainter.layout(Constraints(0.ipx, 200.ipx))
+
+        assertThat(textPainter.didExceedMaxLines).isFalse()
+    }
+
+    @Test
+    fun layout_build_paragraph() {
+        val textPainter = TextDelegate(
+            text = AnnotatedString(text = "Hello"),
+            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
+            density = density,
+            resourceLoader = resourceLoader
+        )
+
+        textPainter.layout(Constraints(0.ipx, 20.ipx))
+
+        assertThat(textPainter.multiParagraph).isNotNull()
+    }
+
+    @Test
+    fun getPositionForOffset_First_Character() {
+        val text = "Hello"
+        val annotatedString = AnnotatedString(
+            text = text,
+            textStyles = listOf(
+                AnnotatedString.Item(
+                    TextStyle(fontSize = 20.sp, fontFamily = fontFamily),
+                    0,
+                    text.length
+                )
+            )
+        )
+        val textPainter = TextDelegate(
+            text = annotatedString,
+            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
+            density = density,
+            resourceLoader = resourceLoader
+        )
+        textPainter.layout(Constraints())
+
+        val selection = textPainter.getOffsetForPosition(PxPosition.Origin)
+
+        assertThat(selection).isEqualTo(0)
+    }
+
+    @Test
+    fun getPositionForOffset_other_Character() {
+        withDensity(density) {
+            val fontSize = 20.sp
+            val characterIndex = 2 // Start from 0.
+            val text = "Hello"
+            val annotatedString = AnnotatedString(
+                text = text,
+                textStyles = listOf(
+                    AnnotatedString.Item(
+                        TextStyle(fontSize = fontSize, fontFamily = fontFamily),
+                        0,
+                        text.length
+                    )
+                )
+            )
+            val textPainter = TextDelegate(
+                text = annotatedString,
+                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
+                density = density,
+                resourceLoader = resourceLoader
+            )
+            textPainter.layout(Constraints())
+
+            val selection = textPainter.getOffsetForPosition(
+                position = PxPosition((fontSize.toPx().value * characterIndex + 1).px, 0.px)
+            )
+
+            assertThat(selection).isEqualTo(characterIndex)
+        }
+    }
+
+    @Test
+    fun hasOverflowShaderFalse() {
+        val text = "Hello"
+        val textStyle = TextStyle(fontSize = 20.sp, fontFamily = fontFamily)
+        val annotatedString = AnnotatedString(
+            text = text,
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+        )
+        val textPainter = TextDelegate(
+            text = annotatedString,
+            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
+            density = density,
+            resourceLoader = resourceLoader
+        )
+
+        textPainter.layout(Constraints())
+
+        assertThat(textPainter.hasVisualOverflow).isFalse()
+    }
+
+    @Test
+    fun hasOverflowShaderFadeHorizontallyTrue() {
+        var text = ""
+        for (i in 1..15) {
+            text = text + "Hello World"
+        }
+        val textStyle = TextStyle(fontSize = 20.sp, fontFamily = fontFamily)
+        val annotatedString = AnnotatedString(
+            text = text,
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+        )
+        val textPainter = TextDelegate(
+            text = annotatedString,
+            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
+            overflow = TextOverflow.Fade,
+            softWrap = false,
+            maxLines = 1,
+            density = density,
+            resourceLoader = resourceLoader
+        )
+
+        textPainter.layout(Constraints(maxWidth = 100.ipx))
+
+        assertThat(textPainter.hasVisualOverflow).isTrue()
+    }
+
+    @Test
+    fun hasOverflowShaderFadeVerticallyTrue() {
+        var text = ""
+        for (i in 1..30) {
+            text = text + "Hello World"
+        }
+        val textStyle = TextStyle(fontSize = 20.sp, fontFamily = fontFamily)
+        val annotatedString = AnnotatedString(
+            text = text,
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+        )
+        val textPainter = TextDelegate(
+            text = annotatedString,
+            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
+            overflow = TextOverflow.Fade,
+            maxLines = 2,
+            density = density,
+            resourceLoader = resourceLoader
+        )
+
+        textPainter.layout(Constraints(maxWidth = 100.ipx))
+
+        assertThat(textPainter.hasVisualOverflow).isTrue()
+    }
+
+    @Test
+    fun testBackgroundPaint_paint_wrap_multiLines() {
+        withDensity(density) {
+            // Setup test.
+            val fontSize = 20.sp
+            val fontSizeInPx = fontSize.toPx().value
+            val text = "HelloHello"
+            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
+            val annotatedString = AnnotatedString(
+                text = text,
+                textStyles = listOf(
+                    AnnotatedString.Item(
+                        textStyle,
+                        0,
+                        text.length
+                    )
+                )
+            )
+            val textPainter = TextDelegate(
+                text = annotatedString,
+                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
+                density = density,
+                resourceLoader = resourceLoader
+            )
+            textPainter.layout(Constraints(maxWidth = 120.ipx))
+
+            val expectedBitmap = Bitmap.createBitmap(
+                ceil(textPainter.width).toInt(),
+                ceil(textPainter.height).toInt(),
+                Bitmap.Config.ARGB_8888
+            )
+            val expectedCanvas =
+                Canvas(android.graphics.Canvas(expectedBitmap))
+            val expectedPaint = Paint()
+            val defaultSelectionColor = Color(0x6633B5E5)
+            expectedPaint.color = defaultSelectionColor
+
+            val firstLineLeft = textPainter.multiParagraph?.getLineLeft(0)
+            val secondLineLeft = textPainter.multiParagraph?.getLineLeft(1)
+            val firstLineRight = textPainter.multiParagraph?.getLineRight(0)
+            val secondLineRight = textPainter.multiParagraph?.getLineRight(1)
+            expectedCanvas.drawRect(
+                Rect(firstLineLeft!!, 0f, firstLineRight!!, fontSizeInPx),
+                expectedPaint
+            )
+            expectedCanvas.drawRect(
+                Rect(
+                    secondLineLeft!!,
+                    fontSizeInPx,
+                    secondLineRight!!,
+                    textPainter.multiParagraph!!.height
+                ),
+                expectedPaint
+            )
+
+            val actualBitmap = Bitmap.createBitmap(
+                ceil(textPainter.width).toInt(),
+                ceil(textPainter.height).toInt(),
+                Bitmap.Config.ARGB_8888
+            )
+            val actualCanvas = Canvas(android.graphics.Canvas(actualBitmap))
+
+            // Run.
+            // Select all.
+            textPainter.paintBackground(
+                start = 0,
+                end = text.length,
+                color = defaultSelectionColor,
+                canvas = actualCanvas
+            )
+
+            // Assert.
+            Assert.assertThat(actualBitmap, equalToBitmap(expectedBitmap))
+        }
+    }
+
+    @Test
+    fun testBackgroundPaint_paint_with_default_color() {
+        withDensity(density) {
+            // Setup test.
+            val selectionStart = 0
+            val selectionEnd = 3
+            val fontSize = 20.sp
+            val fontSizeInPx = fontSize.toPx().value
+            val text = "Hello"
+            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
+            val annotatedString = AnnotatedString(
+                text = text,
+                textStyles = listOf(
+                    AnnotatedString.Item(
+                        textStyle,
+                        0,
+                        text.length
+                    )
+                )
+            )
+            val textPainter = TextDelegate(
+                text = annotatedString,
+                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
+                density = density,
+                resourceLoader = resourceLoader
+            )
+            textPainter.layout(Constraints())
+
+            val expectedBitmap = Bitmap.createBitmap(
+                ceil(textPainter.width).toInt(),
+                ceil(textPainter.height).toInt(),
+                Bitmap.Config.ARGB_8888
+            )
+            val expectedCanvas =
+                Canvas(android.graphics.Canvas(expectedBitmap))
+            val expectedPaint = Paint()
+            val defaultSelectionColor = Color(0x6633B5E5)
+            expectedPaint.color = defaultSelectionColor
+            expectedCanvas.drawRect(
+                Rect(
+                    left = 0f,
+                    top = 0f,
+                    right = fontSizeInPx * (selectionEnd - selectionStart),
+                    bottom = fontSizeInPx
+                ),
+                expectedPaint
+            )
+
+            val actualBitmap = Bitmap.createBitmap(
+                ceil(textPainter.width).toInt(),
+                ceil(textPainter.height).toInt(),
+                Bitmap.Config.ARGB_8888
+            )
+            val actualCanvas = Canvas(android.graphics.Canvas(actualBitmap))
+
+            // Run.
+            textPainter.paintBackground(
+                start = selectionStart,
+                end = selectionEnd,
+                color = defaultSelectionColor,
+                canvas = actualCanvas
+            )
+
+            // Assert
+            Assert.assertThat(actualBitmap, equalToBitmap(expectedBitmap))
+        }
+    }
+
+    @Test
+    fun testBackgroundPaint_paint_with_default_color_bidi() {
+        withDensity(density) {
+            // Setup test.
+            val textLTR = "Hello"
+            // From right to left: שלום
+            val textRTL = "\u05e9\u05dc\u05d5\u05dd"
+            val text = textLTR + textRTL
+            val selectionLTRStart = 2
+            val selectionRTLEnd = 2
+            val fontSize = 20.sp
+            val fontSizeInPx = fontSize.toPx().value
+            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
+            val annotatedString = AnnotatedString(
+                text = text,
+                textStyles = listOf(
+                    AnnotatedString.Item(
+                        textStyle,
+                        0,
+                        text.length
+                    )
+                )
+            )
+            val textPainter = TextDelegate(
+                text = annotatedString,
+                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
+                density = density,
+                resourceLoader = resourceLoader
+            )
+            textPainter.layout(Constraints())
+
+            val expectedBitmap = Bitmap.createBitmap(
+                ceil(textPainter.width).toInt(),
+                ceil(textPainter.height).toInt(),
+                Bitmap.Config.ARGB_8888
+            )
+            val expectedCanvas =
+                Canvas(android.graphics.Canvas(expectedBitmap))
+            val expectedPaint = Paint()
+            val defaultSelectionColor = Color(0x6633B5E5)
+            expectedPaint.color = defaultSelectionColor
+            // Select "llo".
+            expectedCanvas.drawRect(
+                Rect(
+                    left = fontSizeInPx * selectionLTRStart,
+                    top = 0f,
+                    right = textLTR.length * fontSizeInPx,
+                    bottom = fontSizeInPx
+                ),
+                expectedPaint
+            )
+
+            // Select "של"
+            expectedCanvas.drawRect(
+                Rect(
+                    left = (textLTR.length + textRTL.length - selectionRTLEnd) * fontSizeInPx,
+                    top = 0f,
+                    right = (textLTR.length + textRTL.length) * fontSizeInPx,
+                    bottom = fontSizeInPx
+                ),
+                expectedPaint
+            )
+
+            val actualBitmap = Bitmap.createBitmap(
+                ceil(textPainter.width).toInt(),
+                ceil(textPainter.height).toInt(),
+                Bitmap.Config.ARGB_8888
+            )
+            val actualCanvas = Canvas(android.graphics.Canvas(actualBitmap))
+
+            // Run.
+            textPainter.paintBackground(
+                start = selectionLTRStart,
+                end = textLTR.length + selectionRTLEnd,
+                color = defaultSelectionColor,
+                canvas = actualCanvas
+            )
+
+            // Assert
+            Assert.assertThat(actualBitmap, equalToBitmap(expectedBitmap))
+        }
+    }
+
+    @Test
+    fun testBackgroundPaint_paint_with_customized_color() {
+        withDensity(density) {
+            // Setup test.
+            val selectionStart = 0
+            val selectionEnd = 3
+            val fontSize = 20.sp
+            val fontSizeInPx = fontSize.toPx().value
+            val text = "Hello"
+            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
+            val annotatedString = AnnotatedString(
+                text = text,
+                textStyles = listOf(
+                    AnnotatedString.Item(
+                        textStyle,
+                        0,
+                        text.length
+                    )
+                )
+            )
+            val selectionColor = Color(0x66AABB33)
+            val textPainter = TextDelegate(
+                text = annotatedString,
+                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
+                density = density,
+                resourceLoader = resourceLoader
+            )
+            textPainter.layout(Constraints())
+
+            val expectedBitmap = Bitmap.createBitmap(
+                ceil(textPainter.width).toInt(),
+                ceil(textPainter.height).toInt(),
+                Bitmap.Config.ARGB_8888
+            )
+            val expectedCanvas =
+                Canvas(android.graphics.Canvas(expectedBitmap))
+            val expectedPaint = Paint()
+            expectedPaint.color = selectionColor
+            expectedCanvas.drawRect(
+                Rect(
+                    left = 0f,
+                    top = 0f,
+                    right = fontSizeInPx * (selectionEnd - selectionStart),
+                    bottom = fontSizeInPx
+                ),
+                expectedPaint
+            )
+
+            val actualBitmap = Bitmap.createBitmap(
+                ceil(textPainter.width).toInt(),
+                ceil(textPainter.height).toInt(),
+                Bitmap.Config.ARGB_8888
+            )
+            val actualCanvas = Canvas(android.graphics.Canvas(actualBitmap))
+
+            // Run.
+            textPainter.paintBackground(
+                start = selectionStart,
+                end = selectionEnd,
+                color = selectionColor,
+                canvas = actualCanvas
+            )
+
+            // Assert
+            Assert.assertThat(actualBitmap, equalToBitmap(expectedBitmap))
+        }
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-text/src/androidTest/java/androidx/ui/text/TextPainterIntegrationTest.kt b/ui/ui-text/src/androidTest/java/androidx/ui/text/TextPainterIntegrationTest.kt
deleted file mode 100644
index 3b17aae..0000000
--- a/ui/ui-text/src/androidTest/java/androidx/ui/text/TextPainterIntegrationTest.kt
+++ /dev/null
@@ -1,719 +0,0 @@
-/*
- * Copyright 2019 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.ui.text
-
-import android.graphics.Bitmap
-import androidx.test.filters.SmallTest
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.ui.core.Constraints
-import androidx.ui.core.Density
-import androidx.ui.core.PxPosition
-import androidx.ui.core.ipx
-import androidx.ui.core.px
-import androidx.ui.core.sp
-import androidx.ui.core.withDensity
-import androidx.ui.engine.geometry.Rect
-import androidx.ui.engine.geometry.Size
-import androidx.ui.text.FontTestData.Companion.BASIC_MEASURE_FONT
-import androidx.ui.text.style.TextDirection
-import androidx.ui.text.font.asFontFamily
-import androidx.ui.graphics.Color
-import androidx.ui.text.matchers.equalToBitmap
-import androidx.ui.painting.Canvas
-import androidx.ui.painting.Paint
-import androidx.ui.text.style.TextOverflow
-import com.google.common.truth.Truth.assertThat
-import org.junit.Assert
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-import kotlin.math.ceil
-
-@RunWith(JUnit4::class)
-@SmallTest
-class TextPainterIntegrationTest {
-
-    private val fontFamily = BASIC_MEASURE_FONT.asFontFamily()
-    private val density = Density(density = 1f)
-    private val context = InstrumentationRegistry.getInstrumentation().context
-    private val resourceLoader = TestFontResourceLoader(context)
-
-    @Test
-    fun preferredLineHeight_style_set() {
-        withDensity(density) {
-            val fontSize = 20.sp
-            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
-            val textPainter = TextPainter(
-                style = textStyle,
-                density = density,
-                resourceLoader = resourceLoader
-            )
-            val preferredHeight = textPainter.preferredLineHeight
-
-            assertThat(preferredHeight).isEqualTo(fontSize.toPx().value)
-        }
-    }
-
-    // TODO(Migration/qqd): The default font size should be 14.0 but it returns 15.0. Need further
-    // investigation. It is being changed in the native level, and probably related to the font.
-//    @Test
-//    fun preferredLineHeight_style_not_set() {
-//        val defaultTextStyle = TextStyle(fontFamily = fontFamily)
-//        val textPainter = TextPainter(style = defaultTextStyle)
-//
-//        val prefferedHeight = textPainter.preferredLineHeight
-//
-//        assertThat(prefferedHeight).isEqualTo(14.0)
-//    }
-
-    @Test
-    fun minIntrinsicWidth_getter() {
-        val fontSize = 20.sp
-        val text = "Hello"
-        val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
-        val annotatedString = AnnotatedString(
-            text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
-        )
-        val textPainter = TextPainter(
-            text = annotatedString,
-            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
-            density = density,
-            resourceLoader = resourceLoader
-        )
-
-        textPainter.layout(Constraints())
-
-        assertThat(textPainter.minIntrinsicWidth).isEqualTo(0.0f)
-    }
-
-    @Test
-    fun maxIntrinsicWidth_getter() {
-        withDensity(density) {
-            val fontSize = 20.sp
-            val text = "Hello"
-            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
-            val annotatedString = AnnotatedString(
-                text = text,
-                textStyles = listOf(
-                    AnnotatedString.Item(
-                        textStyle,
-                        0,
-                        text.length
-                    )
-                )
-            )
-            val textPainter = TextPainter(
-                text = annotatedString,
-                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
-                density = density,
-                resourceLoader = resourceLoader
-            )
-
-            textPainter.layout(Constraints())
-
-            assertThat(textPainter.maxIntrinsicWidth).isEqualTo(fontSize.toPx().value * text.length)
-        }
-    }
-
-    @Test
-    fun width_getter() {
-        withDensity(density) {
-            val fontSize = 20.sp
-            val text = "Hello"
-            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
-            val annotatedString = AnnotatedString(
-                text = text,
-                textStyles = listOf(
-                    AnnotatedString.Item(
-                        textStyle,
-                        0,
-                        text.length
-                    )
-                )
-            )
-            val textPainter = TextPainter(
-                text = annotatedString,
-                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
-                density = density,
-                resourceLoader = resourceLoader
-            )
-
-            textPainter.layout(Constraints(0.ipx, 200.ipx))
-
-            assertThat(textPainter.width).isEqualTo(fontSize.toPx().value * text.length)
-        }
-    }
-
-    @Test
-    fun width_getter_with_small_width() {
-        val text = "Hello"
-        val width = 80.ipx
-        val textStyle = TextStyle(fontSize = 20.sp, fontFamily = fontFamily)
-        val annotatedString = AnnotatedString(
-            text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
-        )
-        val textPainter = TextPainter(
-            text = annotatedString,
-            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
-            density = density,
-            resourceLoader = resourceLoader
-        )
-
-        textPainter.layout(Constraints(maxWidth = width))
-
-        assertThat(textPainter.width).isEqualTo(width.value.toFloat())
-    }
-
-    @Test
-    fun height_getter() {
-        withDensity(density) {
-            val fontSize = 20.sp
-            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
-            val text = "hello"
-            val annotatedString = AnnotatedString(
-                text = text,
-                textStyles = listOf(
-                    AnnotatedString.Item(
-                        textStyle,
-                        0,
-                        text.length
-                    )
-                )
-            )
-            val textPainter = TextPainter(
-                text = annotatedString,
-                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
-                density = density,
-                resourceLoader = resourceLoader
-            )
-
-            textPainter.layout(Constraints())
-
-            assertThat(textPainter.height).isEqualTo(fontSize.toPx().value)
-        }
-    }
-
-    @Test
-    fun size_getter() {
-        withDensity(density) {
-            val fontSize = 20.sp
-            val fontSizeInPx = fontSize.toPx().value
-            val text = "Hello"
-            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
-            val annotatedString = AnnotatedString(
-                text = text,
-                textStyles = listOf(
-                    AnnotatedString.Item(
-                        textStyle,
-                        0,
-                        text.length
-                    )
-                )
-            )
-            val textPainter = TextPainter(
-                text = annotatedString,
-                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
-                density = density,
-                resourceLoader = resourceLoader
-            )
-
-            textPainter.layout(Constraints())
-
-            assertThat(textPainter.size).isEqualTo(
-                Size(
-                    width = fontSizeInPx * text.length,
-                    height = fontSizeInPx
-                )
-            )
-        }
-    }
-
-    @Test
-    fun didExceedMaxLines_exceed() {
-        var text = ""
-        for (i in 1..50) text += " Hello"
-        val annotatedString = AnnotatedString(text = text)
-        val textPainter = TextPainter(
-            text = annotatedString,
-            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
-            maxLines = 2,
-            density = density,
-            resourceLoader = resourceLoader
-        )
-
-        textPainter.layout(Constraints(0.ipx, 200.ipx))
-
-        assertThat(textPainter.didExceedMaxLines).isTrue()
-    }
-
-    @Test
-    fun didExceedMaxLines_not_exceed() {
-        val text = "Hello"
-        val annotatedString = AnnotatedString(text = text)
-        val textPainter = TextPainter(
-            text = annotatedString,
-            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
-            maxLines = 2,
-            density = density,
-            resourceLoader = resourceLoader
-        )
-
-        textPainter.layout(Constraints(0.ipx, 200.ipx))
-
-        assertThat(textPainter.didExceedMaxLines).isFalse()
-    }
-
-    @Test
-    fun layout_build_paragraph() {
-        val textPainter = TextPainter(
-            text = AnnotatedString(text = "Hello"),
-            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
-            density = density,
-            resourceLoader = resourceLoader
-        )
-
-        textPainter.layout(Constraints(0.ipx, 20.ipx))
-
-        assertThat(textPainter.multiParagraph).isNotNull()
-    }
-
-    @Test
-    fun getPositionForOffset_First_Character() {
-        val text = "Hello"
-        val annotatedString = AnnotatedString(
-            text = text,
-            textStyles = listOf(
-                AnnotatedString.Item(
-                    TextStyle(fontSize = 20.sp, fontFamily = fontFamily),
-                    0,
-                    text.length
-                )
-            )
-        )
-        val textPainter = TextPainter(
-            text = annotatedString,
-            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
-            density = density,
-            resourceLoader = resourceLoader
-        )
-        textPainter.layout(Constraints())
-
-        val selection = textPainter.getOffsetForPosition(PxPosition.Origin)
-
-        assertThat(selection).isEqualTo(0)
-    }
-
-    @Test
-    fun getPositionForOffset_other_Character() {
-        withDensity(density) {
-            val fontSize = 20.sp
-            val characterIndex = 2 // Start from 0.
-            val text = "Hello"
-            val annotatedString = AnnotatedString(
-                text = text,
-                textStyles = listOf(
-                    AnnotatedString.Item(
-                        TextStyle(fontSize = fontSize, fontFamily = fontFamily),
-                        0,
-                        text.length
-                    )
-                )
-            )
-            val textPainter = TextPainter(
-                text = annotatedString,
-                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
-                density = density,
-                resourceLoader = resourceLoader
-            )
-            textPainter.layout(Constraints())
-
-            val selection = textPainter.getOffsetForPosition(
-                position = PxPosition((fontSize.toPx().value * characterIndex + 1).px, 0.px)
-            )
-
-            assertThat(selection).isEqualTo(characterIndex)
-        }
-    }
-
-    @Test
-    fun hasOverflowShaderFalse() {
-        val text = "Hello"
-        val textStyle = TextStyle(fontSize = 20.sp, fontFamily = fontFamily)
-        val annotatedString = AnnotatedString(
-            text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
-        )
-        val textPainter = TextPainter(
-            text = annotatedString,
-            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
-            density = density,
-            resourceLoader = resourceLoader
-        )
-
-        textPainter.layout(Constraints())
-
-        assertThat(textPainter.hasVisualOverflow).isFalse()
-    }
-
-    @Test
-    fun hasOverflowShaderFadeHorizontallyTrue() {
-        var text = ""
-        for (i in 1..15) {
-            text = text + "Hello World"
-        }
-        val textStyle = TextStyle(fontSize = 20.sp, fontFamily = fontFamily)
-        val annotatedString = AnnotatedString(
-            text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
-        )
-        val textPainter = TextPainter(
-            text = annotatedString,
-            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
-            overflow = TextOverflow.Fade,
-            softWrap = false,
-            maxLines = 1,
-            density = density,
-            resourceLoader = resourceLoader
-        )
-
-        textPainter.layout(Constraints(maxWidth = 100.ipx))
-
-        assertThat(textPainter.hasVisualOverflow).isTrue()
-    }
-
-    @Test
-    fun hasOverflowShaderFadeVerticallyTrue() {
-        var text = ""
-        for (i in 1..30) {
-            text = text + "Hello World"
-        }
-        val textStyle = TextStyle(fontSize = 20.sp, fontFamily = fontFamily)
-        val annotatedString = AnnotatedString(
-            text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
-        )
-        val textPainter = TextPainter(
-            text = annotatedString,
-            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
-            overflow = TextOverflow.Fade,
-            maxLines = 2,
-            density = density,
-            resourceLoader = resourceLoader
-        )
-
-        textPainter.layout(Constraints(maxWidth = 100.ipx))
-
-        assertThat(textPainter.hasVisualOverflow).isTrue()
-    }
-
-    @Test
-    fun testBackgroundPaint_paint_wrap_multiLines() {
-        withDensity(density) {
-            // Setup test.
-            val fontSize = 20.sp
-            val fontSizeInPx = fontSize.toPx().value
-            val text = "HelloHello"
-            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
-            val annotatedString = AnnotatedString(
-                text = text,
-                textStyles = listOf(
-                    AnnotatedString.Item(
-                        textStyle,
-                        0,
-                        text.length
-                    )
-                )
-            )
-            val textPainter = TextPainter(
-                text = annotatedString,
-                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
-                density = density,
-                resourceLoader = resourceLoader
-            )
-            textPainter.layout(Constraints(maxWidth = 120.ipx))
-
-            val expectedBitmap = Bitmap.createBitmap(
-                ceil(textPainter.width).toInt(),
-                ceil(textPainter.height).toInt(),
-                Bitmap.Config.ARGB_8888
-            )
-            val expectedCanvas =
-                Canvas(android.graphics.Canvas(expectedBitmap))
-            val expectedPaint = Paint()
-            val defaultSelectionColor = Color(0x6633B5E5)
-            expectedPaint.color = defaultSelectionColor
-
-            val firstLineLeft = textPainter.multiParagraph?.getLineLeft(0)
-            val secondLineLeft = textPainter.multiParagraph?.getLineLeft(1)
-            val firstLineRight = textPainter.multiParagraph?.getLineRight(0)
-            val secondLineRight = textPainter.multiParagraph?.getLineRight(1)
-            expectedCanvas.drawRect(
-                Rect(firstLineLeft!!, 0f, firstLineRight!!, fontSizeInPx),
-                expectedPaint
-            )
-            expectedCanvas.drawRect(
-                Rect(
-                    secondLineLeft!!,
-                    fontSizeInPx,
-                    secondLineRight!!,
-                    textPainter.multiParagraph!!.height
-                ),
-                expectedPaint
-            )
-
-            val actualBitmap = Bitmap.createBitmap(
-                ceil(textPainter.width).toInt(),
-                ceil(textPainter.height).toInt(),
-                Bitmap.Config.ARGB_8888
-            )
-            val actualCanvas = Canvas(android.graphics.Canvas(actualBitmap))
-
-            // Run.
-            // Select all.
-            textPainter.paintBackground(
-                start = 0,
-                end = text.length,
-                color = defaultSelectionColor,
-                canvas = actualCanvas
-            )
-
-            // Assert.
-            Assert.assertThat(actualBitmap, equalToBitmap(expectedBitmap))
-        }
-    }
-
-    @Test
-    fun testBackgroundPaint_paint_with_default_color() {
-        withDensity(density) {
-            // Setup test.
-            val selectionStart = 0
-            val selectionEnd = 3
-            val fontSize = 20.sp
-            val fontSizeInPx = fontSize.toPx().value
-            val text = "Hello"
-            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
-            val annotatedString = AnnotatedString(
-                text = text,
-                textStyles = listOf(
-                    AnnotatedString.Item(
-                        textStyle,
-                        0,
-                        text.length
-                    )
-                )
-            )
-            val textPainter = TextPainter(
-                text = annotatedString,
-                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
-                density = density,
-                resourceLoader = resourceLoader
-            )
-            textPainter.layout(Constraints())
-
-            val expectedBitmap = Bitmap.createBitmap(
-                ceil(textPainter.width).toInt(),
-                ceil(textPainter.height).toInt(),
-                Bitmap.Config.ARGB_8888
-            )
-            val expectedCanvas =
-                Canvas(android.graphics.Canvas(expectedBitmap))
-            val expectedPaint = Paint()
-            val defaultSelectionColor = Color(0x6633B5E5)
-            expectedPaint.color = defaultSelectionColor
-            expectedCanvas.drawRect(
-                Rect(
-                    left = 0f,
-                    top = 0f,
-                    right = fontSizeInPx * (selectionEnd - selectionStart),
-                    bottom = fontSizeInPx
-                ),
-                expectedPaint
-            )
-
-            val actualBitmap = Bitmap.createBitmap(
-                ceil(textPainter.width).toInt(),
-                ceil(textPainter.height).toInt(),
-                Bitmap.Config.ARGB_8888
-            )
-            val actualCanvas = Canvas(android.graphics.Canvas(actualBitmap))
-
-            // Run.
-            textPainter.paintBackground(
-                start = selectionStart,
-                end = selectionEnd,
-                color = defaultSelectionColor,
-                canvas = actualCanvas
-            )
-
-            // Assert
-            Assert.assertThat(actualBitmap, equalToBitmap(expectedBitmap))
-        }
-    }
-
-    @Test
-    fun testBackgroundPaint_paint_with_default_color_bidi() {
-        withDensity(density) {
-            // Setup test.
-            val textLTR = "Hello"
-            // From right to left: שלום
-            val textRTL = "\u05e9\u05dc\u05d5\u05dd"
-            val text = textLTR + textRTL
-            val selectionLTRStart = 2
-            val selectionRTLEnd = 2
-            val fontSize = 20.sp
-            val fontSizeInPx = fontSize.toPx().value
-            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
-            val annotatedString = AnnotatedString(
-                text = text,
-                textStyles = listOf(
-                    AnnotatedString.Item(
-                        textStyle,
-                        0,
-                        text.length
-                    )
-                )
-            )
-            val textPainter = TextPainter(
-                text = annotatedString,
-                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
-                density = density,
-                resourceLoader = resourceLoader
-            )
-            textPainter.layout(Constraints())
-
-            val expectedBitmap = Bitmap.createBitmap(
-                ceil(textPainter.width).toInt(),
-                ceil(textPainter.height).toInt(),
-                Bitmap.Config.ARGB_8888
-            )
-            val expectedCanvas =
-                Canvas(android.graphics.Canvas(expectedBitmap))
-            val expectedPaint = Paint()
-            val defaultSelectionColor = Color(0x6633B5E5)
-            expectedPaint.color = defaultSelectionColor
-            // Select "llo".
-            expectedCanvas.drawRect(
-                Rect(
-                    left = fontSizeInPx * selectionLTRStart,
-                    top = 0f,
-                    right = textLTR.length * fontSizeInPx,
-                    bottom = fontSizeInPx
-                ),
-                expectedPaint
-            )
-
-            // Select "של"
-            expectedCanvas.drawRect(
-                Rect(
-                    left = (textLTR.length + textRTL.length - selectionRTLEnd) * fontSizeInPx,
-                    top = 0f,
-                    right = (textLTR.length + textRTL.length) * fontSizeInPx,
-                    bottom = fontSizeInPx
-                ),
-                expectedPaint
-            )
-
-            val actualBitmap = Bitmap.createBitmap(
-                ceil(textPainter.width).toInt(),
-                ceil(textPainter.height).toInt(),
-                Bitmap.Config.ARGB_8888
-            )
-            val actualCanvas = Canvas(android.graphics.Canvas(actualBitmap))
-
-            // Run.
-            textPainter.paintBackground(
-                start = selectionLTRStart,
-                end = textLTR.length + selectionRTLEnd,
-                color = defaultSelectionColor,
-                canvas = actualCanvas
-            )
-
-            // Assert
-            Assert.assertThat(actualBitmap, equalToBitmap(expectedBitmap))
-        }
-    }
-
-    @Test
-    fun testBackgroundPaint_paint_with_customized_color() {
-        withDensity(density) {
-            // Setup test.
-            val selectionStart = 0
-            val selectionEnd = 3
-            val fontSize = 20.sp
-            val fontSizeInPx = fontSize.toPx().value
-            val text = "Hello"
-            val textStyle = TextStyle(fontSize = fontSize, fontFamily = fontFamily)
-            val annotatedString = AnnotatedString(
-                text = text,
-                textStyles = listOf(
-                    AnnotatedString.Item(
-                        textStyle,
-                        0,
-                        text.length
-                    )
-                )
-            )
-            val selectionColor = Color(0x66AABB33)
-            val textPainter = TextPainter(
-                text = annotatedString,
-                paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
-                density = density,
-                resourceLoader = resourceLoader
-            )
-            textPainter.layout(Constraints())
-
-            val expectedBitmap = Bitmap.createBitmap(
-                ceil(textPainter.width).toInt(),
-                ceil(textPainter.height).toInt(),
-                Bitmap.Config.ARGB_8888
-            )
-            val expectedCanvas =
-                Canvas(android.graphics.Canvas(expectedBitmap))
-            val expectedPaint = Paint()
-            expectedPaint.color = selectionColor
-            expectedCanvas.drawRect(
-                Rect(
-                    left = 0f,
-                    top = 0f,
-                    right = fontSizeInPx * (selectionEnd - selectionStart),
-                    bottom = fontSizeInPx
-                ),
-                expectedPaint
-            )
-
-            val actualBitmap = Bitmap.createBitmap(
-                ceil(textPainter.width).toInt(),
-                ceil(textPainter.height).toInt(),
-                Bitmap.Config.ARGB_8888
-            )
-            val actualCanvas = Canvas(android.graphics.Canvas(actualBitmap))
-
-            // Run.
-            textPainter.paintBackground(
-                start = selectionStart,
-                end = selectionEnd,
-                color = selectionColor,
-                canvas = actualCanvas
-            )
-
-            // Assert
-            Assert.assertThat(actualBitmap, equalToBitmap(expectedBitmap))
-        }
-    }
-}
\ No newline at end of file
diff --git a/ui/ui-text/src/androidTest/java/androidx/ui/text/platform/AndroidParagraphTest.kt b/ui/ui-text/src/androidTest/java/androidx/ui/text/platform/AndroidParagraphTest.kt
index ef5b100..3be82b7 100644
--- a/ui/ui-text/src/androidTest/java/androidx/ui/text/platform/AndroidParagraphTest.kt
+++ b/ui/ui-text/src/androidTest/java/androidx/ui/text/platform/AndroidParagraphTest.kt
@@ -37,7 +37,6 @@
 import androidx.ui.text.style.TextIndent
 import androidx.ui.text.font.FontFamily
 import androidx.ui.text.font.asFontFamily
-import androidx.ui.text.Locale
 import androidx.ui.graphics.Color
 import androidx.ui.text.matchers.equalToBitmap
 import androidx.ui.text.matchers.hasSpan
@@ -63,6 +62,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
+import java.util.Locale
 import kotlin.math.ceil
 
 @RunWith(JUnit4::class)
@@ -1216,7 +1216,7 @@
 
     @Test
     fun locale_isSetOnParagraphImpl_enUS() {
-        val locale = Locale(_languageCode = "en", _countryCode = "US")
+        val locale = Locale("en", "US")
         val text = "abc"
         val paragraph = simpleParagraph(
             text = text,
@@ -1230,7 +1230,7 @@
 
     @Test
     fun locale_isSetOnParagraphImpl_jpJP() {
-        val locale = Locale(_languageCode = "ja", _countryCode = "JP")
+        val locale = Locale("ja", "JP")
         val text = "abc"
         val paragraph = simpleParagraph(
             text = text,
@@ -1244,7 +1244,7 @@
 
     @Test
     fun locale_noCountryCode_isSetOnParagraphImpl() {
-        val locale = Locale(_languageCode = "ja")
+        val locale = Locale("ja")
         val text = "abc"
         val paragraph = simpleParagraph(
             text = text,
diff --git a/ui/ui-text/src/main/java/androidx/ui/input/EditorStyle.kt b/ui/ui-text/src/main/java/androidx/ui/input/EditorStyle.kt
new file mode 100644
index 0000000..a4c2dce
--- /dev/null
+++ b/ui/ui-text/src/main/java/androidx/ui/input/EditorStyle.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019 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.ui.input
+
+import androidx.ui.graphics.Color
+import androidx.ui.text.TextStyle
+
+/**
+ * Data class holding text display attributes used for editors.
+ */
+data class EditorStyle(
+    /** The  editor text style */
+    val textStyle: TextStyle? = null,
+
+    /**
+     * The composition background color
+     *
+     * @see EditorModel.composition
+     */
+    val compositionColor: Color = Color(alpha = 0xFF, red = 0xB0, green = 0xE0, blue = 0xE6),
+
+    /**
+     *  The selection background color
+     *
+     *  @see EditorModel.selection
+     */
+    // TODO(nona): share with Text.DEFAULT_SELECTION_COLOR
+    val selectionColor: Color = Color(alpha = 0x66, red = 0x33, green = 0xB5, blue = 0xE5)
+)
diff --git a/ui/ui-text/src/main/java/androidx/ui/input/GapBuffer.kt b/ui/ui-text/src/main/java/androidx/ui/input/GapBuffer.kt
index 65f0ec4..2b6c8f3 100644
--- a/ui/ui-text/src/main/java/androidx/ui/input/GapBuffer.kt
+++ b/ui/ui-text/src/main/java/androidx/ui/input/GapBuffer.kt
@@ -86,10 +86,10 @@
         }
 
         val newBuffer = CharArray(newCapacity)
-        System.arraycopy(buffer, 0, newBuffer, 0, gapStart)
+        buffer.copyInto(newBuffer, 0, 0, gapStart)
         val tailLength = capacity - gapEnd
         val newEnd = newCapacity - tailLength
-        System.arraycopy(buffer, gapEnd, newBuffer, newEnd, tailLength)
+        buffer.copyInto(newBuffer, newEnd, gapEnd, gapEnd + tailLength)
 
         buffer = newBuffer
         capacity = newCapacity
@@ -119,7 +119,7 @@
             //
             // Output:       ABCD******************KLKMNOPQRSTUVWXYZ
             val copyLen = gapStart - end
-            System.arraycopy(buffer, end, buffer, gapEnd - copyLen, copyLen)
+            buffer.copyInto(buffer, gapEnd - copyLen, end, gapStart)
             gapStart = start
             gapEnd -= copyLen
         } else if (start < gapStart && end >= gapStart) {
@@ -154,7 +154,7 @@
             val startInBuffer = start + gapLength()
             val endInBuffer = end + gapLength()
             val copyLen = startInBuffer - gapEnd
-            System.arraycopy(buffer, gapEnd, buffer, gapStart, copyLen)
+            buffer.copyInto(buffer, gapStart, gapEnd, startInBuffer)
             gapStart += copyLen
             gapEnd = endInBuffer
         }
@@ -299,4 +299,4 @@
         sb.append(text, bufEnd, text.length)
         return sb.toString()
     }
-}
\ No newline at end of file
+}
diff --git a/ui/ui-text/src/main/java/androidx/ui/input/VisualTransformation.kt b/ui/ui-text/src/main/java/androidx/ui/input/VisualTransformation.kt
new file mode 100644
index 0000000..7e5377f
--- /dev/null
+++ b/ui/ui-text/src/main/java/androidx/ui/input/VisualTransformation.kt
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2019 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.ui.input
+
+import androidx.annotation.RestrictTo
+import androidx.ui.text.AnnotatedString
+
+/**
+ * The map interface used for bidirectional offset mapping from original to transformed text.
+ */
+interface OffsetMap {
+    /**
+     * Convert offset in original text into the offset in transformed text.
+     *
+     * This function must be a monotonically non-decreasing function. In other words, if a cursor
+     * advances in the original text, the cursor in the transformed text must advance or stay there.
+     *
+     * @param offset offset in original text.
+     * @return offset in transformed text
+     * @see VisualTransformation
+     */
+    fun originalToTransformed(offset: Int): Int
+
+    /**
+     * Convert offset in transformed text into the offset in original text.
+     *
+     * This function must be a monotonically non-decreasing function. In other words, if a cursor
+     * advances in the transformed text, the cusrsor in the original text must advance or stay
+     * there.
+     *
+     * @param offset offset in transformed text
+     * @return offset in original text
+     * @see VisualTransformation
+     */
+    fun transformedToOriginal(offset: Int): Int
+}
+
+/**
+ * The transformed text with offset offset mapping
+ */
+data class TransformedText(
+    /**
+     * The transformed text
+     */
+    val transformedText: AnnotatedString,
+
+    /**
+     * The map used for bidirectional offset mapping from original to transformed text.
+     */
+    val offsetMap: OffsetMap
+)
+
+/**
+ * Interface used for changing visual output of the input field.
+ *
+ * This interface can be used for changing visual output of the text in the input field.
+ * For example, you can mask characters in password filed with asterisk with
+ * PasswordVisualTransformation.
+ */
+interface VisualTransformation {
+    /**
+     * Change the visual output of given text.
+     *
+     * Note that the returned text length can be different length from the given text. The widget
+     * will call the offset translator for converting offsets for various reasons, cursor drawing
+     * position, text selection by gesture, etc.
+     *
+     * Example: Credit Card Visual Output (inserting hyphens each 4 digits)
+     *  original text   : 1234567890123456
+     *  transformed text: 1234-5678-9012-3456
+     *
+     *  Then, the offset translator should ignore the hyphen characters, so conversion from
+     *  original offset to transformed text works like
+     *  - The 4th char of the original text is 5th char in the transformed text.
+     *  - The 13th char of the original text is 15th char in the transformed text.
+     *  Similarly, the reverse conversion works like
+     *  - The 5th char of the transformed text is 4th char in the original text.
+     *  - The 12th char of the transformed text is 10th char in the original text.
+     *
+     *  The reference implementation would be like as follows:
+     *  <pre>
+     *  val creditCardOffsetTranslator = object : OffsetMap {
+     *      override fun originalToTransformed(originalOffset: Int): Int {
+     *          if (originalOffset <= 3) return originalOffset
+     *          if (originalOffset <= 7) return originalOffset + 1
+     *          if (originalOffset <= 11) return originalOffset + 2
+     *          if (originalOffset <= 16) return originalOffset + 3
+     *          return 19
+     *      }
+     *
+     *      override fun transformedToOriginal(transformedOffset: Int): Int {
+     *          if (transformedOffset <= 4) return transformedOffset
+     *          if (transformedOffset <= 9) return transformedOffset - 1
+     *          if (transformedOffset <= 14) return transformedOffset - 2
+     *          if (transformedOffset <= 19) return transformedOffset - 3
+     *          return 16
+     *      }
+     *  }
+     *  </pre>
+     *
+     * TODO(nona): Add paragraph direction argument for determining offset conversion.
+     *
+     * @param text The original text
+     * @return the pair of filtered text and offset translator.
+     */
+    fun filter(text: AnnotatedString): TransformedText
+}
+
+/**
+ * The Visual Filter can be used for password Input Field.
+ *
+ * Note that this visual filter only works for ASCII characters.
+ *
+ * @param mask The mask character used instead of original text.
+ */
+class PasswordVisualTransformation(val mask: Char = '\u2022') : VisualTransformation {
+    override fun filter(text: AnnotatedString): TransformedText {
+        return TransformedText(
+            AnnotatedString(Character.toString(mask).repeat(text.text.length)),
+            identityOffsetMap
+        )
+    }
+}
+
+/**
+ * The offset map used for identity mapping.
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+val identityOffsetMap = object : OffsetMap {
+    override fun originalToTransformed(offset: Int): Int = offset
+    override fun transformedToOriginal(offset: Int): Int = offset
+}
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/AnnotatedString.kt b/ui/ui-text/src/main/java/androidx/ui/text/AnnotatedString.kt
index 28140c5..5309878 100644
--- a/ui/ui-text/src/main/java/androidx/ui/text/AnnotatedString.kt
+++ b/ui/ui-text/src/main/java/androidx/ui/text/AnnotatedString.kt
@@ -16,6 +16,9 @@
 
 package androidx.ui.text
 
+import java.util.Locale
+import java.util.SortedSet
+
 /**
  * The basic data structure of text with multiple styles.
  */
@@ -38,6 +41,7 @@
             lastStyleEnd = paragraphStyle.end
         }
     }
+
     /**
      * The information attached on the text such as a TextStyle.
      *
@@ -53,4 +57,155 @@
             }
         }
     }
+
+    /**
+     * Create upper case transformed [AnnotatedString]
+     *
+     * The uppercase sometimes maps different number of characters. This function adjusts the text
+     * style and paragraph style ranges to transformed offset.
+     *
+     * Note, if the style's offset is middle of the uppercase mapping context, this function won't
+     * transform the character, e.g. style starts from between base alphabet character and accent
+     * character.
+     *
+     * @param locale A locale used for upper case mapping.
+     * @return A uppercase transformed string.
+     */
+    fun toUpperCase(locale: Locale = Locale.getDefault()): AnnotatedString {
+        return transform { str, start, end -> str.substring(start, end).toUpperCase(locale) }
+    }
+
+    /**
+     * Create lower case transformed [AnnotatedString]
+     *
+     * The lowercase sometimes maps different number of characters. This function adjusts the text
+     * style and paragraph style ranges to transformed offset.
+     *
+     * Note, if the style's offset is middle of the lowercase mapping context, this function won't
+     * transform the character, e.g. style starts from between base alphabet character and accent
+     * character.
+     *
+     * @param locale A locale used for lower case mapping.
+     * @return A lowercase transformed string.
+     */
+    fun toLowerCase(locale: Locale = Locale.getDefault()): AnnotatedString {
+        return transform { str, start, end -> str.substring(start, end).toLowerCase(locale) }
+    }
+
+    /**
+     * Create capitalized [AnnotatedString]
+     *
+     * The capitalization sometimes maps different number of characters. This function adjusts the
+     * text style and paragraph style ranges to transformed offset.
+     *
+     * Note, if the style's offset is middle of the capitalization context, this function won't
+     * transform the character, e.g. style starts from between base alphabet character and accent
+     * character.
+     *
+     * @param locale A locale used for capitalization. Note that, this locale is currently ignored
+     *               since underlying Kotlin method is experimental.
+     * @return A capitalized string.
+     */
+    fun capitalize(
+        @Suppress("UNUSED_PARAMETER") locale: Locale = Locale.getDefault()
+    ): AnnotatedString {
+        return transform { str, start, end ->
+            if (start == 0) {
+                // TODO: pass locale if capitalize with locale function is published.
+                str.substring(start, end).capitalize()
+            } else {
+                str.substring(start, end)
+            }
+        }
+    }
+
+    /**
+     * Create capitalized [AnnotatedString]
+     *
+     * The decapitalization sometimes maps different number of characters. This function adjusts
+     * the text style and paragraph style ranges to transformed offset.
+     *
+     * Note, if the style's offset is middle of the decapitalization context, this function won't
+     * transform the character, e.g. style starts from between base alphabet character and accent
+     * character.
+     *
+     * @param locale A locale used for decapitalization. Note that, this locale is currently
+     *               ignored since underlying Kotlin method is experimental.
+     * @return A decapitalized string.
+     */
+    fun decapitalize(
+        @Suppress("UNUSED_PARAMETER") locale: Locale = Locale.getDefault()
+    ): AnnotatedString {
+        return transform { str, start, end ->
+            if (start == 0) {
+                // TODO: pass locale if decapitalize with locale function is published.
+                str.substring(start, end).decapitalize()
+            } else {
+                str.substring(start, end)
+            }
+        }
+    }
+
+    /**
+     * The core function of [AnnotatedString] transformation.
+     *
+     * @param transform the transformation method
+     * @return newly allocated transformed AnnotatedString
+     */
+    private fun transform(transform: (String, Int, Int) -> String): AnnotatedString {
+        val transitions = sortedSetOf<Int>()
+        collectItemTransitions(textStyles, transitions)
+        collectItemTransitions(paragraphStyles, transitions)
+
+        var resultStr = ""
+        val offsetMap = mutableMapOf(0 to 0)
+        transitions.windowed(size = 2) { (start, end) ->
+            resultStr += transform(text, start, end)
+            offsetMap.put(end, resultStr.length)
+        }
+
+        val newTextStyles = mutableListOf<Item<TextStyle>>()
+        val newParaStyles = mutableListOf<Item<ParagraphStyle>>()
+
+        for (textStyle in textStyles) {
+            // The offset map must have mapping entry from all style start, end position.
+            newTextStyles.add(
+                Item(
+                    textStyle.style,
+                    offsetMap[textStyle.start]!!,
+                    offsetMap[textStyle.end]!!
+                )
+            )
+        }
+
+        for (paraStyle in paragraphStyles) {
+            newParaStyles.add(
+                Item(
+                    paraStyle.style,
+                    offsetMap[paraStyle.start]!!,
+                    offsetMap[paraStyle.end]!!
+                )
+            )
+        }
+
+        return AnnotatedString(
+            text = resultStr,
+            textStyles = newTextStyles,
+            paragraphStyles = newParaStyles)
+    }
+
+    /**
+     * Adds all [AnnotatedString.Item] transition points
+     *
+     * @param items The list of AnnotatedString.Item
+     * @param target The output list
+     */
+    private fun <T> collectItemTransitions(items: List<Item<T>>, target: SortedSet<Int>) {
+        items.fold(target) { acc, item ->
+            acc.apply {
+                add(item.start)
+                add(item.end)
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/Locale.kt b/ui/ui-text/src/main/java/androidx/ui/text/Locale.kt
deleted file mode 100644
index 826956c..0000000
--- a/ui/ui-text/src/main/java/androidx/ui/text/Locale.kt
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright 2019 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.ui.text
-
-/**
- * An identifier used to select a user's language and formatting preferences,
- * consisting of a language and a country. This is a subset of locale
- * identifiers as defined by BCP 47.
- *
- * Locales are canonicalized according to the "preferred value" entries in the
- * [IANA Language Subtag
- * Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry).
- * For example, `const Locale('he')` and `const Locale('iw')` are equal and
- * both have the [languageCode] `he`, because `iw` is a deprecated language
- * subtag that was replaced by the subtag `he`.
- *
- * See also:
- *
- *  * [Window.locale], which specifies the system's currently selected
- *    [Locale].
- *
- * The default constructor creates a new Locale object. The first argument is the
- * primary language subtag, the second is the region subtag.
- *
- * For example:
- *
- * ```dart
- * const Locale swissFrench = const Locale('fr', 'CH');
- * const Locale canadianFrench = const Locale('fr', 'CA');
- * ```
- *
- * The primary language subtag must not be null. The region subtag is
- * optional.
- *
- * The values are _case sensitive_, and should match the case of the relevant
- * subtags in the [IANA Language Subtag
- * Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry).
- * Typically this means the primary language subtag should be lowercase and
- * the region subtag should be uppercase.
- */
-data class Locale(
-    val _languageCode: String,
-    val _countryCode: String? = null
-) {
-
-    // TODO(Migration/siyamed): this class is far far far too much very limited.
-    // we might want to wrap system locale, or use system locale.
-    // The package is also not good, Locale should be somewhere else not under window.
-    // nona@ we need at least
-    // * ISO 15924 script tag. This is required for sr-Latn/sr-Cyrl support.
-    // * Variant. This is required for hyphenation for German, de-1996/de-1901
-    // * Unicode extensions: This is required Arabic/Latin digits selection.
-    // Also, this needs to be a list of locale, otherwise
-    // * locale list based font fallback doesn't work.
-    // * resource fallback may not work well.
-
-    /**
-     * The primary language subtag for the locale.
-     *
-     * This must not be null.
-     *
-     * This is expected to be string registered in the [IANA Language Subtag
-     * Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry)
-     * with the type "language". The string specified must match the case of the
-     * string in the registry.
-     *
-     * Language subtags that are deprecated in the registry and have a preferred
-     * code are changed to their preferred code. For example, `const
-     * Locale('he')` and `const Locale('iw')` are equal, and both have the
-     * [languageCode] `he`, because `iw` is a deprecated language subtag that was
-     * replaced by the subtag `he`.
-     */
-    val languageCode: String
-        get() = _canonicalizeLanguageCode(_languageCode)
-
-    /**
-     * The region subtag for the locale.
-     *
-     * This can be null.
-     *
-     * This is expected to be string registered in the [IANA Language Subtag
-     * Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry)
-     * with the type "region". The string specified must match the case of the
-     * string in the registry.
-     *
-     * Region subtags that are deprecated in the registry and have a preferred
-     * code are changed to their preferred code. For example, `const Locale('de',
-     * 'DE')` and `const Locale('de', 'DD')` are equal, and both have the
-     * [countryCode] `DE`, because `DD` is a deprecated language subtag that was
-     * replaced by the subtag `DE`.
-     */
-    val countryCode
-        get() = if (_countryCode != null) _canonicalizeRegionCode(
-            _countryCode
-        ) else null
-
-    companion object {
-        fun _canonicalizeLanguageCode(languageCode: String): String {
-            // This switch statement is generated by //flutter/tools/gen_locale.dart
-            // TODO(popam): look into that tool
-            // Mappings generated for language subtag registry as of 2017-08-15.
-            return when (languageCode) {
-                "in" -> "id"; // Indonesian; deprecated 1989-01-01
-                "iw" -> "he"; // Hebrew; deprecated 1989-01-01
-                "ji" -> "yi"; // Yiddish; deprecated 1989-01-01
-                "jw" -> "jv"; // Javanese; deprecated 2001-08-13
-                "mo" -> "ro"; // Moldavian, Moldovan; deprecated 2008-11-22
-                "aam" -> "aas"; // Aramanik; deprecated 2015-02-12
-                "adp" -> "dz"; // Adap; deprecated 2015-02-12
-                "aue" -> "ktz"; // =/Kx"au//"ein; deprecated 2015-02-12
-                "ayx" -> "nun"; // Ayi (China); deprecated 2011-08-16
-                "bgm" -> "bcg"; // Baga Mboteni; deprecated 2016-05-30
-                "bjd" -> "drl"; // Bandjigali; deprecated 2012-08-12
-                "ccq" -> "rki"; // Chaungtha; deprecated 2012-08-12
-                "cjr" -> "mom"; // Chorotega; deprecated 2010-03-11
-                "cka" -> "cmr"; // Khumi Awa Chin; deprecated 2012-08-12
-                "cmk" -> "xch"; // Chimakum; deprecated 2010-03-11
-                "coy" -> "pij"; // Coyaima; deprecated 2016-05-30
-                "cqu" -> "quh"; // Chilean Quechua; deprecated 2016-05-30
-                "drh" -> "khk"; // Darkhat; deprecated 2010-03-11
-                "drw" -> "prs"; // Darwazi; deprecated 2010-03-11
-                "gav" -> "dev"; // Gabutamon; deprecated 2010-03-11
-                "gfx" -> "vaj"; // Mangetti Dune !Xung; deprecated 2015-02-12
-                "ggn" -> "gvr"; // Eastern Gurung; deprecated 2016-05-30
-                "gti" -> "nyc"; // Gbati-ri; deprecated 2015-02-12
-                "guv" -> "duz"; // Gey; deprecated 2016-05-30
-                "hrr" -> "jal"; // Horuru; deprecated 2012-08-12
-                "ibi" -> "opa"; // Ibilo; deprecated 2012-08-12
-                "ilw" -> "gal"; // Talur; deprecated 2013-09-10
-                "jeg" -> "oyb"; // Jeng; deprecated 2017-02-23
-                "kgc" -> "tdf"; // Kasseng; deprecated 2016-05-30
-                "kgh" -> "kml"; // Upper Tanudan Kalinga; deprecated 2012-08-12
-                "koj" -> "kwv"; // Sara Dunjo; deprecated 2015-02-12
-                "krm" -> "bmf"; // Krim; deprecated 2017-02-23
-                "ktr" -> "dtp"; // Kota Marudu Tinagas; deprecated 2016-05-30
-                "kvs" -> "gdj"; // Kunggara; deprecated 2016-05-30
-                "kwq" -> "yam"; // Kwak; deprecated 2015-02-12
-                "kxe" -> "tvd"; // Kakihum; deprecated 2015-02-12
-                "kzj" -> "dtp"; // Coastal Kadazan; deprecated 2016-05-30
-                "kzt" -> "dtp"; // Tambunan Dusun; deprecated 2016-05-30
-                "lii" -> "raq"; // Lingkhim; deprecated 2015-02-12
-                "lmm" -> "rmx"; // Lamam; deprecated 2014-02-28
-                "meg" -> "cir"; // Mea; deprecated 2013-09-10
-                "mst" -> "mry"; // Cataelano Mandaya; deprecated 2010-03-11
-                "mwj" -> "vaj"; // Maligo; deprecated 2015-02-12
-                "myt" -> "mry"; // Sangab Mandaya; deprecated 2010-03-11
-                "nad" -> "xny"; // Nijadali; deprecated 2016-05-30
-                "nnx" -> "ngv"; // Ngong; deprecated 2015-02-12
-                "nts" -> "pij"; // Natagaimas; deprecated 2016-05-30
-                "oun" -> "vaj"; // !O!ung; deprecated 2015-02-12
-                "pcr" -> "adx"; // Panang; deprecated 2013-09-10
-                "pmc" -> "huw"; // Palumata; deprecated 2016-05-30
-                "pmu" -> "phr"; // Mirpur Panjabi; deprecated 2015-02-12
-                "ppa" -> "bfy"; // Pao; deprecated 2016-05-30
-                "ppr" -> "lcq"; // Piru; deprecated 2013-09-10
-                "pry" -> "prt"; // Pray 3; deprecated 2016-05-30
-                "puz" -> "pub"; // Purum Naga; deprecated 2014-02-28
-                "sca" -> "hle"; // Sansu; deprecated 2012-08-12
-                "skk" -> "oyb"; // Sok; deprecated 2017-02-23
-                "tdu" -> "dtp"; // Tempasuk Dusun; deprecated 2016-05-30
-                "thc" -> "tpo"; // Tai Hang Tong; deprecated 2016-05-30
-                "thx" -> "oyb"; // The; deprecated 2015-02-12
-                "tie" -> "ras"; // Tingal; deprecated 2011-08-16
-                "tkk" -> "twm"; // Takpa; deprecated 2011-08-16
-                "tlw" -> "weo"; // South Wemale; deprecated 2012-08-12
-                "tmp" -> "tyj"; // Tai Mène; deprecated 2016-05-30
-                "tne" -> "kak"; // Tinoc Kallahan; deprecated 2016-05-30
-                "tnf" -> "prs"; // Tangshewi; deprecated 2010-03-11
-                "tsf" -> "taj"; // Southwestern Tamang; deprecated 2015-02-12
-                "uok" -> "ema"; // Uokha; deprecated 2015-02-12
-                "xba" -> "cax"; // Kamba (Brazil); deprecated 2016-05-30
-                "xia" -> "acn"; // Xiandao; deprecated 2013-09-10
-                "xkh" -> "waw"; // Karahawyana; deprecated 2016-05-30
-                "xsj" -> "suj"; // Subi; deprecated 2015-02-12
-                "ybd" -> "rki"; // Yangbye; deprecated 2012-08-12
-                "yma" -> "lrr"; // Yamphe; deprecated 2012-08-12
-                "ymt" -> "mtm"; // Mator-Taygi-Karagas; deprecated 2015-02-12
-                "yos" -> "zom"; // Yos; deprecated 2013-09-10
-                "yuu" -> "yug"; // Yugh; deprecated 2014-02-28
-                else -> languageCode
-            }
-        }
-
-        fun _canonicalizeRegionCode(regionCode: String): String {
-            // This switch statement is generated by //flutter/tools/gen_locale.dart
-            // TODO(popam): look into that tool
-            // Mappings generated for language subtag registry as of 2017-08-15.
-            return when (regionCode) {
-                "BU" -> "MM"; // Burma; deprecated 1989-12-05
-                "DD" -> "DE"; // German Democratic Republic; deprecated 1990-10-30
-                "FX" -> "FR"; // Metropolitan France; deprecated 1997-07-14
-                "TP" -> "TL"; // East Timor; deprecated 2002-05-20
-                "YD" -> "YE"; // Democratic Yemen; deprecated 1990-08-14
-                "ZR" -> "CD"; // Zaire; deprecated 1997-07-14
-                else -> regionCode
-            }
-        }
-    }
-
-    // Made this a data class, so the following are probably no longer required.
-    // Leaving them commented out though.
-//    override fun equals(other: Any?): Boolean {
-//        if (this === other) {
-//            return true
-//        }
-//        if (other !is Locale) {
-//            return false
-//        }
-//        return languageCode == other.languageCode && countryCode == other.countryCode
-//    }
-//
-//    override fun hashCode(): Int {
-//        var result = 373
-//        result = 37 * result + languageCode.hashCode()
-//        if (_countryCode != null) {
-//            result = 37 * result + countryCode!!.hashCode()
-//        }
-//        return result
-//    }
-//
-//    override fun toString(): String {
-//        if (_countryCode == null) {
-//            return languageCode
-//        }
-//        return "${languageCode}_$countryCode"
-//    }
-}
\ No newline at end of file
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/MultiParagraph.kt b/ui/ui-text/src/main/java/androidx/ui/text/MultiParagraph.kt
index 830a776..e7923f0 100644
--- a/ui/ui-text/src/main/java/androidx/ui/text/MultiParagraph.kt
+++ b/ui/ui-text/src/main/java/androidx/ui/text/MultiParagraph.kt
@@ -245,8 +245,7 @@
 
         val paragraphIndex = findParagraphByIndex(paragraphInfoList, offset)
         return with(paragraphInfoList[paragraphIndex]) {
-            val localOffset = offset.toLocalIndex()
-            paragraph.getBoundingBox(localOffset).toGlobal()
+            paragraph.getBoundingBox(offset.toLocalIndex()).toGlobal()
         }
     }
 
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/ParagraphConstraints.kt b/ui/ui-text/src/main/java/androidx/ui/text/ParagraphConstraints.kt
index fde3f64..be60281 100644
--- a/ui/ui-text/src/main/java/androidx/ui/text/ParagraphConstraints.kt
+++ b/ui/ui-text/src/main/java/androidx/ui/text/ParagraphConstraints.kt
@@ -38,12 +38,10 @@
  * forced line break is placed after it (even if an explicit line break
  * follows).
  *
- * The width influences how ellipses are applied. See the discussion at [new
- * ParagraphStyle] for more details.
+ * The width influences how ellipses are applied.
  *
- * This width is also used to position glyphs according to the [TextAlign]
- * alignment described in the [ParagraphStyle] used when building the
- * [Paragraph] with a [ParagraphBuilder].
+ * This width is also used to position glyphs according to the text alignment
+ * described in the [ParagraphStyle.textAlign] to create [Paragraph].
  */
 data class ParagraphConstraints(val width: Float) {
     override fun toString(): String {
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/RenderComparison.kt b/ui/ui-text/src/main/java/androidx/ui/text/RenderComparison.kt
index 939a7b7..69a24fa 100644
--- a/ui/ui-text/src/main/java/androidx/ui/text/RenderComparison.kt
+++ b/ui/ui-text/src/main/java/androidx/ui/text/RenderComparison.kt
@@ -21,10 +21,6 @@
  *  it will affect the rendering.
  *
  *  Used by [TextSpan.compareTo] and [TextStyle.compareTo].
- *
- *  The values in this enum are ordered such that they are in increasing order
- *  of cost. A value with index N implies all the values with index less than N.
- *  For example, [layout] (index 3) implies [paint] (2).
  */
 // TODO(siyamed) remove this class if not required
 internal enum class RenderComparison {
@@ -45,9 +41,6 @@
      * The two objects are different but only in ways that affect paint, not layout.
      *
      * For example, only the color is changed.
-     *
-     * [RenderObject.markNeedsPaint] would be necessary to handle this kind of
-     * change in a render object.
      */
     PAINT,
 
@@ -57,9 +50,6 @@
      *  For example, the size is changed.
      *
      *  This is the most drastic level of change possible.
-     *
-     *  [RenderObject.markNeedsLayout] would be necessary to handle this kind of
-     *  change in a render object.
      */
     LAYOUT
 }
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/TextBox.kt b/ui/ui-text/src/main/java/androidx/ui/text/TextBox.kt
index 334458d..83a427b 100644
--- a/ui/ui-text/src/main/java/androidx/ui/text/TextBox.kt
+++ b/ui/ui-text/src/main/java/androidx/ui/text/TextBox.kt
@@ -49,7 +49,8 @@
     }
 
     /**
-     * The [left] edge of the box for left-to-right text; the [right] edge of the box for right-to-left text.
+     * The [left] edge of the box for left-to-right text; the [right] edge of the box for
+     * right-to-left text.
      * See also:
      *  * [direction], which specifies the text direction.
      */
@@ -58,7 +59,8 @@
     }
 
     /**
-     * The [right] edge of the box for left-to-right text; the [left] edge of the box for right-to-left text.
+     * The [right] edge of the box for left-to-right text; the [left] edge of the box for
+     * right-to-left text.
      * See also:
      *  * [direction], which specifies the text direction.
      */
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/TextDelegate.kt b/ui/ui-text/src/main/java/androidx/ui/text/TextDelegate.kt
new file mode 100644
index 0000000..20828cc
--- /dev/null
+++ b/ui/ui-text/src/main/java/androidx/ui/text/TextDelegate.kt
@@ -0,0 +1,491 @@
+/*
+ * Copyright 2019 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.ui.text
+
+import androidx.annotation.RestrictTo
+import androidx.annotation.RestrictTo.Scope.LIBRARY
+import androidx.annotation.VisibleForTesting
+import androidx.ui.core.Constraints
+import androidx.ui.core.Density
+import androidx.ui.core.IntPxSize
+import androidx.ui.core.PxPosition
+import androidx.ui.core.Sp
+import androidx.ui.core.constrain
+import androidx.ui.core.px
+import androidx.ui.core.round
+import androidx.ui.core.sp
+import androidx.ui.engine.geometry.Offset
+import androidx.ui.engine.geometry.Rect
+import androidx.ui.engine.geometry.Size
+import androidx.ui.text.style.TextAlign
+import androidx.ui.text.style.TextDirection
+import androidx.ui.graphics.Color
+import androidx.ui.painting.BlendMode
+import androidx.ui.painting.Canvas
+import androidx.ui.painting.Gradient
+import androidx.ui.painting.Paint
+import androidx.ui.painting.Shader
+import androidx.ui.text.font.Font
+import androidx.ui.text.style.TextOverflow
+import java.util.Locale
+import kotlin.math.ceil
+
+private val DefaultTextAlign: TextAlign = TextAlign.Start
+private val DefaultTextDirection: TextDirection = TextDirection.Ltr
+/** The default font size if none is specified. */
+private val DefaultFontSize: Sp = 14.sp
+
+/**
+ * Unfortunately, using full precision floating point here causes bad layouts because floating
+ * point math isn't associative. If we add and subtract padding, for example, we'll get
+ * different values when we estimate sizes and when we actually compute layout because the
+ * operations will end up associated differently. To work around this problem for now, we round
+ * fractional pixel values up to the nearest whole pixel value. The right long-term fix is to do
+ * layout using fixed precision arithmetic.
+ */
+internal fun applyFloatingPointHack(layoutValue: Float): Float {
+    return ceil(layoutValue)
+}
+
+/**
+ * An object that paints a [TextSpan] tree into a [Canvas].
+ *
+ * To use a [TextDelegate], follow these steps:
+ *
+ * 1. Create a [TextSpan] tree and pass it to the [TextDelegate] constructor.
+ *
+ * 2. Call [layout] to prepare the paragraph.
+ *
+ * 3. Call [paint] as often as desired to paint the paragraph.
+ *
+ * If the width of the area into which the text is being painted changes, return to step 2. If the
+ *  text to be painted changes, return to step 1.
+ *
+ * @param text The (potentially styled) text to paint. After this is set, you must call [layout]
+ *   before the next call to [paint]. This and [textDirection] must be non-null before you call
+ *   [layout].
+ *
+ * @param style The text style specified to render the text. Notice that you can also set text style
+ *  on the given [AnnotatedString], and the style set on [text] always has higher priority than this
+ *  setting. But if only one gobal text style is needed, passing it to [TextDelegate] is always
+ *  preferred.
+ *
+ * @param paragraphStyle Style configuration that applies only to paragraphs such as text alignment,
+ * or text direction.
+ *
+ * @param maxLines An optional maximum number of lines for the text to span, wrapping if necessary.
+ *   If the text exceeds the given number of lines, it is truncated such that subsequent lines are
+ *   dropped.
+ *   After this is set, you must call [layout] before the next call to [paint].
+ *
+ * @param softWrap Whether the text should break at soft line breaks.
+ *   If false, the glyphs in the text will be positioned as if there was unlimited horizontal space.
+ *   If [softWrap] is false, [overflow] and [textAlign] may have unexpected effects.
+ *
+ * @param overflow How visual overflow should be handled.
+ *   Specifically, the ellipsis is applied to the last line before the line truncated by [maxLines],
+ *   if [maxLines] is non-null and that line overflows the width constraint.
+ *   After this is set, you must call [layout] before the next call to [paint].
+ *
+ * @param locale The locale used to select region-specific glyphs.
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+class TextDelegate(
+    val text: AnnotatedString? = null,
+    val style: TextStyle? = null,
+    val paragraphStyle: ParagraphStyle? = null,
+    val maxLines: Int? = null,
+    val softWrap: Boolean = true,
+    val overflow: TextOverflow = TextOverflow.Clip,
+    val locale: Locale? = null,
+    val density: Density,
+    val resourceLoader: Font.ResourceLoader
+) {
+    init {
+        assert(maxLines == null || maxLines > 0)
+    }
+
+    @VisibleForTesting
+    internal var multiParagraph: MultiParagraph? = null
+        private set
+
+    private var needsLayout = true
+        private set
+
+    private var overflowShader: Shader? = null
+
+    var hasVisualOverflow = false
+        private set
+
+    private var lastMinWidth: Float = 0.0f
+    private var lastMaxWidth: Float = 0.0f
+
+    private val textStyle: TextStyle
+        get() = style ?: TextStyle()
+
+    @VisibleForTesting
+    internal val textAlign: TextAlign =
+        if (paragraphStyle?.textAlign != null) paragraphStyle.textAlign else DefaultTextAlign
+
+    @VisibleForTesting
+    internal val textDirection: TextDirection? =
+        paragraphStyle?.textDirection ?: DefaultTextDirection
+
+    private val isEllipsis = (overflow == TextOverflow.Ellipsis)
+
+    private fun createTextStyle(): TextStyle {
+        return textStyle.copy(
+            fontSize = (textStyle.fontSize ?: DefaultFontSize)
+        )
+    }
+
+    @VisibleForTesting
+    internal fun createParagraphStyle(): ParagraphStyle {
+        return ParagraphStyle(
+            textAlign = textAlign,
+            textDirection = textDirection,
+            textIndent = paragraphStyle?.textIndent,
+            lineHeight = paragraphStyle?.lineHeight
+        )
+    }
+
+    private fun assertNeedsLayout(name: String) {
+        assert(!needsLayout) {
+            "TextDelegate.$name should only be called after layout has been called."
+        }
+    }
+
+    /**
+     * The width at which decreasing the width of the text would prevent it from painting itself
+     * completely within its bounds.
+     *
+     * Valid only after [layout] has been called.
+     */
+    val minIntrinsicWidth: Float
+        get() {
+            assertNeedsLayout("minIntrinsicWidth")
+            return applyFloatingPointHack(multiParagraph!!.minIntrinsicWidth)
+        }
+
+    /**
+     * The width at which increasing the width of the text no longer decreases the height.
+     *
+     * Valid only after [layout] has been called.
+     */
+    val maxIntrinsicWidth: Float
+        get() {
+            assertNeedsLayout("maxIntrinsicWidth")
+            return applyFloatingPointHack(multiParagraph!!.maxIntrinsicWidth)
+        }
+
+    /**
+     * The horizontal space required to paint this text.
+     *
+     * Valid only after [layout] has been called.
+     */
+    val width: Float
+        get() {
+            assertNeedsLayout("width")
+            return applyFloatingPointHack(size.width)
+        }
+
+    /**
+     * The vertical space required to paint this text.
+     *
+     * Valid only after [layout] has been called.
+     */
+    val height: Float
+        get() {
+            assertNeedsLayout("height")
+            return applyFloatingPointHack(size.height)
+        }
+
+    /**
+     * The amount of space required to paint this text.
+     *
+     * Valid only after [layout] has been called.
+     */
+    var size: Size = Size(0f, 0f)
+        get() {
+            assertNeedsLayout("size")
+            return field
+        }
+        private set
+
+    /**
+     * Whether any text was truncated or ellipsized.
+     *
+     * If [maxLines] is not null, this is true if there were more lines to be drawn than the given
+     * [maxLines], and thus at least one line was omitted in the output; otherwise it is false.
+     *
+     * If [maxLines] is null, this is true if [overflow] is [TextOverflow.Ellipsis] and there was a
+     * line that overflowed the `maxWidth` argument passed to [layout]; otherwise it is false.
+     *
+     * Valid only after [layout] has been called.
+     */
+    val didExceedMaxLines: Boolean
+        get() {
+            assertNeedsLayout("didExceedMaxLines")
+            return multiParagraph!!.didExceedMaxLines
+        }
+
+    /**
+     * Computes the visual position of the glyphs for painting the text.
+     *
+     * The text will layout with a width that's as close to its max intrinsic width as possible
+     * while still being greater than or equal to `minWidth` and less than or equal to `maxWidth`.
+     *
+     * The [text] and [textDirection] properties must be non-null before this is called.
+     */
+    private fun layoutText(minWidth: Float = 0.0f, maxWidth: Float = Float.POSITIVE_INFINITY) {
+        assert(text != null) {
+            "TextDelegate.text must be set to a non-null value before using the TextDelegate."
+        }
+        assert(textDirection != null) {
+            "TextDelegate.textDirection must be set to a non-null value before using the" +
+                    " TextDelegate."
+        }
+
+        // TODO(haoyuchang): fix that when softWarp is false and overflow is Ellipsis, ellipsis
+        //  doesn't work.
+        val widthMatters = softWrap || overflow == TextOverflow.Ellipsis
+        val finalMaxWidth = if (widthMatters) maxWidth else Float.POSITIVE_INFINITY
+
+        if (!needsLayout && minWidth == lastMinWidth && finalMaxWidth == lastMaxWidth) return
+        needsLayout = false
+
+        if (multiParagraph == null) {
+            multiParagraph = MultiParagraph(
+                text!!,
+                createTextStyle(),
+                paragraphStyle ?: ParagraphStyle(),
+                maxLines,
+                isEllipsis,
+                density,
+                resourceLoader
+            )
+        }
+        lastMinWidth = minWidth
+        lastMaxWidth = finalMaxWidth
+        multiParagraph!!.layout(ParagraphConstraints(width = finalMaxWidth))
+        if (minWidth != finalMaxWidth) {
+            val newWidth = maxIntrinsicWidth.coerceIn(minWidth, finalMaxWidth)
+            if (newWidth != multiParagraph!!.width) {
+                multiParagraph!!.layout(ParagraphConstraints(width = newWidth))
+            }
+        }
+    }
+
+    fun layout(constraints: Constraints) {
+        layoutText(constraints.minWidth.value.toFloat(), constraints.maxWidth.value.toFloat())
+
+        val didOverflowHeight = didExceedMaxLines
+        size = constraints.constrain(
+            IntPxSize(multiParagraph!!.width.px.round(), multiParagraph!!.height.px.round())
+        ).let {
+            Size(it.width.value.toFloat(), it.height.value.toFloat())
+        }
+        val didOverflowWidth = size.width < multiParagraph!!.width
+        // TODO(abarth): We're only measuring the sizes of the line boxes here. If
+        // the glyphs draw outside the line boxes, we might think that there isn't
+        // visual overflow when there actually is visual overflow. This can become
+        // a problem if we start having horizontal overflow and introduce a clip
+        // that affects the actual (but undetected) vertical overflow.
+        hasVisualOverflow = didOverflowWidth || didOverflowHeight
+        overflowShader = if (hasVisualOverflow && overflow == TextOverflow.Fade) {
+            val fadeSizePainter = TextDelegate(
+                text = AnnotatedString(text = "\u2026", textStyles = listOf()),
+                style = textStyle,
+                paragraphStyle = paragraphStyle,
+                density = density,
+                resourceLoader = resourceLoader
+            )
+            fadeSizePainter.layoutText()
+            val fadeWidth = fadeSizePainter.multiParagraph!!.width
+            val fadeHeight = fadeSizePainter.multiParagraph!!.height
+            if (didOverflowWidth) {
+                val (fadeStart, fadeEnd) = if (textDirection == TextDirection.Rtl) {
+                    Pair(fadeWidth, 0.0f)
+                } else {
+                    Pair(size.width - fadeWidth, size.width)
+                }
+                Gradient.linear(
+                    Offset(fadeStart, 0.0f),
+                    Offset(fadeEnd, 0.0f),
+                    listOf(Color(0xFFFFFFFF.toInt()), Color(0x00FFFFFF))
+                )
+            } else {
+                val fadeEnd = size.height
+                val fadeStart = fadeEnd - fadeHeight
+                Gradient.linear(
+                    Offset(0.0f, fadeStart),
+                    Offset(0.0f, fadeEnd),
+                    listOf(Color(0xFFFFFFFF.toInt()), Color(0x00FFFFFF))
+                )
+            }
+        } else {
+            null
+        }
+    }
+
+    /**
+     * Paints the text onto the given canvas.
+     *
+     * Valid only after [layout] has been called.
+     *
+     * If you cannot see the text being painted, check that your text color does not conflict with
+     * the background on which you are drawing. The default text color is white (to contrast with
+     * the default black background color), so if you are writing an application with a white
+     * background, the text will not be visible by default.
+     *
+     * To set the text style, specify a [TextStyle] when creating the [TextSpan] that you pass to
+     * the [TextDelegate] constructor or to the [text] property.
+     */
+    fun paint(canvas: Canvas) {
+        assert(!needsLayout) {
+            "TextDelegate.paint called when text geometry was not yet calculated.\n" +
+                    "Please call layout() before paint() to position the text before painting it."
+        }
+        // Ideally we could compute the min/max intrinsic width/height with a
+        // non-destructive operation. However, currently, computing these values
+        // will destroy state inside the painter. If that happens, we need to
+        // get back the correct state by calling layout again.
+        //
+        // TODO(abarth): Make computing the min/max intrinsic width/height
+        // a non-destructive operation.
+        //
+        // If you remove this call, make sure that changing the textAlign still
+        // works properly.
+        // TODO(Migration/qqd): Need to figure out where this constraints come from and how to make
+        // it non-null. For now Crane Text version does not need to layout text again. Comment it.
+        // layoutTextWithConstraints(constraints!!)
+
+        if (hasVisualOverflow) {
+            val bounds = Rect.fromLTWH(0f, 0f, size.width, size.height)
+            if (overflowShader != null) {
+                // This layer limits what the shader below blends with to be just the text
+                // (as opposed to the text and its background).
+                canvas.saveLayer(bounds, Paint())
+            } else {
+                canvas.save()
+            }
+            canvas.clipRect(bounds)
+        }
+
+        multiParagraph!!.paint(canvas)
+        if (hasVisualOverflow) {
+            if (overflowShader != null) {
+                val bounds = Rect.fromLTWH(0f, 0f, size.width, size.height)
+                val paint = Paint()
+                paint.blendMode = BlendMode.multiply
+                paint.shader = overflowShader
+                canvas.drawRect(bounds, paint)
+            }
+            canvas.restore()
+        }
+    }
+
+    /**
+     * Draws text background of the given range.
+     *
+     * If the given range is empty, do nothing.
+     *
+     * @param start inclusive start character offset of the drawing range.
+     * @param end exclusive end character offset of the drawing range.
+     * @param color a color to be used for drawing background.
+     * @param canvas the target canvas.
+     */
+    fun paintBackground(start: Int, end: Int, color: Color, canvas: Canvas) {
+        assert(!needsLayout)
+        if (start == end) return
+        val selectionPath = multiParagraph!!.getPathForRange(start, end)
+        // TODO(haoyuchang): check if move this paint to parameter is better
+        canvas.drawPath(selectionPath, Paint().apply { this.color = color })
+    }
+
+    /**
+     * Draws the cursor at the given character offset.
+     *
+     * TODO(nona): Make cursor customizable.
+     *
+     * @param offset the cursor offset in the text.
+     * @param canvas the target canvas.
+     */
+    fun paintCursor(offset: Int, canvas: Canvas) {
+        assert(!needsLayout)
+        val cursorRect = multiParagraph!!.getCursorRect(offset)
+        canvas.drawRect(cursorRect, Paint().apply { this.color = Color.Black })
+    }
+
+    /**
+     * Returns the bottom y coordinate of the given line.
+     */
+    fun getLineBottom(lineIndex: Int): Float {
+        assert(!needsLayout)
+        return multiParagraph!!.getLineBottom(lineIndex)
+    }
+
+    /**
+     * Returns the line number on which the specified text offset appears.
+     * If you ask for a position before 0, you get 0; if you ask for a position
+     * beyond the end of the text, you get the last line.
+     */
+    fun getLineForOffset(offset: Int): Int {
+        assert(!needsLayout)
+        return multiParagraph!!.getLineForOffset(offset)
+    }
+
+    /**
+     * Get the primary horizontal position for the specified text offset.
+     */
+    fun getPrimaryHorizontal(offset: Int): Float {
+        assert(!needsLayout)
+        return multiParagraph!!.getPrimaryHorizontal(offset)
+    }
+
+    /** Returns the character offset closest to the given graphical position. */
+    fun getOffsetForPosition(position: PxPosition): Int {
+        assert(!needsLayout)
+        return multiParagraph!!.getOffsetForPosition(position)
+    }
+
+    /**
+     * Returns the bounding box as Rect of the character for given character offset. Rect includes
+     * the top, bottom, left and right of a character.
+     *
+     * Valid only after [layout] has been called.
+     */
+    fun getBoundingBox(offset: Int): Rect {
+        assert(!needsLayout)
+        return multiParagraph!!.getBoundingBox(offset)
+    }
+
+    /**
+     * Returns the text range of the word at the given character offset. Characters not part of a
+     * word, such as spaces, symbols, and punctuation, have word breaks on both sides. In such
+     * cases, this method will return a text range that contains the given character offset.
+     *
+     * Word boundaries are defined more precisely in Unicode Standard Annex #29
+     * <http://www.unicode.org/reports/tr29/#Word_Boundaries>.
+     */
+    fun getWordBoundary(offset: Int): TextRange {
+        assert(!needsLayout)
+        return multiParagraph!!.getWordBoundary(offset)
+    }
+}
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/TextPainter.kt b/ui/ui-text/src/main/java/androidx/ui/text/TextPainter.kt
deleted file mode 100644
index 0a5d93a..0000000
--- a/ui/ui-text/src/main/java/androidx/ui/text/TextPainter.kt
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * Copyright 2019 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.ui.text
-
-import androidx.annotation.RestrictTo
-import androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP
-import androidx.annotation.VisibleForTesting
-import androidx.ui.core.Constraints
-import androidx.ui.core.Density
-import androidx.ui.core.IntPxSize
-import androidx.ui.core.PxPosition
-import androidx.ui.core.Sp
-import androidx.ui.core.constrain
-import androidx.ui.core.px
-import androidx.ui.core.round
-import androidx.ui.core.sp
-import androidx.ui.engine.geometry.Offset
-import androidx.ui.engine.geometry.Rect
-import androidx.ui.engine.geometry.Size
-import androidx.ui.text.style.TextAlign
-import androidx.ui.text.style.TextDirection
-import androidx.ui.graphics.Color
-import androidx.ui.painting.BlendMode
-import androidx.ui.painting.Canvas
-import androidx.ui.painting.Gradient
-import androidx.ui.painting.Paint
-import androidx.ui.painting.Shader
-import androidx.ui.text.font.Font
-import androidx.ui.text.style.TextOverflow
-import kotlin.math.ceil
-
-private val DefaultTextAlign: TextAlign = TextAlign.Start
-private val DefaultTextDirection: TextDirection = TextDirection.Ltr
-/** The default font size if none is specified. */
-private val DefaultFontSize: Sp = 14.sp
-
-/**
- * Unfortunately, using full precision floating point here causes bad layouts because floating
- * point math isn't associative. If we add and subtract padding, for example, we'll get
- * different values when we estimate sizes and when we actually compute layout because the
- * operations will end up associated differently. To work around this problem for now, we round
- * fractional pixel values up to the nearest whole pixel value. The right long-term fix is to do
- * layout using fixed precision arithmetic.
- */
-internal fun applyFloatingPointHack(layoutValue: Float): Float {
-    return ceil(layoutValue)
-}
-
-/**
- * An object that paints a [TextSpan] tree into a [Canvas].
- *
- * To use a [TextPainter], follow these steps:
- *
- * 1. Create a [TextSpan] tree and pass it to the [TextPainter] constructor.
- *
- * 2. Call [layout] to prepare the paragraph.
- *
- * 3. Call [paint] as often as desired to paint the paragraph.
- *
- * If the width of the area into which the text is being painted changes, return to step 2. If the
- *  text to be painted changes, return to step 1.
- *
- * @param text The (potentially styled) text to paint. After this is set, you must call [layout]
- *   before the next call to [paint]. This and [textDirection] must be non-null before you call
- *   [layout].
- *
- * @param style The text style specified to render the text. Notice that you can also set text style
- *  on the given [AnnotatedString], and the style set on [text] always has higher priority than this
- *  setting. But if only one gobal text style is needed, passing it to [TextPainter] is always
- *  preferred.
- *
- * @param paragraphStyle Style configuration that applies only to paragraphs such as text alignment,
- * or text direction.
- *
- * @param maxLines An optional maximum number of lines for the text to span, wrapping if necessary.
- *   If the text exceeds the given number of lines, it is truncated such that subsequent lines are
- *   dropped.
- *   After this is set, you must call [layout] before the next call to [paint].
- *
- * @param softWrap Whether the text should break at soft line breaks.
- *   If false, the glyphs in the text will be positioned as if there was unlimited horizontal space.
- *   If [softWrap] is false, [overflow] and [textAlign] may have unexpected effects.
- *
- * @param overflow How visual overflow should be handled.
- *   Specifically, the ellipsis is applied to the last line before the line truncated by [maxLines],
- *   if [maxLines] is non-null and that line overflows the width constraint.
- *   After this is set, you must call [layout] before the next call to [paint].
- *
- * @param locale The locale used to select region-specific glyphs.
- */
-class TextPainter(
-    text: AnnotatedString? = null,
-    val style: TextStyle? = null,
-    val paragraphStyle: ParagraphStyle? = null,
-    val maxLines: Int? = null,
-    val softWrap: Boolean = true,
-    val overflow: TextOverflow = TextOverflow.Clip,
-    val locale: Locale? = null,
-    val density: Density,
-    val resourceLoader: Font.ResourceLoader
-) {
-    init {
-        assert(maxLines == null || maxLines > 0)
-    }
-
-    @VisibleForTesting
-    internal var multiParagraph: MultiParagraph? = null
-        private set
-
-    @VisibleForTesting
-    internal var needsLayout = true
-        private set
-
-    @VisibleForTesting
-    internal var layoutTemplate: Paragraph? = null
-        private set
-
-    private var overflowShader: Shader? = null
-
-    @VisibleForTesting
-    internal var hasVisualOverflow = false
-        private set
-
-    private var lastMinWidth: Float = 0.0f
-    private var lastMaxWidth: Float = 0.0f
-
-    @RestrictTo(LIBRARY_GROUP)
-    var text: AnnotatedString? = text
-        set(value) {
-            if (field == value) return
-            field = value
-            multiParagraph = null
-            needsLayout = true
-        }
-
-    internal val textStyle: TextStyle
-        get() = style ?: TextStyle()
-
-    internal val textAlign: TextAlign =
-        if (paragraphStyle?.textAlign != null) paragraphStyle.textAlign else DefaultTextAlign
-
-    internal val textDirection: TextDirection? =
-        paragraphStyle?.textDirection ?: DefaultTextDirection
-
-    private val isEllipsis = (overflow == TextOverflow.Ellipsis)
-
-    private fun createTextStyle(): TextStyle {
-        return textStyle.copy(
-            fontSize = (textStyle.fontSize ?: DefaultFontSize)
-        )
-    }
-
-    internal fun createParagraphStyle(): ParagraphStyle {
-        return ParagraphStyle(
-            textAlign = textAlign,
-            textDirection = textDirection,
-            textIndent = paragraphStyle?.textIndent,
-            lineHeight = paragraphStyle?.lineHeight
-        )
-    }
-
-    /**
-     * The height of a space in [text] in logical pixels.
-     *
-     * Not every line of text in [text] will have this height, but this height is "typical" for
-     * text in [text] and useful for sizing other objects relative a typical line of text.
-     *
-     * Obtaining this value does not require calling [layout].
-     *
-     * The style of the [text] property is used to determine the font settings that contribute to
-     * the [preferredLineHeight]. If [textStyle] is null, the default [TextStyle] values are used.
-     */
-    val preferredLineHeight: Float
-        get() {
-            if (layoutTemplate == null) {
-                // TODO(Migration/qqd): The textDirection below used to be RTL.
-                layoutTemplate = Paragraph(
-                    text = " ",
-                    style = createTextStyle(),
-                    // direction doesn't matter, text is just a space
-                    paragraphStyle = createParagraphStyle(),
-                    textStyles = listOf(),
-                    maxLines = maxLines,
-                    ellipsis = isEllipsis,
-                    density = density,
-                    resourceLoader = resourceLoader
-                )
-                layoutTemplate?.layout(ParagraphConstraints(width = Float.POSITIVE_INFINITY))
-            }
-            return layoutTemplate!!.height
-        }
-
-    private fun assertNeedsLayout(name: String) {
-        assert(!needsLayout) {
-            "TextPainter.$name should only be called after layout has been called."
-        }
-    }
-
-    /**
-     * The width at which decreasing the width of the text would prevent it from painting itself
-     * completely within its bounds.
-     *
-     * Valid only after [layout] has been called.
-     */
-    val minIntrinsicWidth: Float
-        get() {
-            assertNeedsLayout("minIntrinsicWidth")
-            return applyFloatingPointHack(multiParagraph!!.minIntrinsicWidth)
-        }
-
-    /**
-     * The width at which increasing the width of the text no longer decreases the height.
-     *
-     * Valid only after [layout] has been called.
-     */
-    val maxIntrinsicWidth: Float
-        get() {
-            assertNeedsLayout("maxIntrinsicWidth")
-            return applyFloatingPointHack(multiParagraph!!.maxIntrinsicWidth)
-        }
-
-    /**
-     * The horizontal space required to paint this text.
-     *
-     * Valid only after [layout] has been called.
-     */
-    val width: Float
-        get() {
-            assertNeedsLayout("width")
-            return applyFloatingPointHack(size.width)
-        }
-
-    /**
-     * The vertical space required to paint this text.
-     *
-     * Valid only after [layout] has been called.
-     */
-    val height: Float
-        get() {
-            assertNeedsLayout("height")
-            return applyFloatingPointHack(size.height)
-        }
-
-    /**
-     * The amount of space required to paint this text.
-     *
-     * Valid only after [layout] has been called.
-     */
-    var size: Size = Size(0f, 0f)
-        get() {
-            assertNeedsLayout("size")
-            return field
-        }
-        private set
-
-    /**
-     * Whether any text was truncated or ellipsized.
-     *
-     * If [maxLines] is not null, this is true if there were more lines to be drawn than the given
-     * [maxLines], and thus at least one line was omitted in the output; otherwise it is false.
-     *
-     * If [maxLines] is null, this is true if [ellipsis] is true and there was a line that
-     * overflowed the `maxWidth` argument passed to [layout]; otherwise it is false.
-     *
-     * Valid only after [layout] has been called.
-     */
-    val didExceedMaxLines: Boolean
-        get() {
-            assertNeedsLayout("didExceedMaxLines")
-            return multiParagraph!!.didExceedMaxLines
-        }
-
-    /**
-     * Computes the visual position of the glyphs for painting the text.
-     *
-     * The text will layout with a width that's as close to its max intrinsic width as possible
-     * while still being greater than or equal to `minWidth` and less than or equal to `maxWidth`.
-     *
-     * The [text] and [textDirection] properties must be non-null before this is called.
-     */
-    private fun layoutText(minWidth: Float = 0.0f, maxWidth: Float = Float.POSITIVE_INFINITY) {
-        assert(text != null) {
-            "TextPainter.text must be set to a non-null value before using the TextPainter."
-        }
-        assert(textDirection != null) {
-            "TextPainter.textDirection must be set to a non-null value before using the" +
-                    " TextPainter."
-        }
-
-        // TODO(haoyuchang): fix that when softWarp is false and overflow is Ellipsis, ellipsis
-        //  doesn't work.
-        val widthMatters = softWrap || overflow == TextOverflow.Ellipsis
-        val finalMaxWidth = if (widthMatters) maxWidth else Float.POSITIVE_INFINITY
-
-        if (!needsLayout && minWidth == lastMinWidth && finalMaxWidth == lastMaxWidth) return
-        needsLayout = false
-
-        if (multiParagraph == null) {
-            multiParagraph = MultiParagraph(
-                text!!,
-                createTextStyle(),
-                paragraphStyle ?: ParagraphStyle(),
-                maxLines,
-                isEllipsis,
-                density,
-                resourceLoader
-            )
-        }
-        lastMinWidth = minWidth
-        lastMaxWidth = finalMaxWidth
-        multiParagraph!!.layout(ParagraphConstraints(width = finalMaxWidth))
-        if (minWidth != finalMaxWidth) {
-            val newWidth = maxIntrinsicWidth.coerceIn(minWidth, finalMaxWidth)
-            if (newWidth != multiParagraph!!.width) {
-                multiParagraph!!.layout(ParagraphConstraints(width = newWidth))
-            }
-        }
-    }
-
-    fun layout(constraints: Constraints) {
-        layoutText(constraints.minWidth.value.toFloat(), constraints.maxWidth.value.toFloat())
-
-        val didOverflowHeight = didExceedMaxLines
-        size = constraints.constrain(
-            IntPxSize(multiParagraph!!.width.px.round(), multiParagraph!!.height.px.round())
-        ).let {
-            Size(it.width.value.toFloat(), it.height.value.toFloat())
-        }
-        val didOverflowWidth = size.width < multiParagraph!!.width
-        // TODO(abarth): We're only measuring the sizes of the line boxes here. If
-        // the glyphs draw outside the line boxes, we might think that there isn't
-        // visual overflow when there actually is visual overflow. This can become
-        // a problem if we start having horizontal overflow and introduce a clip
-        // that affects the actual (but undetected) vertical overflow.
-        hasVisualOverflow = didOverflowWidth || didOverflowHeight
-        overflowShader = if (hasVisualOverflow && overflow == TextOverflow.Fade) {
-            val fadeSizePainter = TextPainter(
-                text = AnnotatedString(text = "\u2026", textStyles = listOf()),
-                style = textStyle,
-                paragraphStyle = paragraphStyle,
-                density = density,
-                resourceLoader = resourceLoader
-            )
-            fadeSizePainter.layoutText()
-            val fadeWidth = fadeSizePainter.multiParagraph!!.width
-            val fadeHeight = fadeSizePainter.multiParagraph!!.height
-            if (didOverflowWidth) {
-                val (fadeStart, fadeEnd) = if (textDirection == TextDirection.Rtl) {
-                    Pair(fadeWidth, 0.0f)
-                } else {
-                    Pair(size.width - fadeWidth, size.width)
-                }
-                Gradient.linear(
-                    Offset(fadeStart, 0.0f),
-                    Offset(fadeEnd, 0.0f),
-                    listOf(Color(0xFFFFFFFF.toInt()), Color(0x00FFFFFF))
-                )
-            } else {
-                val fadeEnd = size.height
-                val fadeStart = fadeEnd - fadeHeight
-                Gradient.linear(
-                    Offset(0.0f, fadeStart),
-                    Offset(0.0f, fadeEnd),
-                    listOf(Color(0xFFFFFFFF.toInt()), Color(0x00FFFFFF))
-                )
-            }
-        } else {
-            null
-        }
-    }
-
-    /**
-     * Paints the text onto the given canvas.
-     *
-     * Valid only after [layout] has been called.
-     *
-     * If you cannot see the text being painted, check that your text color does not conflict with
-     * the background on which you are drawing. The default text color is white (to contrast with
-     * the default black background color), so if you are writing an application with a white
-     * background, the text will not be visible by default.
-     *
-     * To set the text style, specify a [TextStyle] when creating the [TextSpan] that you pass to
-     * the [TextPainter] constructor or to the [text] property.
-     */
-    fun paint(canvas: Canvas) {
-        assert(!needsLayout) {
-            "TextPainter.paint called when text geometry was not yet calculated.\n" +
-                    "Please call layout() before paint() to position the text before painting it."
-        }
-        // Ideally we could compute the min/max intrinsic width/height with a
-        // non-destructive operation. However, currently, computing these values
-        // will destroy state inside the painter. If that happens, we need to
-        // get back the correct state by calling layout again.
-        //
-        // TODO(abarth): Make computing the min/max intrinsic width/height
-        // a non-destructive operation.
-        //
-        // If you remove this call, make sure that changing the textAlign still
-        // works properly.
-        // TODO(Migration/qqd): Need to figure out where this constraints come from and how to make
-        // it non-null. For now Crane Text version does not need to layout text again. Comment it.
-        // layoutTextWithConstraints(constraints!!)
-
-        if (hasVisualOverflow) {
-            val bounds = Rect.fromLTWH(0f, 0f, size.width, size.height)
-            if (overflowShader != null) {
-                // This layer limits what the shader below blends with to be just the text
-                // (as opposed to the text and its background).
-                canvas.saveLayer(bounds, Paint())
-            } else {
-                canvas.save()
-            }
-            canvas.clipRect(bounds)
-        }
-
-        multiParagraph!!.paint(canvas)
-        if (hasVisualOverflow) {
-            if (overflowShader != null) {
-                val bounds = Rect.fromLTWH(0f, 0f, size.width, size.height)
-                val paint = Paint()
-                paint.blendMode = BlendMode.multiply
-                paint.shader = overflowShader
-                canvas.drawRect(bounds, paint)
-            }
-            canvas.restore()
-        }
-    }
-
-    /**
-     * Draws text background of the given range.
-     *
-     * If the given range is empty, do nothing.
-     *
-     * @param start inclusive start character offset of the drawing range.
-     * @param end exclusive end character offset of the drawing range.
-     * @param color a color to be used for drawing background.
-     * @param canvas the target canvas.
-     */
-    fun paintBackground(start: Int, end: Int, color: Color, canvas: Canvas) {
-        assert(!needsLayout)
-        if (start == end) return
-        val selectionPath = multiParagraph!!.getPathForRange(start, end)
-        // TODO(haoyuchang): check if move this paint to parameter is better
-        canvas.drawPath(selectionPath, Paint().apply { this.color = color })
-    }
-
-    /**
-     * Draws the cursor at the given character offset.
-     *
-     * TODO(nona): Make cursor customizable.
-     *
-     * @param offset the cursor offset in the text.
-     * @param canvas the target canvas.
-     */
-    fun paintCursor(offset: Int, canvas: Canvas) {
-        assert(!needsLayout)
-        val cursorRect = multiParagraph!!.getCursorRect(offset)
-        canvas.drawRect(cursorRect, Paint().apply { this.color = Color.Black })
-    }
-
-    /**
-     * Returns the bottom y coordinate of the given line.
-     *
-     * @hide
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
-    fun getLineBottom(lineIndex: Int): Float {
-        assert(!needsLayout)
-        return multiParagraph!!.getLineBottom(lineIndex)
-    }
-
-    /**
-     * Returns the line number on which the specified text offset appears.
-     * If you ask for a position before 0, you get 0; if you ask for a position
-     * beyond the end of the text, you get the last line.
-     *
-     * @hide
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
-    fun getLineForOffset(offset: Int): Int {
-        assert(!needsLayout)
-        return multiParagraph!!.getLineForOffset(offset)
-    }
-
-    /**
-     * Get the primary horizontal position for the specified text offset.
-     *
-     * @hide
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
-    fun getPrimaryHorizontal(offset: Int): Float {
-        assert(!needsLayout)
-        return multiParagraph!!.getPrimaryHorizontal(offset)
-    }
-
-    /** Returns the character offset closest to the given graphical position. */
-    fun getOffsetForPosition(position: PxPosition): Int {
-        assert(!needsLayout)
-        return multiParagraph!!.getOffsetForPosition(position)
-    }
-
-    /**
-     * Returns the bounding box as Rect of the character for given character offset. Rect includes
-     * the top, bottom, left and right of a character.
-     *
-     * Valid only after [layout] has been called.
-     *
-     * @hide
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
-    fun getBoundingBox(offset: Int): Rect {
-        assert(!needsLayout)
-        return multiParagraph!!.getBoundingBox(offset)
-    }
-
-    /**
-     * Returns the text range of the word at the given character offset. Characters not part of a
-     * word, such as spaces, symbols, and punctuation, have word breaks on both sides. In such
-     * cases, this method will return a text range that contains the given character offset.
-     *
-     * Word boundaries are defined more precisely in Unicode Standard Annex #29
-     * <http://www.unicode.org/reports/tr29/#Word_Boundaries>.
-     */
-    fun getWordBoundary(offset: Int): TextRange {
-        assert(!needsLayout)
-        return multiParagraph!!.getWordBoundary(offset)
-    }
-}
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/TextSpan.kt b/ui/ui-text/src/main/java/androidx/ui/text/TextSpan.kt
index b399a56..baa9d8a 100644
--- a/ui/ui-text/src/main/java/androidx/ui/text/TextSpan.kt
+++ b/ui/ui-text/src/main/java/androidx/ui/text/TextSpan.kt
@@ -66,8 +66,7 @@
      */
     fun toPlainText(): String {
         val buffer = StringBuilder()
-        visitTextSpan {
-                span: TextSpan ->
+        visitTextSpan { span: TextSpan ->
             buffer.append(span.text)
             true
         }
@@ -84,7 +83,8 @@
         }
         if (other.text != text ||
             children.size != other.children.size ||
-            (style == null) != (other.style == null)) {
+            (style == null) != (other.style == null)
+        ) {
             return RenderComparison.LAYOUT
         }
         var result: RenderComparison = RenderComparison.IDENTICAL
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/TextStyle.kt b/ui/ui-text/src/main/java/androidx/ui/text/TextStyle.kt
index 91bcf86..f8be302 100644
--- a/ui/ui-text/src/main/java/androidx/ui/text/TextStyle.kt
+++ b/ui/ui-text/src/main/java/androidx/ui/text/TextStyle.kt
@@ -30,6 +30,7 @@
 import androidx.ui.graphics.lerp
 import androidx.ui.lerp
 import androidx.ui.painting.Shadow
+import java.util.Locale
 
 /**
  * Configuration object to define the text style.
@@ -45,10 +46,9 @@
  *  style cannot be found in the provided custom font family.
  * @param fontFamily font family to be used when rendering the text.
  * @param fontFeatureSettings The advanced typography settings provided by font. The format is the
- *  same as the CSS font-feature-settings attribute: https://www.w3.org/TR/css-fonts-3/#font-feature-settings-prop
+ *  same as the CSS font-feature-settings attribute:
+ *  https://www.w3.org/TR/css-fonts-3/#font-feature-settings-prop
  * @param letterSpacing The amount of space (in logical pixels) to add between each letter.
- * @param wordSpacing The amount of space (in logical pixels) to add at each sequence of white-space
- *  (i.e. between each word). Only works on Android Q and above.
  * @param baselineShift This parameter specifies how much the baseline is shifted from the current
  *  position.
  * @param textGeometricTransform The geometric transformation applied the text.
@@ -136,16 +136,12 @@
          *
          * This will not work well if the styles don't set the same fields.
          *
-         * The `t` argument represents position on the timeline, with 0.0 meaning that the interpolation
-         * has not started, returning `a` (or something equivalent to `a`), 1.0 meaning that the
-         * interpolation has finished, returning `b` (or something equivalent to `b`), and values in
-         * between meaning that the interpolation is at the relevant point on the timeline between `a`
-         * and `b`. The interpolation can be extrapolated beyond 0.0 and 1.0, so negative values and
-         * values greater than 1.0 are valid (and can easily be generated by curves such as
-         * [Curves.elasticInOut]).
-         *
-         * Values for `t` are usually obtained from an [Animation<Float>], such as an
-         * [AnimationController].
+         * The `t` argument represents position on the timeline, with 0.0 meaning that the
+         * interpolation has not started, returning `a` (or something equivalent to `a`), 1.0
+         * meaning that the interpolation has finished, returning `b` (or something equivalent to
+         * `b`), and values in between meaning that the interpolation is at the relevant point on
+         * the timeline between `a` and `b`. The interpolation can be extrapolated beyond 0.0 and
+         * 1.0, so negative values and values greater than 1.0 are valid.
          */
         fun lerp(a: TextStyle? = null, b: TextStyle? = null, t: Float): TextStyle? {
             val aIsNull = a == null
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/platform/AndroidParagraph.kt b/ui/ui-text/src/main/java/androidx/ui/text/platform/AndroidParagraph.kt
index 054eb01..3ad1df5 100644
--- a/ui/ui-text/src/main/java/androidx/ui/text/platform/AndroidParagraph.kt
+++ b/ui/ui-text/src/main/java/androidx/ui/text/platform/AndroidParagraph.kt
@@ -118,13 +118,13 @@
         get() = 0.0f
 
     override val maxIntrinsicWidth: Float
-        get() = layout?.let { it.maxIntrinsicWidth } ?: 0.0f
+        get() = layout?.maxIntrinsicWidth ?: 0.0f
 
     override val baseline: Float
-        get() = layout?.let { it.layout.getLineBaseline(0).toFloat() } ?: 0.0f
+        get() = layout?.getLineBaseline(0) ?: 0.0f
 
     override val didExceedMaxLines: Boolean
-        get() = layout?.let { it.didExceedMaxLines } ?: false
+        get() = layout?.didExceedMaxLines ?: false
 
     @VisibleForTesting
     internal val textLocale: Locale
@@ -135,10 +135,9 @@
 
     private val ensureLayout: TextLayout
         get() {
-            val tmpLayout = this.layout ?: throw java.lang.IllegalStateException(
+            return this.layout ?: throw java.lang.IllegalStateException(
                 "layout() should be called first"
             )
-            return tmpLayout
         }
 
     @VisibleForTesting
@@ -156,7 +155,7 @@
             text = text,
             textIndent = paragraphStyle.textIndent,
             textStyles = listOf(
-                AnnotatedString.Item<TextStyle>(
+                AnnotatedString.Item(
                     newStyle,
                     0,
                     text.length
@@ -225,7 +224,7 @@
     }
 
     override fun getPathForRange(start: Int, end: Int): Path {
-        if (!(start <= end && start >= 0 && end <= text.length)) {
+        if (start !in 0..end || end > text.length) {
             throw AssertionError(
                 "Start($start) or End($end) is out of Range(0..${text.length}), or start > end!"
             )
@@ -236,7 +235,7 @@
     }
 
     override fun getCursorRect(offset: Int): Rect {
-        if (!(offset in (0..text.length))) {
+        if (offset !in 0..text.length) {
             throw AssertionError("offset($offset) is out of bounds (0,${text.length}")
         }
         // TODO(nona): Support cursor drawable.
@@ -285,9 +284,15 @@
         ensureLayout.isEllipsisApplied(lineIndex)
 
     override fun paint(canvas: Canvas) {
-        val tmpLayout = layout ?: throw IllegalStateException("paint cannot be " +
-                "called before layout() is called")
-        tmpLayout.paint(canvas.nativeCanvas)
+        val nativeCanvas = canvas.nativeCanvas
+        if (didExceedMaxLines) {
+            nativeCanvas.save()
+            nativeCanvas.clipRect(0f, 0f, width, height)
+        }
+        ensureLayout.paint(nativeCanvas)
+        if (didExceedMaxLines) {
+            nativeCanvas.restore()
+        }
     }
 
     private fun createTypeface(style: TextStyle): Typeface {
@@ -438,7 +443,7 @@
             style.locale?.let {
                 spannableString.setSpan(
                     // TODO(Migration/haoyuchang): support locale fallback in the framework
-                    LocaleSpan(Locale(it.languageCode, it.countryCode ?: "")),
+                    LocaleSpan(Locale(it.language, it.country ?: "")),
                     start,
                     end,
                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
@@ -481,7 +486,7 @@
 
     // fontSizeScale must be applied after fontSize is applied.
     fontSizeScale?.let {
-        textPaint.textSize *= fontSizeScale
+        textPaint.textSize *= it
     }
 
     // TODO(siyamed): This default values are problem here. If the user just gives a single font
@@ -498,8 +503,8 @@
 
     locale?.let {
         textPaint.textLocale = Locale(
-            it.languageCode,
-            it.countryCode ?: ""
+            it.language,
+            it.country ?: ""
         )
     }
 
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/platform/TypefaceAdapter.kt b/ui/ui-text/src/main/java/androidx/ui/text/platform/TypefaceAdapter.kt
index 395f4c7..b7d89d2 100644
--- a/ui/ui-text/src/main/java/androidx/ui/text/platform/TypefaceAdapter.kt
+++ b/ui/ui-text/src/main/java/androidx/ui/text/platform/TypefaceAdapter.kt
@@ -49,8 +49,8 @@
     )
 
     companion object {
-        // Accept FontWeights at and above 600 to be bold. 600 comes from FontFamily.cpp#computeFakery
-        // function in minikin
+        // Accept FontWeights at and above 600 to be bold. 600 comes from
+        // FontFamily.cpp#computeFakery function in minikin
         private val ANDROID_BOLD = FontWeight.w600
 
         // 16 is a random number and is not based on any strong logic
@@ -205,7 +205,8 @@
         return if (Build.VERSION.SDK_INT < 28) {
             val targetStyle = getTypefaceStyle(
                 isBold = synthesizeWeight,
-                isItalic = synthesizeStyle && fontStyle == FontStyle.Italic)
+                isItalic = synthesizeStyle && fontStyle == FontStyle.Italic
+            )
             Typeface.create(typeface, targetStyle)
         } else {
             val finalFontWeight = if (synthesizeWeight) {
diff --git a/ui/ui-text/src/test/java/androidx/ui/input/PasswordVisualTransformationTest.kt b/ui/ui-text/src/test/java/androidx/ui/input/PasswordVisualTransformationTest.kt
new file mode 100644
index 0000000..0b95106
--- /dev/null
+++ b/ui/ui-text/src/test/java/androidx/ui/input/PasswordVisualTransformationTest.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2019 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.ui.input
+
+import androidx.ui.text.AnnotatedString
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class PasswordVisualTransformationTest {
+    @Test
+    fun check_visual_output_is_masked_with_asterisk() {
+        val transformation = PasswordVisualTransformation(mask = '*')
+        val text = AnnotatedString("12345")
+        val (transformedText, map) = transformation.filter(text)
+
+        assertEquals("*****", transformedText.text)
+        for (i in 0..transformedText.text.length) {
+            assertEquals(i, map.originalToTransformed(i))
+            assertEquals(i, map.transformedToOriginal(i))
+        }
+    }
+
+    @Test
+    fun check_visual_output_is_masked_with_default() {
+        val filter = PasswordVisualTransformation()
+        val text = AnnotatedString("1234567890")
+        val (filtered, map) = filter.filter(text)
+
+        assertEquals("\u2022".repeat(10), filtered.text)
+        for (i in 0..filtered.text.length) {
+            assertEquals(i, map.originalToTransformed(i))
+            assertEquals(i, map.transformedToOriginal(i))
+        }
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-text/src/test/java/androidx/ui/text/AnnotatedStringTransformTest.kt b/ui/ui-text/src/test/java/androidx/ui/text/AnnotatedStringTransformTest.kt
new file mode 100644
index 0000000..b2b25d4
--- /dev/null
+++ b/ui/ui-text/src/test/java/androidx/ui/text/AnnotatedStringTransformTest.kt
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2019 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.ui.text
+
+import androidx.ui.core.sp
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import java.util.Locale
+
+@RunWith(JUnit4::class)
+class AnnotatedStringTransformTest {
+
+    private val TextStyle1 = TextStyle(fontSize = 8.sp)
+    private val TextStyle2 = TextStyle(fontSize = 16.sp)
+    private val TextStyle3 = TextStyle(fontSize = 24.sp)
+
+    private val ParaStyle1 = ParagraphStyle(lineHeight = 1.0f)
+    private val ParaStyle2 = ParagraphStyle(lineHeight = 2.0f)
+
+    /**
+     * Helper function for creating AnnotatedString.Item with TextRange.
+     */
+    private fun <T> makeItem(style: T, range: TextRange) =
+        AnnotatedString.Item(style, range.start, range.end)
+
+    /**
+     * Make AnnotatedString.Item with original string with using "(" and ")" characters.
+     *
+     * For example.
+     *   val text = "aaa bbb ccc"
+     *
+     *   AnnotatedString.Item(STYLE, 4, 8)
+     *
+     * can be written as
+     *
+     *   val text = "aaa bbb ccc"
+     *
+     *   makeItem(STYLE, "aaa (bbb )ccc")
+     */
+    private fun <T> makeItem(style: T, rangeStr: String): AnnotatedString.Item<T> {
+        val start = rangeStr.indexOf('(')
+        val end = rangeStr.indexOf(')')
+
+        if (start >= end) throw RuntimeException("Invalid range str: $rangeStr")
+        return makeItem(style, TextRange(start, end - 1 /* subtract start marker */))
+    }
+
+    @Test
+    fun `English uppercase`() {
+        val input = AnnotatedString("aaa bbb ccc",
+            listOf(
+                makeItem(TextStyle1, "(aaa bbb ccc)"),
+                makeItem(TextStyle2, "(aaa )bbb ccc"),
+                makeItem(TextStyle3, "aaa (bbb ccc)")
+            ), listOf(
+                makeItem(ParaStyle1, "(aaa bbb )ccc"),
+                makeItem(ParaStyle2, "aaa bbb (ccc)")
+            )
+        )
+
+        val uppercase = input.toUpperCase()
+
+        assertEquals(input.text.toUpperCase(), uppercase.text)
+        assertEquals(input.textStyles, uppercase.textStyles)
+        assertEquals(input.paragraphStyles, uppercase.paragraphStyles)
+    }
+
+    @Test
+    fun `English lowercase`() {
+        val input = AnnotatedString("aaa bbb ccc",
+            listOf(
+                makeItem(TextStyle1, "(aaa bbb ccc)"),
+                makeItem(TextStyle2, "(aaa )bbb ccc"),
+                makeItem(TextStyle3, "aaa (bbb ccc)")
+            ), listOf(
+                makeItem(ParaStyle1, "(aaa bbb )ccc"),
+                makeItem(ParaStyle2, "aaa bbb (ccc)")
+            )
+        )
+
+        val lowercase = input.toLowerCase()
+
+        assertEquals(input.text.toLowerCase(), lowercase.text)
+        assertEquals(input.textStyles, lowercase.textStyles)
+        assertEquals(input.paragraphStyles, lowercase.paragraphStyles)
+    }
+
+    @Test
+    fun `English capitalize`() {
+        val input = AnnotatedString("aaa bbb ccc",
+            listOf(
+                makeItem(TextStyle1, "(aaa bbb ccc)"),
+                makeItem(TextStyle2, "(aaa )bbb ccc"),
+                makeItem(TextStyle3, "aaa (bbb ccc)")
+            ), listOf(
+                makeItem(ParaStyle1, "(aaa bbb )ccc"),
+                makeItem(ParaStyle2, "aaa bbb (ccc)")
+            )
+        )
+
+        val capitalized = input.capitalize()
+
+        assertEquals(input.text.capitalize(), capitalized.text)
+        assertEquals(input.textStyles, capitalized.textStyles)
+        assertEquals(input.paragraphStyles, capitalized.paragraphStyles)
+    }
+
+    @Test
+    fun `English decapitalize`() {
+        val input = AnnotatedString("aaa bbb ccc",
+            listOf(
+                makeItem(TextStyle1, "(aaa bbb ccc)"),
+                makeItem(TextStyle2, "(aaa )bbb ccc"),
+                makeItem(TextStyle3, "aaa (bbb ccc)")
+            ), listOf(
+                makeItem(ParaStyle1, "(aaa bbb )ccc"),
+                makeItem(ParaStyle2, "aaa bbb (ccc)")
+            )
+        )
+
+        val decapitalized = input.decapitalize()
+
+        assertEquals(input.text.decapitalize(), decapitalized.text)
+        assertEquals(input.textStyles, decapitalized.textStyles)
+        assertEquals(input.paragraphStyles, decapitalized.paragraphStyles)
+    }
+
+    @Test
+    fun `locale dependent uppercase or lowercase (Turkish uppercase)`() {
+        val input = AnnotatedString("hhh iii jjj",
+            listOf(
+                makeItem(TextStyle1, "(hhh iii jjj)"),
+                makeItem(TextStyle2, "(hhh )iii jjj"),
+                makeItem(TextStyle3, "hhh (iii jjj)")
+            ), listOf(
+                makeItem(ParaStyle1, "(hhh iii )jjj"),
+                makeItem(ParaStyle2, "hhh iii (jjj)")
+            )
+        )
+
+        val uppercase = input.toUpperCase(Locale.forLanguageTag("tr"))
+
+        assertEquals(input.text.toUpperCase(Locale.forLanguageTag("tr")), uppercase.text)
+
+        val upperI = "i".toUpperCase(Locale.forLanguageTag("tr"))
+
+        assertEquals(
+            listOf(
+                makeItem(TextStyle1, "(HHH $upperI$upperI$upperI JJJ)"),
+                makeItem(TextStyle2, "(HHH )$upperI$upperI$upperI JJJ"),
+                makeItem(TextStyle3, "HHH ($upperI$upperI$upperI JJJ)")
+            ),
+            uppercase.textStyles)
+        assertEquals(
+            listOf(
+                makeItem(ParaStyle1, "(HHH $upperI$upperI$upperI )JJJ"),
+                makeItem(ParaStyle2, "HHH $upperI$upperI$upperI (JJJ)")
+            ),
+            uppercase.paragraphStyles)
+    }
+
+    @Test
+    fun `not 1-by-1 mapping uppercase or lowercase (Lithuanian lowercase)`() {
+        val input = AnnotatedString("HHH ÌÌÌ YYY",
+            listOf(
+                makeItem(TextStyle1, "(HHH ÌÌÌ YYY)"),
+                makeItem(TextStyle2, "(HHH )ÌÌÌ YYY"),
+                makeItem(TextStyle3, "HHH (ÌÌÌ YYY)")
+            ), listOf(
+                makeItem(ParaStyle1, "(HHH ÌÌÌ )YYY"),
+                makeItem(ParaStyle2, "HHH ÌÌÌ (YYY)")
+            )
+        )
+
+        val lowercase = input.toLowerCase(Locale.forLanguageTag("lt"))
+
+        assertEquals(input.text.toLowerCase(Locale.forLanguageTag("lt")), lowercase.text)
+
+        // Usually generate U+0069 U+0307 U+0300
+        val lowerIDot = "Ì".toLowerCase(Locale.forLanguageTag("lt"))
+        assertEquals(
+            listOf(
+                makeItem(TextStyle1, "(hhh $lowerIDot$lowerIDot$lowerIDot yyy)"),
+                makeItem(TextStyle2, "(hhh )$lowerIDot$lowerIDot$lowerIDot yyy"),
+                makeItem(TextStyle3, "hhh ($lowerIDot$lowerIDot$lowerIDot yyy)")
+            ),
+            lowercase.textStyles)
+        assertEquals(
+            listOf(
+                makeItem(ParaStyle1, "(hhh $lowerIDot$lowerIDot$lowerIDot )yyy"),
+                makeItem(ParaStyle2, "hhh $lowerIDot$lowerIDot$lowerIDot (yyy)")
+            ),
+            lowercase.paragraphStyles)
+    }
+
+    @Test
+    fun `nothing happens for CJK uppercase or lowercase (Japanese uppercase)`() {
+        val input = AnnotatedString("あああ いいい ううう",
+            listOf(
+                makeItem(TextStyle1, "(あああ いいい ううう)"),
+                makeItem(TextStyle2, "(あああ )いいい ううう"),
+                makeItem(TextStyle3, "あああ (いいい ううう)")
+            ), listOf(
+                makeItem(ParaStyle1, "(あああ いいい )ううう"),
+                makeItem(ParaStyle2, "あああ いいい (ううう)")
+            )
+        )
+
+        val uppercase = input.toUpperCase()
+
+        // No upper case concept in Japanese, so should be the same
+        assertEquals(input.text, uppercase.text)
+        assertEquals(input.textStyles, uppercase.textStyles)
+        assertEquals(input.paragraphStyles, uppercase.paragraphStyles)
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-text/src/test/java/androidx/ui/text/TextDelegateTest.kt b/ui/ui-text/src/test/java/androidx/ui/text/TextDelegateTest.kt
new file mode 100644
index 0000000..6487e90
--- /dev/null
+++ b/ui/ui-text/src/test/java/androidx/ui/text/TextDelegateTest.kt
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2019 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.ui.text
+
+import androidx.ui.core.Constraints
+import androidx.ui.core.Density
+import androidx.ui.painting.Canvas
+import androidx.ui.text.font.Font
+import androidx.ui.text.style.TextAlign
+import androidx.ui.text.style.TextDirection
+import androidx.ui.text.style.TextOverflow
+import com.google.common.truth.Truth.assertThat
+import com.nhaarman.mockitokotlin2.mock
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import java.util.Locale
+
+@RunWith(JUnit4::class)
+class TextDelegateTest() {
+    private val density = Density(density = 1f)
+    private val resourceLoader = mock<Font.ResourceLoader>()
+
+    @Test
+    fun `constructor with default values`() {
+        val textDelegate = TextDelegate(density = density, resourceLoader = resourceLoader)
+
+        assertThat(textDelegate.text).isNull()
+        assertThat(textDelegate.textAlign).isEqualTo(TextAlign.Start)
+        assertThat(textDelegate.textDirection).isEqualTo(TextDirection.Ltr)
+        assertThat(textDelegate.maxLines).isNull()
+        assertThat(textDelegate.overflow).isEqualTo(TextOverflow.Clip)
+        assertThat(textDelegate.locale).isNull()
+    }
+
+    @Test
+    fun `constructor with customized text(TextSpan)`() {
+        val text = AnnotatedString("Hello")
+        val textDelegate = TextDelegate(
+            text = text,
+            density = density,
+            resourceLoader = resourceLoader
+        )
+
+        assertThat(textDelegate.text).isEqualTo(text)
+    }
+
+    @Test
+    fun `constructor with customized textAlign`() {
+        val textDelegate = TextDelegate(
+            paragraphStyle = ParagraphStyle(textAlign = TextAlign.Left),
+            density = density,
+            resourceLoader = resourceLoader
+        )
+
+        assertThat(textDelegate.textAlign).isEqualTo(TextAlign.Left)
+    }
+
+    @Test
+    fun `constructor with customized textDirection`() {
+        val textDelegate = TextDelegate(
+            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
+            density = density,
+            resourceLoader = resourceLoader
+        )
+
+        assertThat(textDelegate.textDirection).isEqualTo(TextDirection.Rtl)
+    }
+
+    @Test
+    fun `constructor with customized maxLines`() {
+        val maxLines = 8
+
+        val textDelegate = TextDelegate(
+            maxLines = maxLines,
+            density = density,
+            resourceLoader = resourceLoader
+        )
+
+        assertThat(textDelegate.maxLines).isEqualTo(maxLines)
+    }
+
+    @Test
+    fun `constructor with customized overflow`() {
+        val overflow = TextOverflow.Ellipsis
+
+        val textDelegate = TextDelegate(
+            overflow = overflow,
+            density = density,
+            resourceLoader = resourceLoader
+        )
+
+        assertThat(textDelegate.overflow).isEqualTo(overflow)
+    }
+
+    @Test
+    fun `constructor with customized locale`() {
+        val locale = Locale("en", "US")
+
+        val textDelegate = TextDelegate(
+            locale = locale,
+            density = density,
+            resourceLoader = resourceLoader
+        )
+
+        assertThat(textDelegate.locale).isEqualTo(locale)
+    }
+
+    @Test
+    fun `createParagraphStyle without TextStyle in AnnotatedText`() {
+        val maxLines = 5
+        val overflow = TextOverflow.Ellipsis
+        val locale = Locale("en", "US")
+        val text = AnnotatedString(text = "Hello")
+        val textDelegate = TextDelegate(
+            text = text,
+            paragraphStyle = ParagraphStyle(
+                textAlign = TextAlign.Center,
+                textDirection = TextDirection.Rtl
+            ),
+            maxLines = maxLines,
+            overflow = overflow,
+            locale = locale,
+            density = density,
+            resourceLoader = resourceLoader
+        )
+
+        val paragraphStyle = textDelegate.createParagraphStyle()
+
+        assertThat(paragraphStyle.textAlign).isEqualTo(TextAlign.Center)
+        assertThat(paragraphStyle.textDirection).isEqualTo(TextDirection.Rtl)
+    }
+
+    @Test
+    fun `applyFloatingPointHack with value is integer toDouble`() {
+        assertThat(applyFloatingPointHack(2f)).isEqualTo(2.0f)
+    }
+
+    @Test
+    fun `applyFloatingPointHack with value smaller than half`() {
+        assertThat(applyFloatingPointHack(2.2f)).isEqualTo(3.0f)
+    }
+
+    @Test
+    fun `applyFloatingPointHack with value larger than half`() {
+        assertThat(applyFloatingPointHack(2.8f)).isEqualTo(3.0f)
+    }
+
+    @Test(expected = AssertionError::class)
+    fun `minIntrinsicWidth without layout assertion should fail`() {
+        val textDelegate = TextDelegate(density = density, resourceLoader = resourceLoader)
+
+        textDelegate.minIntrinsicWidth
+    }
+
+    @Test(expected = AssertionError::class)
+    fun `maxIntrinsicWidth without layout assertion should fail`() {
+        val textDelegate = TextDelegate(density = density, resourceLoader = resourceLoader)
+
+        textDelegate.maxIntrinsicWidth
+    }
+
+    @Test(expected = AssertionError::class)
+    fun `width without layout assertion should fail`() {
+        val textDelegate = TextDelegate(density = density, resourceLoader = resourceLoader)
+
+        textDelegate.width
+    }
+
+    @Test(expected = AssertionError::class)
+    fun `height without layout assertion should fail`() {
+        val textDelegate = TextDelegate(density = density, resourceLoader = resourceLoader)
+
+        textDelegate.height
+    }
+
+    @Test(expected = AssertionError::class)
+    fun `size without layout assertion should fail`() {
+        val textDelegate = TextDelegate(density = density, resourceLoader = resourceLoader)
+
+        textDelegate.size
+    }
+
+    @Test(expected = AssertionError::class)
+    fun `layout without text assertion should fail`() {
+        val textDelegate = TextDelegate(
+            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
+            density = density,
+            resourceLoader = resourceLoader
+        )
+
+        textDelegate.layout(Constraints())
+    }
+
+    @Test(expected = AssertionError::class)
+    fun `paint without layout assertion should fail`() {
+        val textDelegate = TextDelegate(density = density, resourceLoader = resourceLoader)
+        val canvas = mock<Canvas>()
+
+        textDelegate.paint(canvas)
+    }
+}
diff --git a/ui/ui-text/src/test/java/androidx/ui/text/TextPainterTest.kt b/ui/ui-text/src/test/java/androidx/ui/text/TextPainterTest.kt
deleted file mode 100644
index 5dcae69..0000000
--- a/ui/ui-text/src/test/java/androidx/ui/text/TextPainterTest.kt
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright 2019 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.ui.text
-
-import androidx.ui.core.Constraints
-import androidx.ui.core.Density
-import androidx.ui.painting.Canvas
-import androidx.ui.text.font.Font
-import androidx.ui.text.style.TextAlign
-import androidx.ui.text.style.TextDirection
-import androidx.ui.text.style.TextOverflow
-import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.mock
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@RunWith(JUnit4::class)
-class TextPainterTest() {
-    private val density = Density(density = 1f)
-    private val resourceLoader = mock<Font.ResourceLoader>()
-
-    @Test
-    fun `constructor with default values`() {
-        val textPainter = TextPainter(density = density, resourceLoader = resourceLoader)
-
-        assertThat(textPainter.text).isNull()
-        assertThat(textPainter.textAlign).isEqualTo(TextAlign.Start)
-        assertThat(textPainter.textDirection).isEqualTo(TextDirection.Ltr)
-        assertThat(textPainter.maxLines).isNull()
-        assertThat(textPainter.overflow).isEqualTo(TextOverflow.Clip)
-        assertThat(textPainter.locale).isNull()
-    }
-
-    @Test
-    fun `constructor with customized text(TextSpan)`() {
-        val text = AnnotatedString("Hello")
-        val textPainter = TextPainter(
-            text = text,
-            density = density,
-            resourceLoader = resourceLoader
-        )
-
-        assertThat(textPainter.text).isEqualTo(text)
-    }
-
-    @Test
-    fun `constructor with customized textAlign`() {
-        val textPainter = TextPainter(
-            paragraphStyle = ParagraphStyle(textAlign = TextAlign.Left),
-            density = density,
-            resourceLoader = resourceLoader
-        )
-
-        assertThat(textPainter.textAlign).isEqualTo(TextAlign.Left)
-    }
-
-    @Test
-    fun `constructor with customized textDirection`() {
-        val textPainter = TextPainter(
-            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Rtl),
-            density = density,
-            resourceLoader = resourceLoader
-        )
-
-        assertThat(textPainter.textDirection).isEqualTo(TextDirection.Rtl)
-    }
-
-    @Test
-    fun `constructor with customized maxLines`() {
-        val maxLines = 8
-
-        val textPainter = TextPainter(
-            maxLines = maxLines,
-            density = density,
-            resourceLoader = resourceLoader
-        )
-
-        assertThat(textPainter.maxLines).isEqualTo(maxLines)
-    }
-
-    @Test
-    fun `constructor with customized overflow`() {
-        val overflow = TextOverflow.Ellipsis
-
-        val textPainter = TextPainter(
-            overflow = overflow,
-            density = density,
-            resourceLoader = resourceLoader
-        )
-
-        assertThat(textPainter.overflow).isEqualTo(overflow)
-    }
-
-    @Test
-    fun `constructor with customized locale`() {
-        val locale = Locale("en", "US")
-
-        val textPainter = TextPainter(
-            locale = locale,
-            density = density,
-            resourceLoader = resourceLoader
-        )
-
-        assertThat(textPainter.locale).isEqualTo(locale)
-    }
-
-    @Test
-    fun `text setter`() {
-        val textPainter = TextPainter(density = density, resourceLoader = resourceLoader)
-        val text = AnnotatedString(text = "Hello")
-
-        textPainter.text = text
-
-        assertThat(textPainter.text).isEqualTo(text)
-        assertThat(textPainter.multiParagraph).isNull()
-        assertThat(textPainter.needsLayout).isTrue()
-    }
-
-    @Test
-    fun `createParagraphStyle without TextStyle in AnnotatedText`() {
-        val maxLines = 5
-        val overflow = TextOverflow.Ellipsis
-        val locale = Locale("en", "US")
-        val text = AnnotatedString(text = "Hello")
-        val textPainter = TextPainter(
-            text = text,
-            paragraphStyle = ParagraphStyle(
-                textAlign = TextAlign.Center,
-                textDirection = TextDirection.Rtl
-            ),
-            maxLines = maxLines,
-            overflow = overflow,
-            locale = locale,
-            density = density,
-            resourceLoader = resourceLoader
-        )
-
-        val paragraphStyle = textPainter.createParagraphStyle()
-
-        assertThat(paragraphStyle.textAlign).isEqualTo(TextAlign.Center)
-        assertThat(paragraphStyle.textDirection).isEqualTo(TextDirection.Rtl)
-    }
-
-    @Test
-    fun `applyFloatingPointHack with value is integer toDouble`() {
-        assertThat(applyFloatingPointHack(2f)).isEqualTo(2.0f)
-    }
-
-    @Test
-    fun `applyFloatingPointHack with value smaller than half`() {
-        assertThat(applyFloatingPointHack(2.2f)).isEqualTo(3.0f)
-    }
-
-    @Test
-    fun `applyFloatingPointHack with value larger than half`() {
-        assertThat(applyFloatingPointHack(2.8f)).isEqualTo(3.0f)
-    }
-
-    @Test(expected = AssertionError::class)
-    fun `minIntrinsicWidth without layout assertion should fail`() {
-        val textPainter = TextPainter(density = density, resourceLoader = resourceLoader)
-
-        textPainter.minIntrinsicWidth
-    }
-
-    @Test(expected = AssertionError::class)
-    fun `maxIntrinsicWidth without layout assertion should fail`() {
-        val textPainter = TextPainter(density = density, resourceLoader = resourceLoader)
-
-        textPainter.maxIntrinsicWidth
-    }
-
-    @Test(expected = AssertionError::class)
-    fun `width without layout assertion should fail`() {
-        val textPainter = TextPainter(density = density, resourceLoader = resourceLoader)
-
-        textPainter.width
-    }
-
-    @Test(expected = AssertionError::class)
-    fun `height without layout assertion should fail`() {
-        val textPainter = TextPainter(density = density, resourceLoader = resourceLoader)
-
-        textPainter.height
-    }
-
-    @Test(expected = AssertionError::class)
-    fun `size without layout assertion should fail`() {
-        val textPainter = TextPainter(density = density, resourceLoader = resourceLoader)
-
-        textPainter.size
-    }
-
-    @Test(expected = AssertionError::class)
-    fun `layout without text assertion should fail`() {
-        val textPainter = TextPainter(
-            paragraphStyle = ParagraphStyle(textDirection = TextDirection.Ltr),
-            density = density,
-            resourceLoader = resourceLoader
-        )
-
-        textPainter.layout(Constraints())
-    }
-
-    @Test(expected = AssertionError::class)
-    fun `paint without layout assertion should fail`() {
-        val textPainter = TextPainter(density = density, resourceLoader = resourceLoader)
-        val canvas = mock<Canvas>()
-
-        textPainter.paint(canvas)
-    }
-}
diff --git a/ui/ui-text/src/test/java/androidx/ui/text/TextStyleTest.kt b/ui/ui-text/src/test/java/androidx/ui/text/TextStyleTest.kt
index 70ae35a..42c143e 100644
--- a/ui/ui-text/src/test/java/androidx/ui/text/TextStyleTest.kt
+++ b/ui/ui-text/src/test/java/androidx/ui/text/TextStyleTest.kt
@@ -34,6 +34,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
+import java.util.Locale
 
 @RunWith(JUnit4::class)
 class TextStyleTest {
diff --git a/ui/ui-tooling/OWNERS b/ui/ui-tooling/OWNERS
new file mode 100644
index 0000000..abfbec5
--- /dev/null
+++ b/ui/ui-tooling/OWNERS
@@ -0,0 +1 @@
+chuckj@google.com
diff --git a/ui/ui-tooling/build.gradle b/ui/ui-tooling/build.gradle
new file mode 100644
index 0000000..6c52afa
--- /dev/null
+++ b/ui/ui-tooling/build.gradle
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2019 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.LibraryGroups
+import androidx.build.LibraryVersions
+import androidx.build.Publish
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
+import static androidx.build.dependencies.DependenciesKt.*
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+    id("AndroidXUiPlugin")
+    id("org.jetbrains.kotlin.android")
+}
+
+dependencies {
+    kotlinPlugin project(path: ":compose:compose-compiler", configuration: "embeddablePlugin")
+
+    implementation(KOTLIN_COMPOSE_STDLIB)
+    implementation(project(":compose:compose-runtime"))
+    implementation(project(":ui:ui-core"))
+    implementation(project(":ui:ui-framework"))
+    implementation(project(":ui:ui-platform"))
+
+    androidTestImplementation(JUNIT)
+    androidTestImplementation(ANDROIDX_TEST_RUNNER)
+    androidTestImplementation(ANDROIDX_TEST_RULES)
+    androidTestImplementation project(":ui:ui-layout")
+    androidTestImplementation project(":ui:ui-foundation")
+    androidTestImplementation(TRUTH)
+}
+
+androidx {
+    name = "AndroidX UI Tooling"
+    publish = Publish.SNAPSHOT_AND_RELEASE
+    mavenVersion = LibraryVersions.UI
+    mavenGroup = LibraryGroups.UI
+    inceptionYear = "2019"
+    description = "AndroidX UI Tooling support"
+}
+
+tasks.withType(KotlinCompile).configureEach {
+    kotlinOptions {
+        useIR = true
+    }
+}
diff --git a/ui/ui-tooling/src/androidTest/AndroidManifest.xml b/ui/ui-tooling/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..52a8adc
--- /dev/null
+++ b/ui/ui-tooling/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2019 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 package="androidx.ui.tooling" xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <application
+        android:debuggable="false"
+        tools:ignore="HardcodedDebugMode"
+        tools:replace="android:debuggable"
+        >
+        <activity android:name="androidx.ui.tooling.TestActivity"
+            android:theme="@style/TestTheme"/>
+    </application>
+</manifest>
+
diff --git a/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/InspectableTests.kt b/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/InspectableTests.kt
new file mode 100644
index 0000000..6d4a3f9b
--- /dev/null
+++ b/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/InspectableTests.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2019 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.ui.tooling
+
+import androidx.compose.SlotTable
+import androidx.compose.composer
+import androidx.test.filters.SmallTest
+import androidx.ui.core.dp
+import androidx.ui.core.px
+import androidx.ui.foundation.ColoredRect
+import androidx.ui.graphics.Color
+import androidx.ui.layout.Column
+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.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class InspectableTests : ToolingTest() {
+    @Test
+    fun simpleInspection() {
+        show {
+            Inspectable {
+                Column {
+                    ColoredRect(color = Color(0xFF), width = 100.dp, height = 100.dp)
+                }
+            }
+        }
+
+        // Should be able to find the group for this test
+        val group = tables.findGroupForFile("InspectableTests")
+        assertNotNull(group)
+
+        // The group should have a non-empty bounding box
+        assertEquals(0.px, group!!.box.top)
+        assertEquals(0.px, group.box.left)
+        assertNotEquals(0.px, group.box.right)
+        assertNotEquals(0.px, group.box.bottom)
+    }
+
+    @Test
+    fun inInspectionMode() {
+        var displayed = false
+        show {
+            Inspectable {
+                Column {
+                    InInspectionModeOnly {
+                        ColoredRect(color = Color(0xFF), width = 100.dp, height = 100.dp)
+                        displayed = true
+                    }
+                }
+            }
+        }
+
+        assertTrue(displayed)
+    }
+
+    @Test
+    fun notInInspectionMode() {
+        var displayed = false
+        show {
+            Column {
+                InInspectionModeOnly {
+                    ColoredRect(color = Color(0xFF), width = 100.dp, height = 100.dp)
+                    displayed = true
+                }
+            }
+        }
+
+        assertFalse(displayed)
+    }
+}
+
+fun Iterable<SlotTable>.findGroupForFile(fileName: String) =
+    map { it.findGroupForFile(fileName) }.filterNotNull().firstOrNull()
+fun SlotTable.findGroupForFile(fileName: String) = asTree().findGroupForFile(fileName)
+fun Group.findGroupForFile(fileName: String): Group? {
+    val position = position
+    if (position != null && position.contains(fileName)) return this
+    return children.map { it.findGroupForFile(fileName) }.filterNotNull().firstOrNull()
+}
\ No newline at end of file
diff --git a/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/TestActivity.kt b/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/TestActivity.kt
new file mode 100644
index 0000000..255afca
--- /dev/null
+++ b/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/TestActivity.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2019 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.ui.tooling
+
+import android.app.Activity
+import java.util.concurrent.CountDownLatch
+
+class TestActivity : Activity() {
+    var hasFocusLatch = CountDownLatch(1)
+
+    override fun onWindowFocusChanged(hasFocus: Boolean) {
+        super.onWindowFocusChanged(hasFocus)
+        if (hasFocus) {
+            hasFocusLatch.countDown()
+        }
+    }
+}
diff --git a/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/ToolingTest.kt b/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/ToolingTest.kt
new file mode 100644
index 0000000..e2d67c5
--- /dev/null
+++ b/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/ToolingTest.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2019 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.ui.tooling
+
+import android.os.Handler
+import androidx.compose.Children
+import androidx.compose.Composable
+import androidx.compose.composer
+import androidx.test.rule.ActivityTestRule
+import androidx.ui.core.OnPositioned
+import androidx.ui.core.setContent
+import org.junit.Before
+import org.junit.Rule
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+
+open class ToolingTest {
+    @get:Rule
+    val activityTestRule = ActivityTestRule<TestActivity>(
+        TestActivity::class.java
+    )
+    lateinit var activity: TestActivity
+    lateinit var handler: Handler
+    lateinit var positionedLatch: CountDownLatch
+
+    @Before
+    fun setup() {
+        activity = activityTestRule.activity
+        activity.hasFocusLatch.await(5, TimeUnit.SECONDS)
+
+        activityTestRule.onUiThread { handler = Handler() }
+    }
+
+    @Composable
+    internal fun Positioned() {
+        OnPositioned(onPositioned = { positionedLatch.countDown() })
+    }
+
+    internal fun show(@Children composable: @Composable() () -> Unit) {
+        positionedLatch = CountDownLatch(1)
+        activityTestRule.onUiThread {
+            activity.setContent {
+                Positioned()
+                composable()
+            }
+        }
+
+        // Wait for the layout to be performed
+        positionedLatch.await(1, TimeUnit.SECONDS)
+
+        // Wait for the UI thread to complete its current work so we know that layout is done.
+        activityTestRule.onUiThread { }
+    }
+}
+
+// Kotlin IR compiler doesn't seem too happy with auto-conversion from
+// lambda to Runnable, so separate it here
+fun ActivityTestRule<TestActivity>.onUiThread(block: () -> Unit) {
+    val runnable: Runnable = object : Runnable {
+        override fun run() {
+            block()
+        }
+    }
+    runOnUiThread(runnable)
+}
\ No newline at end of file
diff --git a/ui/ui-tooling/src/androidTest/res/values/style.xml b/ui/ui-tooling/src/androidTest/res/values/style.xml
new file mode 100644
index 0000000..e4bcb85
--- /dev/null
+++ b/ui/ui-tooling/src/androidTest/res/values/style.xml
@@ -0,0 +1,26 @@
+<!--
+  Copyright 2019 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.
+  -->
+
+<resources>
+    <style name="TestTheme" parent="@android:style/Theme.Material.Light.NoActionBar">
+        <item name="android:windowBackground">#ffffff</item>
+        <item name="android:windowActionBar">false</item>
+        <item name="android:windowAnimationStyle">@null</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:windowFullscreen">true</item>
+        <item name="android:windowNoTitle">true</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/ui/ui-tooling/src/main/AndroidManifest.xml b/ui/ui-tooling/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9294924
--- /dev/null
+++ b/ui/ui-tooling/src/main/AndroidManifest.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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 package="androidx.ui.tooling">
+    <application/>
+</manifest>
+
diff --git a/ui/ui-tooling/src/main/java/androidx/ui/tooling/Inspectable.kt b/ui/ui-tooling/src/main/java/androidx/ui/tooling/Inspectable.kt
new file mode 100644
index 0000000..a3ff6a3
--- /dev/null
+++ b/ui/ui-tooling/src/main/java/androidx/ui/tooling/Inspectable.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2019 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.ui.tooling
+
+import androidx.compose.Ambient
+import androidx.compose.Children
+import androidx.compose.Composable
+import androidx.compose.SlotTable
+import androidx.compose.ambient
+import androidx.compose.composer
+import androidx.compose.unaryPlus
+import java.util.Collections
+import java.util.WeakHashMap
+
+/**
+ * Inspectable mode ambient. True if the the composition is composed inside a Inspectable component.
+ */
+val InspectionMode = Ambient.of("Inspection Mode") { false }
+
+/**
+ * A wrapper for compositions in inspection mode. The composition inside the Inspectable component
+ * is in inspection mode.
+ */
+@Composable
+fun Inspectable(@Children children: @Composable() () -> Unit) {
+    composer.composer.collectKeySourceInformation()
+    tables.add(composer.composer.slotTable)
+    InspectionMode.Provider(true) {
+        children()
+    }
+}
+
+val tables = Collections.newSetFromMap(WeakHashMap<SlotTable, Boolean>())
+
+/**
+ * A wrapper for inspection-mode-only behavior. The children of this component will only be included
+ * in the composition when the composition is in inspection mode.
+ */
+@Composable
+fun InInspectionModeOnly(@Children children: @Composable() () -> Unit) {
+    if (+ambient(InspectionMode)) {
+        children()
+    }
+}
diff --git a/ui/ui-tooling/src/main/java/androidx/ui/tooling/SlotTree.kt b/ui/ui-tooling/src/main/java/androidx/ui/tooling/SlotTree.kt
new file mode 100644
index 0000000..f57f0fa
--- /dev/null
+++ b/ui/ui-tooling/src/main/java/androidx/ui/tooling/SlotTree.kt
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2019 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.ui.tooling
+
+import androidx.compose.SlotReader
+import androidx.compose.SlotTable
+import androidx.compose.isJoinedKey
+import androidx.compose.joinedKeyLeft
+import androidx.compose.joinedKeyRight
+import androidx.compose.keySourceInfoOf
+import androidx.ui.core.LayoutNode
+import androidx.ui.core.PxBounds
+import androidx.ui.core.max
+import androidx.ui.core.min
+import androidx.ui.core.px
+import androidx.ui.core.toPx
+
+/**
+ * A group in the slot table. Represents either a call or an emitted node.
+ */
+sealed class Group(
+    /**
+     * The key is the key generated for the group
+     */
+    val key: Any?,
+
+    /**
+     * The bounding layout box for the group.
+     */
+    val box: PxBounds,
+
+    /**
+     * Any data that was stored in the slot table for the group
+     */
+    val data: Array<Any?>,
+
+    /**
+     * The child groups of this group
+     */
+    val children: Array<Group>
+)
+
+/**
+ * A group that represents the invocation of a component
+ */
+class CallGroup(key: Any?, box: PxBounds, data: Array<Any?>, children: Array<Group>) :
+    Group(key, box, data, children)
+
+/**
+ * A group that represents an emitted node
+ */
+class NodeGroup(
+    key: Any?,
+
+    /**
+     * An emitted node
+     */
+    val node: Any,
+    box: PxBounds,
+    data: Array<Any?>,
+    children: Array<Group>
+) : Group(key, box, data, children)
+
+private fun SlotReader.getGroup(): Group = getGroup(true)
+
+/**
+ * A key that has being joined together to form one key.
+ */
+data class JoinedKey(val left: Any?, val right: Any?)
+
+private fun convertKey(key: Any?): Any? =
+    when (key) {
+        is Int -> keySourceInfoOf(key) ?: key
+        else ->
+            if (isJoinedKey(key))
+                JoinedKey(
+                    convertKey(joinedKeyLeft(key)),
+                    convertKey(joinedKeyRight(key))
+                )
+            else key
+    }
+
+internal val emptyBox = PxBounds(0.px, 0.px, 0.px, 0.px)
+
+/**
+ * Iterate the slot table and extract a group tree that corresponds to the content of the table.
+ */
+private fun SlotReader.getGroup(expectKey: Boolean): Group {
+    val key = if (expectKey) convertKey(next()) else null
+    val nodeGroup = isNode
+    val end = current + groupSize
+    next()
+    val data = mutableListOf<Any?>()
+    val children = mutableListOf<Group>()
+    val node = if (nodeGroup) next() else null
+    while (current < end && isGroup) {
+        children.add(getGroup(false))
+    }
+
+    // A group can start with data
+    while (!isGroup && current <= end) {
+        val dataOrKey = next()
+        if (isGroup) {
+            // Last value is a key, back up.
+            previous()
+            break
+        }
+        data.add(dataOrKey)
+    }
+
+    // A group ends with a lest of keyed groups
+    while (current < end) {
+        children.add(getGroup(true))
+    }
+
+    // Calculate bounding box
+    val box = when (node) {
+        is LayoutNode -> {
+            val left = node.x.toPx()
+            val top = node.y.toPx()
+            val right = left + node.width.toPx()
+            val bottom = top + node.height.toPx()
+            PxBounds(left = left, top = top, right = right, bottom = bottom)
+        }
+        else -> if (children.isEmpty()) emptyBox else
+            children.map { g -> g.box }.reduce { acc, box -> box.union(acc) }
+    }
+    return if (nodeGroup) NodeGroup(
+        key,
+        node as Any,
+        box,
+        data.toTypedArray(),
+        children.toTypedArray()
+    ) else
+        CallGroup(key, box, data.toTypedArray(), children.toTypedArray())
+}
+
+/**
+ * Return a group tree for for the slot table that represents the entire content of the slot
+ * table.
+ */
+fun SlotTable.asTree(): Group = read { it.getGroup() }
+
+internal fun PxBounds.union(other: PxBounds): PxBounds = PxBounds(
+    left = min(left, other.left),
+    top = min(top, other.top),
+    bottom = max(bottom, other.bottom),
+    right = max(right, other.right)
+)
+
+private fun keyPosition(key: Any?): String? = when (key) {
+    is String -> key
+    is JoinedKey -> keyPosition(key.left)
+        ?: keyPosition(key.right)
+    else -> null
+}
+
+/**
+ * The source position of the group extracted from the key, if one exists for the group.
+ */
+val Group.position: String? get() = keyPosition(key)
diff --git a/ui/ui-vector/src/main/java/androidx/ui/vector/Vector.kt b/ui/ui-vector/src/main/java/androidx/ui/vector/Vector.kt
new file mode 100644
index 0000000..1e6e8a2
--- /dev/null
+++ b/ui/ui-vector/src/main/java/androidx/ui/vector/Vector.kt
@@ -0,0 +1,476 @@
+/*
+ * Copyright 2019 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.ui.vector
+
+import android.graphics.Matrix
+import androidx.ui.engine.geometry.Offset
+import androidx.ui.painting.Canvas
+import androidx.ui.painting.Image
+import androidx.ui.painting.Paint
+import androidx.ui.painting.PaintingStyle
+import androidx.ui.painting.Path
+import androidx.ui.painting.StrokeCap
+import androidx.ui.painting.StrokeJoin
+import androidx.ui.core.Px
+import androidx.ui.graphics.Brush
+import androidx.ui.graphics.EmptyBrush
+import androidx.ui.graphics.vectorgraphics.PathBuilder
+import androidx.ui.graphics.vectorgraphics.PathNode
+import androidx.ui.graphics.vectorgraphics.PathParser
+import androidx.ui.painting.withSave
+import kotlin.math.ceil
+
+const val DefaultGroupName = ""
+const val DefaultRotation = 0.0f
+const val DefaultPivotX = 0.0f
+const val DefaultPivotY = 0.0f
+const val DefaultScaleX = 1.0f
+const val DefaultScaleY = 1.0f
+const val DefaultTranslationX = 0.0f
+const val DefaultTranslationY = 0.0f
+
+val EmptyPath = emptyArray<PathNode>()
+
+/**
+ * paint used to draw the cached vector graphic to the provided canvas
+ * TODO (njawad) Can we update the Crane Canvas API to make this paint optional?
+ */
+internal val EmptyPaint = Paint()
+
+class PathDelegate(val delegate: PathBuilder.() -> Unit)
+
+// TODO figure out how to use UNIONTYPE with a Lambda receiver. Cannot cast to KClass which is what
+// UnionType is expecting
+// TODO uncomment usage of UnionType when Compose can be accessed across modules
+typealias PathData = /*@UnionType(String::class, PathDelegate::class, Array<PathNode>::class)*/ Any?
+
+// TODO (njawad) change to color int
+typealias BrushType = /*@UnionType(Int::class, Brush::class)*/ Any
+
+const val DefaultPathName = ""
+const val DefaultAlpha = 1.0f
+const val DefaultStrokeLineWidth = 0.0f
+const val DefaultStrokeLineMiter = 4.0f
+
+val DefaultStrokeLineCap = StrokeCap.butt
+val DefaultStrokeLineJoin = StrokeJoin.miter
+
+fun addPathNodes(pathStr: String?): Array<PathNode> =
+    if (pathStr == null) {
+        EmptyPath
+    } else {
+        PathParser().parsePathString(pathStr).toNodes()
+    }
+
+sealed class VNode {
+    abstract fun draw(canvas: Canvas)
+}
+
+class VectorComponent(
+    val name: String = "",
+    var viewportWidth: Float,
+    var viewportHeight: Float,
+    var defaultWidth: Px,
+    var defaultHeight: Px
+) : VNode() {
+
+    val root = GroupComponent(this@VectorComponent.name).apply {
+        pivotX = 0.0f
+        pivotY = 0.0f
+        scaleX = defaultWidth.value / viewportWidth
+        scaleY = defaultHeight.value / viewportHeight
+    }
+
+    /**
+     * Cached Image of the Vector Graphic to be re-used across draw calls
+     * if the Vector graphic is not dirty
+     */
+    // TODO (njawad) add invalidation logic to re-draw into the offscreen Image
+    private var cachedImage: Image? = null
+
+    val size: Int
+        get() = root.size
+
+    override fun draw(canvas: Canvas) {
+        var targetImage = cachedImage
+        if (targetImage == null) {
+            targetImage = Image(
+                ceil(defaultWidth.value).toInt(),
+                ceil(defaultHeight.value).toInt()
+            )
+            cachedImage = targetImage
+            root.draw(Canvas(targetImage))
+        }
+        canvas.drawImage(targetImage, Offset.zero, EmptyPaint)
+    }
+
+    override fun toString(): String {
+        return buildString {
+            append("Params: ")
+            append("\tname: ").append(name).append("\n")
+            append("\twidth: ").append(defaultWidth).append("\n")
+            append("\theight: ").append(defaultHeight).append("\n")
+            append("\tviewportWidth: ").append(viewportWidth).append("\n")
+            append("\tviewportHeight: ").append(viewportHeight).append("\n")
+        }
+    }
+}
+
+class PathComponent(val name: String) : VNode() {
+
+    var fill: Brush = EmptyBrush
+        set(value) {
+            field = value
+            updateFillPaint {
+                field.applyBrush(this)
+            }
+        }
+
+    var fillAlpha: Float = DefaultAlpha
+        set(value) {
+            field = value
+            updateFillPaint {
+                alpha = field
+            }
+        }
+
+    var pathNodes: Array<PathNode> = emptyArray()
+        set(value) {
+            field = value
+            isPathDirty = true
+        }
+
+    var strokeAlpha: Float = DefaultAlpha
+        set(value) {
+            field = value
+            updateStrokePaint {
+                alpha = field
+            }
+        }
+
+    var strokeLineWidth: Float = DefaultStrokeLineWidth
+        set(value) {
+            field = value
+            updateStrokePaint {
+                strokeWidth = field
+            }
+        }
+
+    var stroke: Brush = EmptyBrush
+        set(value) {
+            field = value
+            updateStrokePaint {
+                field.applyBrush(this)
+            }
+        }
+
+    var strokeLineCap: StrokeCap = DefaultStrokeLineCap
+        set(value) {
+            field = value
+            updateStrokePaint {
+                strokeCap = field
+            }
+        }
+
+    var strokeLineJoin: StrokeJoin = DefaultStrokeLineJoin
+        set(value) {
+            field = value
+            updateStrokePaint {
+                strokeJoin = field
+            }
+        }
+
+    var strokeLineMiter: Float = DefaultStrokeLineMiter
+        set(value) {
+            field = value
+            updateStrokePaint {
+                strokeMiterLimit = field
+            }
+        }
+
+    private var isPathDirty = true
+
+    private val path = Path()
+
+    private var fillPaint: Paint? = null
+    private var strokePaint: Paint? = null
+
+    private val parser = PathParser()
+
+    private fun updateStrokePaint(strokePaintUpdater: Paint.() -> Unit) {
+        if (strokePaint == null) {
+            strokePaint = createStrokePaint()
+        } else {
+            strokePaint?.strokePaintUpdater()
+        }
+    }
+
+    private fun createStrokePaint(): Paint = Paint().apply {
+        isAntiAlias = true
+        style = PaintingStyle.stroke
+        alpha = strokeAlpha
+        strokeWidth = strokeLineWidth
+        strokeCap = strokeLineCap
+        strokeJoin = strokeLineJoin
+        strokeMiterLimit = strokeLineMiter
+        stroke.applyBrush(this)
+    }
+
+    private fun updateFillPaint(fillPaintUpdater: Paint.() -> Unit) {
+        if (fillPaint == null) {
+            fillPaint = createFillPaint()
+        } else {
+            fillPaint?.fillPaintUpdater()
+        }
+    }
+
+    private fun createFillPaint(): Paint = Paint().apply {
+        isAntiAlias = true
+        alpha = fillAlpha
+        style = PaintingStyle.fill
+        fill.applyBrush(this)
+    }
+
+    private fun updatePath() {
+        parser.clear()
+        path.reset()
+        parser.addPathNodes(pathNodes).toPath(path)
+    }
+
+    override fun draw(canvas: Canvas) {
+        if (isPathDirty) {
+            updatePath()
+            isPathDirty = false
+        }
+
+        val fillBrush = fill
+        if (fillBrush !== EmptyBrush) {
+            var targetFillPaint = fillPaint
+            if (targetFillPaint == null) {
+                targetFillPaint = createFillPaint()
+                fillPaint = targetFillPaint
+            }
+            canvas.drawPath(path, targetFillPaint)
+        }
+
+        val strokeBrush = stroke
+        if (strokeBrush !== EmptyBrush) {
+            var targetStrokePaint = strokePaint
+            if (targetStrokePaint == null) {
+                targetStrokePaint = createStrokePaint()
+                strokePaint = targetStrokePaint
+            }
+            canvas.drawPath(path, targetStrokePaint)
+        }
+    }
+
+    override fun toString(): String {
+        return path.toString()
+    }
+}
+
+class GroupComponent(val name: String = DefaultGroupName) : VNode() {
+
+    private var groupMatrix: Matrix? = null
+
+    private val children = mutableListOf<VNode>()
+
+    var clipPathNodes: Array<PathNode> = EmptyPath
+        set(value) {
+            field = value
+            isClipPathDirty = true
+        }
+
+    private val willClipPath: Boolean
+        get() = clipPathNodes.isNotEmpty()
+
+    private var isClipPathDirty = true
+
+    private var clipPath: Path? = null
+    private var parser: PathParser? = null
+
+    private fun updateClipPath() {
+        if (willClipPath) {
+            var targetParser = parser
+            if (targetParser == null) {
+                targetParser = PathParser()
+                parser = targetParser
+            } else {
+                targetParser.clear()
+            }
+
+            var targetClip = clipPath
+            if (targetClip == null) {
+                targetClip = Path()
+                clipPath = targetClip
+            } else {
+                targetClip.reset()
+            }
+
+            targetParser.addPathNodes(clipPathNodes).toPath(targetClip)
+        }
+    }
+
+    var rotation: Float = DefaultRotation
+        set(value) {
+            field = value
+            isMatrixDirty = true
+        }
+
+    var pivotX: Float = DefaultPivotX
+        set(value) {
+            field = value
+            isMatrixDirty = true
+        }
+
+    var pivotY: Float = DefaultPivotY
+        set(value) {
+            field = value
+            isMatrixDirty = true
+        }
+
+    var scaleX: Float = DefaultScaleX
+        set(value) {
+            field = value
+            isMatrixDirty = true
+        }
+
+    var scaleY: Float = DefaultScaleY
+        set(value) {
+            field = value
+            isMatrixDirty = true
+        }
+
+    var translationX: Float = DefaultTranslationX
+        set(value) {
+            field = value
+            isMatrixDirty = true
+        }
+
+    var translationY: Float = DefaultTranslationY
+        set(value) {
+            field = value
+            isMatrixDirty = true
+        }
+
+    private var isMatrixDirty = true
+
+    private fun updateMatrix() {
+        val matrix: Matrix
+        val target = groupMatrix
+        if (target == null) {
+            matrix = Matrix()
+            groupMatrix = matrix
+        } else {
+            matrix = target
+        }
+        with(matrix) {
+            reset()
+            postTranslate(-pivotX, -pivotY)
+            postScale(scaleX, scaleY)
+            postRotate(rotation, 0f, 0f)
+            postTranslate(translationX + pivotX,
+                translationY + pivotY)
+        }
+    }
+
+    fun insertAt(index: Int, instance: VNode) {
+        if (index < size) {
+            children[index] = instance
+        } else {
+            children.add(instance)
+        }
+    }
+
+    fun move(from: Int, to: Int, count: Int) {
+        if (from > to) {
+            var current = to
+            repeat(count) {
+                val node = children[from]
+                children.removeAt(from)
+                children.add(current, node)
+                current++
+            }
+        } else {
+            repeat(count) {
+                val node = children[from]
+                children.removeAt(from)
+                children.add(to - 1, node)
+            }
+        }
+    }
+
+    fun remove(index: Int, count: Int) {
+        repeat(count) {
+            children.removeAt(index)
+        }
+    }
+
+    override fun draw(canvas: Canvas) {
+        if (isMatrixDirty) {
+            updateMatrix()
+            isMatrixDirty = false
+        }
+
+        if (isClipPathDirty) {
+            updateClipPath()
+            isClipPathDirty = false
+        }
+
+        canvas.withSave {
+            val targetClip = clipPath
+            if (willClipPath && targetClip != null) {
+                canvas.clipPath(targetClip)
+            }
+
+            val matrix = groupMatrix
+            if (matrix != null) {
+                // TODO (njawad) add concat support to matrix
+                canvas.nativeCanvas.concat(matrix)
+            }
+
+            for (node in children) {
+                node.draw(canvas)
+            }
+        }
+    }
+
+    val size: Int
+        get() = children.size
+
+    override fun toString(): String {
+        val sb = StringBuilder().append("VGroup: ").append(name)
+        for (node in children) {
+            sb.append("\t").append(node.toString()).append("\n")
+        }
+        return sb.toString()
+    }
+}
+
+fun createPath(pathData: PathData): Array<PathNode> {
+    @Suppress("UNCHECKED_CAST")
+    return when (pathData) {
+        is Array<*> -> pathData as Array<PathNode>
+        is PathDelegate -> {
+            with(PathBuilder()) {
+                pathData.delegate(this)
+                getNodes()
+            }
+        }
+        else -> throw IllegalArgumentException("Must be array of PathNodes or PathDelegate")
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-vector/src/main/java/androidx/ui/vector/VectorComposeNonIR.kt b/ui/ui-vector/src/main/java/androidx/ui/vector/VectorComposeNonIR.kt
index c9fb0acd..7201fb2 100644
--- a/ui/ui-vector/src/main/java/androidx/ui/vector/VectorComposeNonIR.kt
+++ b/ui/ui-vector/src/main/java/androidx/ui/vector/VectorComposeNonIR.kt
@@ -29,9 +29,6 @@
 import androidx.compose.SlotTable
 import androidx.compose.ViewValidator
 import androidx.compose.cache
-import androidx.ui.graphics.vectorgraphics.GroupComponent
-import androidx.ui.graphics.vectorgraphics.VNode
-import androidx.ui.graphics.vectorgraphics.VectorComponent
 import java.util.WeakHashMap
 
 private val VectorTreeRoots = WeakHashMap<VectorComponent, VectorTree>()
@@ -50,7 +47,7 @@
 fun composeVector(
     container: VectorComponent,
     parent: CompositionReference? = null,
-    composable: @Composable() VectorScope.() -> Unit
+    composable: @Composable() VectorScope.(viewportWidth: Float, viewportHeight: Float) -> Unit
 ) {
     var root = VectorTreeRoots[container]
     if (root == null) {
@@ -59,6 +56,8 @@
         root.context = CompositionContext.prepare(root, parent) {
             VectorComposer(container.root, this).also { composer = it }
         }
+        root.viewportWidth = container.viewportWidth
+        root.viewportHeight = container.viewportHeight
         root.scope = VectorScope(VectorComposition(composer))
     }
     root.composable = composable
@@ -71,20 +70,23 @@
 ) : Composer<VNode>(SlotTable(), Applier(root, VectorApplyAdapter()), recomposer)
 
 fun disposeVector(container: VectorComponent, parent: CompositionReference? = null) {
-    composeVector(container, parent) {}
+    composeVector(container, parent) { _, _ -> }
     VectorTreeRoots.remove(container)
 }
 
 private class VectorTree : Component() {
 
     lateinit var scope: VectorScope
-    lateinit var composable: @Composable() VectorScope.() -> Unit
+    lateinit var composable: @Composable() VectorScope.(Float, Float) -> Unit
     lateinit var context: CompositionContext
 
+    var viewportWidth: Float = 0.0f
+    var viewportHeight: Float = 0.0f
+
     override fun compose() {
         with(context.composer) {
             startGroup(0) // TODO (njawad) what key should be used here?
-            scope.composable()
+            scope.composable(viewportWidth, viewportHeight)
             endGroup()
         }
     }
@@ -128,7 +130,7 @@
     @Suppress("NOTHING_TO_INLINE")
     inline operator fun <V> Effect<V>.unaryPlus(): V = resolve(this@VectorComposition.composer)
 
-    inline fun <T: VNode> emit(
+    inline fun <T : VNode> emit(
         key: Any,
         /*crossinline*/
         ctor: () -> T,
diff --git a/versionedparcelable/api/api_lint.ignore b/versionedparcelable/api/api_lint.ignore
new file mode 100644
index 0000000..f66b0cc
--- /dev/null
+++ b/versionedparcelable/api/api_lint.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+MissingNullability: androidx.versionedparcelable.ParcelUtils#getVersionedParcelableList(android.os.Bundle, String) parameter #0:
+    Missing nullability on parameter `bundle` in method `getVersionedParcelableList`
+MissingNullability: androidx.versionedparcelable.ParcelUtils#getVersionedParcelableList(android.os.Bundle, String) parameter #1:
+    Missing nullability on parameter `key` in method `getVersionedParcelableList`
diff --git a/viewpager/api/api_lint.ignore b/viewpager/api/api_lint.ignore
index 9a70682..0dcbc5b 100644
--- a/viewpager/api/api_lint.ignore
+++ b/viewpager/api/api_lint.ignore
@@ -9,6 +9,70 @@
     Listeners should be an interface, or otherwise renamed Callback: SimpleOnPageChangeListener
 
 
+MissingNullability: androidx.viewpager.widget.PagerTabStrip#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `onDraw`
+MissingNullability: androidx.viewpager.widget.PagerTabStrip#onTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onTouchEvent`
+MissingNullability: androidx.viewpager.widget.PagerTabStrip#setBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `d` in method `setBackgroundDrawable`
+MissingNullability: androidx.viewpager.widget.ViewPager#addFocusables(java.util.ArrayList<android.view.View>, int, int) parameter #0:
+    Missing nullability on parameter `views` in method `addFocusables`
+MissingNullability: androidx.viewpager.widget.ViewPager#addTouchables(java.util.ArrayList<android.view.View>) parameter #0:
+    Missing nullability on parameter `views` in method `addTouchables`
+MissingNullability: androidx.viewpager.widget.ViewPager#addView(android.view.View, int, android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `child` in method `addView`
+MissingNullability: androidx.viewpager.widget.ViewPager#addView(android.view.View, int, android.view.ViewGroup.LayoutParams) parameter #2:
+    Missing nullability on parameter `params` in method `addView`
+MissingNullability: androidx.viewpager.widget.ViewPager#canScroll(android.view.View, boolean, int, int, int) parameter #0:
+    Missing nullability on parameter `v` in method `canScroll`
+MissingNullability: androidx.viewpager.widget.ViewPager#checkLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `checkLayoutParams`
+MissingNullability: androidx.viewpager.widget.ViewPager#dispatchKeyEvent(android.view.KeyEvent) parameter #0:
+    Missing nullability on parameter `event` in method `dispatchKeyEvent`
+MissingNullability: androidx.viewpager.widget.ViewPager#dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent) parameter #0:
+    Missing nullability on parameter `event` in method `dispatchPopulateAccessibilityEvent`
+MissingNullability: androidx.viewpager.widget.ViewPager#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
+MissingNullability: androidx.viewpager.widget.ViewPager#generateDefaultLayoutParams():
+    Missing nullability on method `generateDefaultLayoutParams` return
+MissingNullability: androidx.viewpager.widget.ViewPager#generateLayoutParams(android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.viewpager.widget.ViewPager#generateLayoutParams(android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.viewpager.widget.ViewPager#generateLayoutParams(android.view.ViewGroup.LayoutParams):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.viewpager.widget.ViewPager#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `generateLayoutParams`
+MissingNullability: androidx.viewpager.widget.ViewPager#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `onDraw`
+MissingNullability: androidx.viewpager.widget.ViewPager#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onInterceptTouchEvent`
+MissingNullability: androidx.viewpager.widget.ViewPager#onRequestFocusInDescendants(int, android.graphics.Rect) parameter #1:
+    Missing nullability on parameter `previouslyFocusedRect` in method `onRequestFocusInDescendants`
+MissingNullability: androidx.viewpager.widget.ViewPager#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.viewpager.widget.ViewPager#onSaveInstanceState():
+    Missing nullability on method `onSaveInstanceState` return
+MissingNullability: androidx.viewpager.widget.ViewPager#onTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onTouchEvent`
+MissingNullability: androidx.viewpager.widget.ViewPager#removeView(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `removeView`
+MissingNullability: androidx.viewpager.widget.ViewPager#setOnPageChangeListener(androidx.viewpager.widget.ViewPager.OnPageChangeListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnPageChangeListener`
+MissingNullability: androidx.viewpager.widget.ViewPager#verifyDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `who` in method `verifyDrawable`
+MissingNullability: androidx.viewpager.widget.ViewPager.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `LayoutParams`
+MissingNullability: androidx.viewpager.widget.ViewPager.LayoutParams#LayoutParams(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `LayoutParams`
+MissingNullability: androidx.viewpager.widget.ViewPager.SavedState#CREATOR:
+    Missing nullability on field `CREATOR` in class `class androidx.viewpager.widget.ViewPager.SavedState`
+MissingNullability: androidx.viewpager.widget.ViewPager.SavedState#toString():
+    Missing nullability on method `toString` return
+MissingNullability: androidx.viewpager.widget.ViewPager.SavedState#writeToParcel(android.os.Parcel, int) parameter #0:
+    Missing nullability on parameter `out` in method `writeToParcel`
+
+
 ParcelCreator: androidx.viewpager.widget.ViewPager.SavedState:
     Parcelable requires `public int describeContents()`; missing in androidx.viewpager.widget.ViewPager.SavedState
 
diff --git a/viewpager2/api/1.0.0-beta04.txt b/viewpager2/api/1.0.0-beta04.txt
new file mode 100644
index 0000000..e1b6ab9
--- /dev/null
+++ b/viewpager2/api/1.0.0-beta04.txt
@@ -0,0 +1,96 @@
+// Signature format: 3.0
+package androidx.viewpager2.adapter {
+
+  public abstract class FragmentStateAdapter extends androidx.recyclerview.widget.RecyclerView.Adapter<androidx.viewpager2.adapter.FragmentViewHolder> implements androidx.viewpager2.adapter.StatefulAdapter {
+    ctor public FragmentStateAdapter(androidx.fragment.app.FragmentActivity);
+    ctor public FragmentStateAdapter(androidx.fragment.app.Fragment);
+    ctor public FragmentStateAdapter(androidx.fragment.app.FragmentManager, androidx.lifecycle.Lifecycle);
+    method public boolean containsItem(long);
+    method public abstract androidx.fragment.app.Fragment createFragment(int);
+    method public final void onBindViewHolder(androidx.viewpager2.adapter.FragmentViewHolder, int);
+    method public final androidx.viewpager2.adapter.FragmentViewHolder onCreateViewHolder(android.view.ViewGroup, int);
+    method public final boolean onFailedToRecycleView(androidx.viewpager2.adapter.FragmentViewHolder);
+    method public final void onViewAttachedToWindow(androidx.viewpager2.adapter.FragmentViewHolder);
+    method public final void onViewRecycled(androidx.viewpager2.adapter.FragmentViewHolder);
+    method public final void restoreState(android.os.Parcelable);
+    method public final android.os.Parcelable saveState();
+    method public final void setHasStableIds(boolean);
+  }
+
+  public final class FragmentViewHolder extends androidx.recyclerview.widget.RecyclerView.ViewHolder {
+  }
+
+  public interface StatefulAdapter {
+    method public void restoreState(android.os.Parcelable);
+    method public android.os.Parcelable saveState();
+  }
+
+}
+
+package androidx.viewpager2.widget {
+
+  public final class CompositePageTransformer implements androidx.viewpager2.widget.ViewPager2.PageTransformer {
+    ctor public CompositePageTransformer();
+    method public void addTransformer(androidx.viewpager2.widget.ViewPager2.PageTransformer);
+    method public void removeTransformer(androidx.viewpager2.widget.ViewPager2.PageTransformer);
+    method public void transformPage(android.view.View, float);
+  }
+
+  public final class MarginPageTransformer implements androidx.viewpager2.widget.ViewPager2.PageTransformer {
+    ctor public MarginPageTransformer(@Px int);
+    method public void transformPage(android.view.View, float);
+  }
+
+  public final class ViewPager2 extends android.view.ViewGroup {
+    ctor public ViewPager2(android.content.Context);
+    ctor public ViewPager2(android.content.Context, android.util.AttributeSet?);
+    ctor public ViewPager2(android.content.Context, android.util.AttributeSet?, int);
+    ctor @RequiresApi(21) public ViewPager2(android.content.Context, android.util.AttributeSet?, int, int);
+    method public void addItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration);
+    method public void addItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration, int);
+    method public boolean beginFakeDrag();
+    method public boolean endFakeDrag();
+    method public boolean fakeDragBy(@Px float);
+    method public androidx.recyclerview.widget.RecyclerView.Adapter? getAdapter();
+    method public int getCurrentItem();
+    method public androidx.recyclerview.widget.RecyclerView.ItemDecoration getItemDecorationAt(int);
+    method public int getItemDecorationCount();
+    method public int getOffscreenPageLimit();
+    method public int getOrientation();
+    method public int getScrollState();
+    method public void invalidateItemDecorations();
+    method public boolean isFakeDragging();
+    method public boolean isUserInputEnabled();
+    method public void registerOnPageChangeCallback(androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback);
+    method public void removeItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration);
+    method public void removeItemDecorationAt(int);
+    method public void requestTransform();
+    method public void setAdapter(androidx.recyclerview.widget.RecyclerView.Adapter?);
+    method public void setCurrentItem(int);
+    method public void setCurrentItem(int, boolean);
+    method public void setOffscreenPageLimit(int);
+    method public void setOrientation(int);
+    method public void setPageTransformer(androidx.viewpager2.widget.ViewPager2.PageTransformer?);
+    method public void setUserInputEnabled(boolean);
+    method public void unregisterOnPageChangeCallback(androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback);
+    field public static final int OFFSCREEN_PAGE_LIMIT_DEFAULT = -1; // 0xffffffff
+    field public static final int ORIENTATION_HORIZONTAL = 0; // 0x0
+    field public static final int ORIENTATION_VERTICAL = 1; // 0x1
+    field public static final int SCROLL_STATE_DRAGGING = 1; // 0x1
+    field public static final int SCROLL_STATE_IDLE = 0; // 0x0
+    field public static final int SCROLL_STATE_SETTLING = 2; // 0x2
+  }
+
+  public abstract static class ViewPager2.OnPageChangeCallback {
+    ctor public ViewPager2.OnPageChangeCallback();
+    method public void onPageScrollStateChanged(int);
+    method public void onPageScrolled(int, float, @Px int);
+    method public void onPageSelected(int);
+  }
+
+  public static interface ViewPager2.PageTransformer {
+    method public void transformPage(android.view.View, float);
+  }
+
+}
+
diff --git a/viewpager2/api/api_lint.ignore b/viewpager2/api/api_lint.ignore
new file mode 100644
index 0000000..29b10a8
--- /dev/null
+++ b/viewpager2/api/api_lint.ignore
@@ -0,0 +1,13 @@
+// Baseline format: 1.0
+MissingNullability: androidx.viewpager2.widget.ViewPager2#dispatchRestoreInstanceState(android.util.SparseArray<android.os.Parcelable>) parameter #0:
+    Missing nullability on parameter `container` in method `dispatchRestoreInstanceState`
+MissingNullability: androidx.viewpager2.widget.ViewPager2#getAccessibilityClassName():
+    Missing nullability on method `getAccessibilityClassName` return
+MissingNullability: androidx.viewpager2.widget.ViewPager2#onInitializeAccessibilityNodeInfo(android.view.accessibility.AccessibilityNodeInfo) parameter #0:
+    Missing nullability on parameter `info` in method `onInitializeAccessibilityNodeInfo`
+MissingNullability: androidx.viewpager2.widget.ViewPager2#onRestoreInstanceState(android.os.Parcelable) parameter #0:
+    Missing nullability on parameter `state` in method `onRestoreInstanceState`
+MissingNullability: androidx.viewpager2.widget.ViewPager2#onViewAdded(android.view.View) parameter #0:
+    Missing nullability on parameter `child` in method `onViewAdded`
+MissingNullability: androidx.viewpager2.widget.ViewPager2#performAccessibilityAction(int, android.os.Bundle) parameter #1:
+    Missing nullability on parameter `arguments` in method `performAccessibilityAction`
diff --git a/preference/ktx/api/res-1.1.0-alpha04.txt b/viewpager2/api/res-1.0.0-beta04.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha04.txt
copy to viewpager2/api/res-1.0.0-beta04.txt
diff --git a/viewpager2/api/restricted_1.0.0-beta04.txt b/viewpager2/api/restricted_1.0.0-beta04.txt
new file mode 100644
index 0000000..686a4b0
--- /dev/null
+++ b/viewpager2/api/restricted_1.0.0-beta04.txt
@@ -0,0 +1,105 @@
+// Signature format: 3.0
+package androidx.viewpager2.adapter {
+
+  public abstract class FragmentStateAdapter extends androidx.recyclerview.widget.RecyclerView.Adapter<androidx.viewpager2.adapter.FragmentViewHolder> implements androidx.viewpager2.adapter.StatefulAdapter {
+    ctor public FragmentStateAdapter(androidx.fragment.app.FragmentActivity);
+    ctor public FragmentStateAdapter(androidx.fragment.app.Fragment);
+    ctor public FragmentStateAdapter(androidx.fragment.app.FragmentManager, androidx.lifecycle.Lifecycle);
+    method public boolean containsItem(long);
+    method public abstract androidx.fragment.app.Fragment createFragment(int);
+    method public final void onBindViewHolder(androidx.viewpager2.adapter.FragmentViewHolder, int);
+    method public final androidx.viewpager2.adapter.FragmentViewHolder onCreateViewHolder(android.view.ViewGroup, int);
+    method public final boolean onFailedToRecycleView(androidx.viewpager2.adapter.FragmentViewHolder);
+    method public final void onViewAttachedToWindow(androidx.viewpager2.adapter.FragmentViewHolder);
+    method public final void onViewRecycled(androidx.viewpager2.adapter.FragmentViewHolder);
+    method public final void restoreState(android.os.Parcelable);
+    method public final android.os.Parcelable saveState();
+    method public final void setHasStableIds(boolean);
+  }
+
+  public final class FragmentViewHolder extends androidx.recyclerview.widget.RecyclerView.ViewHolder {
+  }
+
+  public interface StatefulAdapter {
+    method public void restoreState(android.os.Parcelable);
+    method public android.os.Parcelable saveState();
+  }
+
+}
+
+package androidx.viewpager2.widget {
+
+  public final class CompositePageTransformer implements androidx.viewpager2.widget.ViewPager2.PageTransformer {
+    ctor public CompositePageTransformer();
+    method public void addTransformer(androidx.viewpager2.widget.ViewPager2.PageTransformer);
+    method public void removeTransformer(androidx.viewpager2.widget.ViewPager2.PageTransformer);
+    method public void transformPage(android.view.View, float);
+  }
+
+  public final class MarginPageTransformer implements androidx.viewpager2.widget.ViewPager2.PageTransformer {
+    ctor public MarginPageTransformer(@Px int);
+    method public void transformPage(android.view.View, float);
+  }
+
+  public final class ViewPager2 extends android.view.ViewGroup {
+    ctor public ViewPager2(android.content.Context);
+    ctor public ViewPager2(android.content.Context, android.util.AttributeSet?);
+    ctor public ViewPager2(android.content.Context, android.util.AttributeSet?, int);
+    ctor @RequiresApi(21) public ViewPager2(android.content.Context, android.util.AttributeSet?, int, int);
+    method public void addItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration);
+    method public void addItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration, int);
+    method public boolean beginFakeDrag();
+    method public boolean endFakeDrag();
+    method public boolean fakeDragBy(@Px float);
+    method public androidx.recyclerview.widget.RecyclerView.Adapter? getAdapter();
+    method public int getCurrentItem();
+    method public androidx.recyclerview.widget.RecyclerView.ItemDecoration getItemDecorationAt(int);
+    method public int getItemDecorationCount();
+    method @androidx.viewpager2.widget.ViewPager2.OffscreenPageLimit public int getOffscreenPageLimit();
+    method @androidx.viewpager2.widget.ViewPager2.Orientation public int getOrientation();
+    method @androidx.viewpager2.widget.ViewPager2.ScrollState public int getScrollState();
+    method public void invalidateItemDecorations();
+    method public boolean isFakeDragging();
+    method public boolean isUserInputEnabled();
+    method public void registerOnPageChangeCallback(androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback);
+    method public void removeItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration);
+    method public void removeItemDecorationAt(int);
+    method public void requestTransform();
+    method public void setAdapter(androidx.recyclerview.widget.RecyclerView.Adapter?);
+    method public void setCurrentItem(int);
+    method public void setCurrentItem(int, boolean);
+    method public void setOffscreenPageLimit(@androidx.viewpager2.widget.ViewPager2.OffscreenPageLimit int);
+    method public void setOrientation(@androidx.viewpager2.widget.ViewPager2.Orientation int);
+    method public void setPageTransformer(androidx.viewpager2.widget.ViewPager2.PageTransformer?);
+    method public void setUserInputEnabled(boolean);
+    method public void unregisterOnPageChangeCallback(androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback);
+    field public static final int OFFSCREEN_PAGE_LIMIT_DEFAULT = -1; // 0xffffffff
+    field public static final int ORIENTATION_HORIZONTAL = 0; // 0x0
+    field public static final int ORIENTATION_VERTICAL = 1; // 0x1
+    field public static final int SCROLL_STATE_DRAGGING = 1; // 0x1
+    field public static final int SCROLL_STATE_IDLE = 0; // 0x0
+    field public static final int SCROLL_STATE_SETTLING = 2; // 0x2
+  }
+
+  @IntDef({androidx.viewpager2.widget.ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT}) @IntRange(from=1) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ViewPager2.OffscreenPageLimit {
+  }
+
+  public abstract static class ViewPager2.OnPageChangeCallback {
+    ctor public ViewPager2.OnPageChangeCallback();
+    method public void onPageScrollStateChanged(@androidx.viewpager2.widget.ViewPager2.ScrollState int);
+    method public void onPageScrolled(int, float, @Px int);
+    method public void onPageSelected(int);
+  }
+
+  @IntDef({androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL, androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ViewPager2.Orientation {
+  }
+
+  public static interface ViewPager2.PageTransformer {
+    method public void transformPage(android.view.View, float);
+  }
+
+  @IntDef({androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_IDLE, androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_DRAGGING, androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_SETTLING}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ViewPager2.ScrollState {
+  }
+
+}
+
diff --git a/viewpager2/build.gradle b/viewpager2/build.gradle
index 9de6aa7..9c933df 100644
--- a/viewpager2/build.gradle
+++ b/viewpager2/build.gradle
@@ -43,7 +43,9 @@
         exclude group: 'androidx.viewpager2', module: 'viewpager2'
     }
     androidTestImplementation(KOTLIN_STDLIB)
-    androidTestImplementation(project(":internal-testutils-ktx"))
+    androidTestImplementation(project(":internal-testutils-ktx"), {
+        exclude group: 'org.jetbrains.kotlinx'
+    })
 }
 
 android {
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterDataSetChangeWhileSmoothScrollTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterDataSetChangeWhileSmoothScrollTest.kt
index a1bc911..d97eba3 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterDataSetChangeWhileSmoothScrollTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterDataSetChangeWhileSmoothScrollTest.kt
@@ -22,6 +22,7 @@
 import androidx.viewpager2.widget.AdapterDataSetChangeWhileSmoothScrollTest.Event.OnPageScrollStateChangedEvent
 import androidx.viewpager2.widget.AdapterDataSetChangeWhileSmoothScrollTest.Event.OnPageScrolledEvent
 import androidx.viewpager2.widget.AdapterDataSetChangeWhileSmoothScrollTest.Event.OnPageSelectedEvent
+import androidx.viewpager2.widget.AdapterDataSetChangeWhileSmoothScrollTest.Modification
 import androidx.viewpager2.widget.AdapterDataSetChangeWhileSmoothScrollTest.Modification.REMOVE_FIRST_VISIBLE
 import androidx.viewpager2.widget.AdapterDataSetChangeWhileSmoothScrollTest.Modification.SHIFT_FIRST_VISIBLE
 import androidx.viewpager2.widget.AdapterDataSetChangeWhileSmoothScrollTest.Modification.SHIFT_FIRST_VISIBLE_THEN_REMOVE_FIRST
@@ -64,9 +65,7 @@
         val rtl: Boolean,
         val targetBound: Boolean,
         val modification: Modification,
-        val adapterProvider: AdapterProviderForItems,
-        val expectedFinalPage: Int,
-        val expectedFinalPageText: String
+        val adapterProvider: AdapterProviderForItems
     )
 
     companion object {
@@ -121,13 +120,14 @@
             idleLatch.await(10, SECONDS)
 
             // then
-            test.assertBasicState(config.expectedFinalPage, config.expectedFinalPageText)
+            val expectedFinalPosition = test.viewPager.currentCompletelyVisibleItem
+            test.assertBasicState(expectedFinalPosition, dataSet[expectedFinalPosition])
             recorder.apply {
                 val removeItemMarkIx = markerIx(modificationMark)
-                val expectedSelectEvents = if (targetPage == config.expectedFinalPage) {
+                val expectedSelectEvents = if (targetPage == expectedFinalPosition) {
                     listOf(targetPage)
                 } else {
-                    listOf(targetPage, config.expectedFinalPage)
+                    listOf(targetPage, expectedFinalPosition)
                 }
                 // verify all events
                 assertThat(settlingIx, equalTo(0))
@@ -150,7 +150,7 @@
                 scrollsBeforeMarker.assertMaxShownPages()
                 // Only check assertLastCorrect on scroll events _after_ the marker:
                 //   the target is not reached before the data set change
-                scrollsAfterMarker.assertLastCorrect(config.expectedFinalPage)
+                scrollsAfterMarker.assertLastCorrect(expectedFinalPosition)
             }
         }
     }
@@ -325,78 +325,11 @@
     return listOf(viewAdapterProvider, viewAdapterProviderValueId).flatMap { adapterProvider ->
         listOf(ORIENTATION_HORIZONTAL, ORIENTATION_VERTICAL).flatMap { orientation ->
             listOf(false, true).flatMap { rtl ->
-                listOf(
-                    TestConfig(
-                        orientation, rtl, true,
-                        SHIFT_FIRST_VISIBLE,
-                        adapterProvider = adapterProvider,
-                        expectedFinalPage = 2,
-                        expectedFinalPageText = "0"
-                    ),
-                    TestConfig(
-                        orientation, rtl, true,
-                        SHIFT_FIRST_VISIBLE_THEN_REMOVE_FIRST,
-                        adapterProvider = adapterProvider,
-                        expectedFinalPage = targetPage - 1,
-                        expectedFinalPageText = "${targetPage + 1}"
-                    ),
-                    TestConfig(
-                        orientation, rtl, true,
-                        SHIFT_FIRST_VISIBLE_THEN_REMOVE_LAST,
-                        adapterProvider = adapterProvider,
-                        expectedFinalPage = 2,
-                        expectedFinalPageText = "0"
-                    ),
-                    TestConfig(
-                        orientation, rtl, true,
-                        SHIFT_FIRST_VISIBLE_THEN_REMOVE_FIRST_AND_LAST,
-                        adapterProvider = adapterProvider,
-                        expectedFinalPage = targetPage - 3,
-                        expectedFinalPageText = "${targetPage - 3}"
-                    ),
-                    TestConfig(
-                        orientation, rtl, true,
-                        REMOVE_FIRST_VISIBLE,
-                        adapterProvider = adapterProvider,
-                        expectedFinalPage = targetPage - 1,
-                        expectedFinalPageText = "$targetPage"
-                    ),
-                    TestConfig(
-                        orientation, rtl, false,
-                        SHIFT_FIRST_VISIBLE,
-                        adapterProvider = adapterProvider,
-                        expectedFinalPage = targetPage,
-                        expectedFinalPageText = "$targetPage"
-                    ),
-                    TestConfig(
-                        orientation, rtl, false,
-                        SHIFT_FIRST_VISIBLE_THEN_REMOVE_FIRST,
-                        adapterProvider = adapterProvider,
-                        expectedFinalPage = targetPage,
-                        expectedFinalPageText = "${targetPage + 2}"
-                    ),
-                    TestConfig(
-                        orientation, rtl, false,
-                        SHIFT_FIRST_VISIBLE_THEN_REMOVE_LAST,
-                        adapterProvider = adapterProvider,
-                        expectedFinalPage = targetPage - 1,
-                        expectedFinalPageText = "${targetPage - 4}"
-                    ),
-                    TestConfig(
-                        orientation, rtl, false,
-                        SHIFT_FIRST_VISIBLE_THEN_REMOVE_FIRST_AND_LAST,
-                        adapterProvider = adapterProvider,
-                        expectedFinalPage = targetPage - 3,
-                        expectedFinalPageText = "${targetPage - 4}"
-                    ),
-                    TestConfig(
-                        orientation, rtl, false,
-                        REMOVE_FIRST_VISIBLE,
-                        adapterProvider = adapterProvider,
-                        expectedFinalPage = targetPage,
-                        expectedFinalPageText = "${targetPage + 1}"
-                    )
-                )
+                listOf(true, false).flatMap { targetBound ->
+                    Modification.values().map { modification ->
+                        TestConfig(orientation, rtl, targetBound, modification, adapterProvider)
+                    }
+                }
             }
         }
     }
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
index 8185e8b..00719bf 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
@@ -39,6 +39,7 @@
 import androidx.test.espresso.action.ViewActions.actionWithAssertions
 import androidx.test.espresso.assertion.ViewAssertions.matches
 import androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom
+import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
 import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
 import androidx.test.espresso.matcher.ViewMatchers.withId
 import androidx.test.espresso.matcher.ViewMatchers.withText
@@ -492,7 +493,7 @@
         )
         assertThat("viewPager should be IDLE", viewPager.scrollState, equalTo(SCROLL_STATE_IDLE))
         if (value != null) {
-            onView(allOf<View>(withId(R.id.text_view), isDisplayed())).check(
+            onView(allOf<View>(withId(R.id.text_view), isCompletelyDisplayed())).check(
                 matches(withText(value))
             )
         }
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/ChangeDataSetWhileScrollingTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/ChangeDataSetWhileScrollingTest.kt
index 6040950..861f676 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/ChangeDataSetWhileScrollingTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/ChangeDataSetWhileScrollingTest.kt
@@ -49,7 +49,7 @@
 
             sleep(200) // introduce some delay, follow-up with pollingCheck
 
-            PollingCheck.waitFor(1000) {
+            PollingCheck.waitFor(2000) {
                 viewPager.scrollState == SCROLL_STATE_IDLE && viewPager.currentItem == 0
             }
 
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PaddingMarginDecorationTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PaddingMarginDecorationTest.kt
new file mode 100644
index 0000000..473935e
--- /dev/null
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PaddingMarginDecorationTest.kt
@@ -0,0 +1,429 @@
+/*
+ * Copyright 2019 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.viewpager2.widget
+
+import android.graphics.Rect
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewGroup.MarginLayoutParams
+import androidx.recyclerview.widget.RecyclerView
+import androidx.test.filters.LargeTest
+import androidx.testutils.LocaleTestUtils
+import androidx.viewpager2.widget.PaddingMarginDecorationTest.Event.OnPageScrollStateChangedEvent
+import androidx.viewpager2.widget.PaddingMarginDecorationTest.Event.OnPageScrolledEvent
+import androidx.viewpager2.widget.PaddingMarginDecorationTest.Event.OnPageSelectedEvent
+import androidx.viewpager2.widget.PaddingMarginDecorationTest.TestConfig
+import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
+import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
+import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_DRAGGING
+import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_IDLE
+import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_SETTLING
+import androidx.viewpager2.widget.swipe.ViewAdapter
+import org.hamcrest.CoreMatchers.equalTo
+import org.junit.Assert.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import java.util.concurrent.TimeUnit.SECONDS
+import kotlin.math.roundToInt
+
+@RunWith(Parameterized::class)
+@LargeTest
+class PaddingMarginDecorationTest(private val config: TestConfig) : BaseTest() {
+    data class TestConfig(
+        @ViewPager2.Orientation val orientation: Int,
+        val rtl: Boolean,
+        val vpPaddingPx: Int,
+        val rvPaddingPx: Int,
+        val itemMarginPx: Int,
+        val itemDecorationPx: Int
+    )
+
+    companion object {
+        @JvmStatic
+        @Parameterized.Parameters(name = "{0}")
+        fun spec(): List<TestConfig> = createTestSet()
+
+        // Set unequal decorations, to prevent symmetry from hiding bugs
+        // Similarly, make sure no margin is an exact multiple of another margin
+        // TODO(139452422): Set to 2/3/7/5 when PagerSnapHelper is fixed
+        const val fLeft = 2
+        const val fTop = 2
+        const val fRight = 2
+        const val fBottom = 2
+
+        fun View.applyMargin(margin: Int) {
+            val lp = layoutParams as MarginLayoutParams
+            lp.setMargins(margin * fLeft, margin * fTop, margin * fRight, margin * fBottom)
+            layoutParams = lp
+        }
+
+        fun View.applyPadding(padding: Int) {
+            setPadding(padding * fLeft, padding * fTop, padding * fRight, padding * fBottom)
+        }
+    }
+
+    private lateinit var test: Context
+    private val viewPager get() = test.viewPager
+
+    private val vpSize: Int get() {
+        return if (viewPager.isHorizontal) viewPager.width else viewPager.height
+    }
+
+    private val vpPadding: Int get() {
+        return if (viewPager.isHorizontal)
+            viewPager.paddingLeft + viewPager.paddingRight
+        else
+            viewPager.paddingTop + viewPager.paddingBottom
+    }
+
+    private val rvSize: Int get() {
+        val rv = viewPager.recyclerView
+        return if (viewPager.isHorizontal) rv.width else rv.height
+    }
+
+    private val rvMargin: Int get() {
+        return if (viewPager.isHorizontal)
+            horizontalMargin(viewPager.recyclerView.layoutParams)
+        else
+            verticalMargin(viewPager.recyclerView.layoutParams)
+    }
+
+    private val rvPadding: Int get() {
+        val rv = viewPager.recyclerView
+        return if (viewPager.isHorizontal)
+            rv.paddingLeft + rv.paddingRight
+        else
+            rv.paddingTop + rv.paddingBottom
+    }
+
+    private val itemSize: Int get() {
+        val item = viewPager.linearLayoutManager.findViewByPosition(0)!!
+        return if (viewPager.isHorizontal) item.width else item.height
+    }
+
+    private val itemMargin: Int get() {
+        val item = viewPager.linearLayoutManager.findViewByPosition(0)!!
+        return if (viewPager.isHorizontal)
+            horizontalMargin(item.layoutParams)
+        else
+            verticalMargin(item.layoutParams)
+    }
+
+    private val itemDecoration: Int get() {
+        val llm = viewPager.linearLayoutManager
+        val item = llm.findViewByPosition(0)!!
+        return if (viewPager.isHorizontal)
+            llm.getLeftDecorationWidth(item) + llm.getRightDecorationWidth(item)
+        else
+            llm.getTopDecorationHeight(item) + llm.getBottomDecorationHeight(item)
+    }
+
+    private val adapterProvider: AdapterProviderForItems get() {
+        return if (config.itemMarginPx > 0) {
+            { items -> { MarginViewAdapter(config.itemMarginPx, items) } }
+        } else {
+            { items -> { ViewAdapter(items) } }
+        }
+    }
+
+    class MarginViewAdapter(private val margin: Int, items: List<String>) : ViewAdapter(items) {
+        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+            return super.onCreateViewHolder(parent, viewType).apply { itemView.applyMargin(margin) }
+        }
+    }
+
+    class ItemDecorator(private val size: Int) : RecyclerView.ItemDecoration() {
+        override fun getItemOffsets(
+            outRect: Rect,
+            view: View,
+            parent: RecyclerView,
+            state: RecyclerView.State
+        ) {
+            outRect.left = size * fLeft
+            outRect.top = size * fTop
+            outRect.right = size * fRight
+            outRect.bottom = size * fBottom
+        }
+    }
+
+    override fun setUp() {
+        super.setUp()
+        if (config.rtl) {
+            localeUtil.resetLocale()
+            localeUtil.setLocale(LocaleTestUtils.RTL_LANGUAGE)
+        }
+        test = setUpTest(config.orientation)
+        test.runOnUiThreadSync {
+            viewPager.clipToPadding = false
+            viewPager.applyPadding(config.vpPaddingPx)
+            viewPager.recyclerView.clipToPadding = false
+            viewPager.recyclerView.applyPadding(config.rvPaddingPx)
+            viewPager.addItemDecoration(ItemDecorator(config.itemDecorationPx))
+        }
+    }
+
+    private fun horizontalMargin(lp: ViewGroup.LayoutParams): Int {
+        return if (lp is MarginLayoutParams) lp.leftMargin + lp.rightMargin else 0
+    }
+
+    private fun verticalMargin(lp: ViewGroup.LayoutParams): Int {
+        return if (lp is MarginLayoutParams) lp.topMargin + lp.bottomMargin else 0
+    }
+
+    @Test
+    fun test_pageSize() {
+        test.setAdapterSync(adapterProvider(stringSequence(1)))
+
+        val f = if (viewPager.isHorizontal) fLeft + fRight else fTop + fBottom
+
+        assertThat(vpPadding, equalTo(config.vpPaddingPx * f))
+        assertThat(rvPadding, equalTo(config.rvPaddingPx * f))
+        assertThat(itemMargin, equalTo(config.itemMarginPx * f))
+        assertThat(itemDecoration, equalTo(config.itemDecorationPx * f))
+
+        assertThat(viewPager.pageSize, equalTo(rvSize - rvPadding))
+        assertThat(viewPager.pageSize, equalTo(vpSize - vpPadding - rvMargin - rvPadding))
+        assertThat(viewPager.pageSize, equalTo(itemSize + itemDecoration + itemMargin))
+    }
+
+    /*
+    Sample log to guide the test
+
+    1 -> 2
+    onPageScrollStateChanged,1
+    onPageScrolled,1,0.019444,21
+    onPageScrolled,1,0.082407,88
+    onPageScrolled,1,0.173148,187
+    onPageScrollStateChanged,2
+    onPageSelected,2
+    onPageScrolled,1,0.343518,370
+    onPageScrolled,1,0.855556,924
+    onPageScrolled,1,0.984259,1063
+    onPageScrolled,2,0.000000,0
+    onPageScrollStateChanged,0
+
+    2 -> 1
+    onPageScrollStateChanged,1
+    onPageScrolled,1,0.972222,1050
+    onPageScrolled,1,0.910185,983
+    onPageScrolled,1,0.835185,902
+    onPageScrolled,1,0.764815,826
+    onPageScrollStateChanged,2
+    onPageSelected,1
+    onPageScrolled,1,0.616667,666
+    onPageScrolled,1,0.136111,147
+    onPageScrolled,1,0.015741,17
+    onPageScrolled,1,0.000000,0
+    onPageScrollStateChanged,0
+     */
+    @Test
+    fun test_swipeBetweenPages() {
+        test.setAdapterSync(adapterProvider(stringSequence(2)))
+        listOf(1, 0).forEach { targetPage ->
+            // given
+            val initialPage = viewPager.currentItem
+            assertThat(Math.abs(initialPage - targetPage), equalTo(1))
+
+            val callback = viewPager.addNewRecordingCallback()
+            val latch = viewPager.addWaitForScrolledLatch(targetPage)
+
+            // when
+            test.swipe(initialPage, targetPage)
+            latch.await(2, SECONDS)
+
+            // then
+            test.assertBasicState(targetPage)
+
+            callback.apply {
+                // verify all events
+                assertThat(draggingIx, equalTo(0))
+                assertThat(settlingIx, isBetweenInEx(firstScrolledIx + 1, lastScrolledIx))
+                assertThat(idleIx, equalTo(lastIx))
+                assertThat(pageSelectedIx(targetPage), equalTo(settlingIx + 1))
+                assertThat(scrollEventCount, equalTo(eventCount - 4))
+
+                // dive into scroll events
+                val sortOrder =
+                        if (targetPage - initialPage > 0) SortOrder.ASC
+                        else SortOrder.DESC
+                scrollEvents.assertPositionSorted(sortOrder)
+                scrollEvents.assertOffsetSorted(sortOrder)
+                scrollEvents.assertValueSanity(initialPage, targetPage, viewPager.pageSize)
+                scrollEvents.assertLastCorrect(targetPage)
+                scrollEvents.assertMaxShownPages()
+            }
+
+            viewPager.unregisterOnPageChangeCallback(callback)
+        }
+    }
+
+    /*
+    Before page 0
+    onPageScrollStateChanged,1
+    onPageScrolled,0,0.000000,0
+    onPageScrolled,0,0.000000,0
+    onPageScrolled,0,0.000000,0
+    onPageScrolled,0,0.000000,0
+    onPageScrollStateChanged,0
+
+    After page 2
+    onPageScrollStateChanged,1
+    onPageScrolled,2,0.000000,0
+    onPageScrolled,2,0.000000,0
+    onPageScrolled,2,0.000000,0
+    onPageScrollStateChanged,0
+     */
+    @Test
+    fun test_swipeBeyondEdgePages() {
+        val totalPages = 2
+        val edgePages = setOf(0, totalPages - 1)
+
+        test.setAdapterSync(adapterProvider(stringSequence(totalPages)))
+        listOf(0, 1, 1).forEach { targetPage ->
+            // given
+            val initialPage = viewPager.currentItem
+            val callback = viewPager.addNewRecordingCallback()
+            val latch = viewPager.addWaitForScrolledLatch(targetPage)
+
+            // when
+            test.swipe(initialPage, targetPage)
+            latch.await(2, SECONDS)
+
+            // then
+            test.assertBasicState(targetPage)
+
+            if (targetPage == initialPage && edgePages.contains(targetPage)) {
+                callback.apply {
+                    // verify all events
+                    assertThat("Events should start with a state change to DRAGGING",
+                        draggingIx, equalTo(0))
+                    assertThat("Last event should be a state change to IDLE",
+                        idleIx, equalTo(lastIx))
+                    assertThat("All events but the state changes to DRAGGING and IDLE" +
+                            " should be scroll events",
+                        scrollEventCount, equalTo(eventCount - 2))
+
+                    // dive into scroll events
+                    scrollEvents.forEach {
+                        assertThat("All scroll events should report page $targetPage",
+                            it.position, equalTo(targetPage))
+                        assertThat("All scroll events should report an offset of 0f",
+                            it.positionOffset, equalTo(0f))
+                        assertThat("All scroll events should report an offset of 0px",
+                            it.positionOffsetPixels, equalTo(0))
+                    }
+                }
+            }
+
+            viewPager.unregisterOnPageChangeCallback(callback)
+        }
+    }
+
+    private fun ViewPager2.addNewRecordingCallback(): RecordingCallback {
+        return RecordingCallback().also { registerOnPageChangeCallback(it) }
+    }
+
+    private sealed class Event {
+        data class OnPageScrolledEvent(
+            val position: Int,
+            val positionOffset: Float,
+            val positionOffsetPixels: Int
+        ) : Event()
+        data class OnPageSelectedEvent(val position: Int) : Event()
+        data class OnPageScrollStateChangedEvent(val state: Int) : Event()
+    }
+
+    private class RecordingCallback : ViewPager2.OnPageChangeCallback() {
+        private val events = mutableListOf<Event>()
+
+        val scrollEvents get() = events.mapNotNull { it as? OnPageScrolledEvent }
+        val eventCount get() = events.size
+        val scrollEventCount get() = scrollEvents.size
+        val lastIx get() = events.size - 1
+        val firstScrolledIx get() = events.indexOfFirst { it is OnPageScrolledEvent }
+        val lastScrolledIx get() = events.indexOfLast { it is OnPageScrolledEvent }
+        val settlingIx get() = events.indexOf(OnPageScrollStateChangedEvent(SCROLL_STATE_SETTLING))
+        val draggingIx get() = events.indexOf(OnPageScrollStateChangedEvent(SCROLL_STATE_DRAGGING))
+        val idleIx get() = events.indexOf(OnPageScrollStateChangedEvent(SCROLL_STATE_IDLE))
+        val pageSelectedIx: (page: Int) -> Int = { events.indexOf(OnPageSelectedEvent(it)) }
+
+        override fun onPageScrolled(
+            position: Int,
+            positionOffset: Float,
+            positionOffsetPixels: Int
+        ) {
+            events.add(OnPageScrolledEvent(position, positionOffset, positionOffsetPixels))
+        }
+
+        override fun onPageSelected(position: Int) {
+            events.add(OnPageSelectedEvent(position))
+        }
+
+        override fun onPageScrollStateChanged(state: Int) {
+            events.add(OnPageScrollStateChangedEvent(state))
+        }
+    }
+
+    private fun List<OnPageScrolledEvent>.assertPositionSorted(sortOrder: SortOrder) {
+        map { it.position }.assertSorted { it * sortOrder.sign }
+    }
+
+    private fun List<OnPageScrolledEvent>.assertLastCorrect(targetPage: Int) {
+        last().apply {
+            assertThat(position, equalTo(targetPage))
+            assertThat(positionOffsetPixels, equalTo(0))
+        }
+    }
+
+    private fun List<OnPageScrolledEvent>.assertValueSanity(
+        initialPage: Int,
+        otherPage: Int,
+        pageSize: Int
+    ) = forEach {
+        assertThat(it.position, isBetweenInInMinMax(initialPage, otherPage))
+        assertThat(it.positionOffset, isBetweenInEx(0f, 1f))
+        assertThat((it.positionOffset * pageSize).roundToInt(), equalTo(it.positionOffsetPixels))
+    }
+
+    private fun List<OnPageScrolledEvent>.assertOffsetSorted(sortOrder: SortOrder) {
+        map { it.position + it.positionOffset.toDouble() }.assertSorted { it * sortOrder.sign }
+    }
+
+    private fun List<OnPageScrolledEvent>.assertMaxShownPages() {
+        assertThat(map { it.position }.distinct().size, isBetweenInIn(0, 4))
+    }
+}
+
+// region Test Suite creation
+
+private fun createTestSet(): List<TestConfig> {
+    return listOf(ORIENTATION_HORIZONTAL, ORIENTATION_VERTICAL).flatMap { orientation ->
+        listOf(false, true).flatMap { rtl ->
+            listOf(
+                TestConfig(orientation, rtl, 0, 0, 0, 0),
+                TestConfig(orientation, rtl, 0, 0, 0, 10),
+                TestConfig(orientation, rtl, 0, 0, 10, 0),
+                TestConfig(orientation, rtl, 0, 10, 0, 0),
+                TestConfig(orientation, rtl, 10, 0, 0, 0),
+                TestConfig(orientation, rtl, 1, 2, 3, 4)
+            )
+        }
+    }
+}
+
+// endregion
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageChangeCallbackTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageChangeCallbackTest.kt
index da60cc2..cc4bb92 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageChangeCallbackTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageChangeCallbackTest.kt
@@ -40,7 +40,6 @@
 import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_IDLE
 import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_SETTLING
 import androidx.viewpager2.widget.swipe.PageSwiperManual
-import androidx.viewpager2.widget.swipe.ViewAdapter
 import org.hamcrest.CoreMatchers.equalTo
 import org.hamcrest.CoreMatchers.not
 import org.hamcrest.Matchers.allOf
@@ -60,8 +59,7 @@
 class PageChangeCallbackTest(private val config: TestConfig) : BaseTest() {
     data class TestConfig(
         @ViewPager2.Orientation val orientation: Int,
-        val rtl: Boolean,
-        val pageMarginPx: Int
+        val rtl: Boolean
     )
 
     companion object {
@@ -78,26 +76,6 @@
         }
     }
 
-    private val adapterProvider: AdapterProviderForItems get() {
-        return if (config.pageMarginPx > 0) {
-            { items -> { MarginViewAdapter(config.pageMarginPx, items) } }
-        } else {
-            { items -> { ViewAdapter(items) } }
-        }
-    }
-
-    class MarginViewAdapter(private val margin: Int, items: List<String>) : ViewAdapter(items) {
-        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
-            val viewHolder = super.onCreateViewHolder(parent, viewType)
-            val lp = viewHolder.itemView.layoutParams as ViewGroup.MarginLayoutParams
-            // Set unequal margins, to prevent symmetry from hiding bugs
-            // Similarly, make sure no margin is an exact multiple of another margin
-            lp.setMargins(margin * 2, margin * 3, margin * 7, margin * 5)
-            viewHolder.itemView.layoutParams = lp
-            return viewHolder
-        }
-    }
-
     /*
     Sample log to guide the test
 
@@ -131,7 +109,7 @@
     @Test
     fun test_swipeBetweenPages() {
         setUpTest(config.orientation).apply {
-            setAdapterSync(adapterProvider(stringSequence(4)))
+            setAdapterSync(viewAdapterProvider(stringSequence(4)))
             listOf(1, 2, 3, 2, 1, 0).forEach { targetPage ->
                 // given
                 val initialPage = viewPager.currentItem
@@ -194,7 +172,7 @@
 
         setUpTest(config.orientation).apply {
 
-            setAdapterSync(adapterProvider(stringSequence(totalPages)))
+            setAdapterSync(viewAdapterProvider(stringSequence(totalPages)))
             listOf(0, 0, 1, 2, 2, 2, 1, 2, 2, 2, 1, 0, 0, 0).forEach { targetPage ->
                 // given
                 val initialPage = viewPager.currentItem
@@ -257,7 +235,7 @@
     fun test_peekOnAdjacentPage_next() {
         // given
         setUpTest(config.orientation).apply {
-            setAdapterSync(adapterProvider(stringSequence(3)))
+            setAdapterSync(viewAdapterProvider(stringSequence(3)))
             val callback = viewPager.addNewRecordingCallback()
             val latch = viewPager.addWaitForScrolledLatch(0)
 
@@ -316,7 +294,7 @@
     fun test_peekOnAdjacentPage_previous() {
         // given
         setUpTest(config.orientation).apply {
-            setAdapterSync(adapterProvider(stringSequence(3)))
+            setAdapterSync(viewAdapterProvider(stringSequence(3)))
 
             viewPager.setCurrentItemSync(2, false, 1, SECONDS)
 
@@ -393,7 +371,7 @@
     fun test_selectItemProgrammatically_smoothScroll() {
         // given
         setUpTest(config.orientation).apply {
-            setAdapterSync(adapterProvider(stringSequence(1000)))
+            setAdapterSync(viewAdapterProvider(stringSequence(1000)))
 
             // when
             listOf(6, 5, 6, 3, 10, 0, 0, 999, 999, 0).forEach { targetPage ->
@@ -434,7 +412,7 @@
     fun test_multiplePageChanges() {
         // given
         setUpTest(config.orientation).apply {
-            setAdapterSync(adapterProvider(stringSequence(10)))
+            setAdapterSync(viewAdapterProvider(stringSequence(10)))
             val targetPages = listOf(4, 9)
             val callback = viewPager.addNewRecordingCallback()
             val latch = viewPager.addWaitForScrolledLatch(targetPages.last(), true)
@@ -484,7 +462,7 @@
     fun test_noSmoothScroll_after_smoothScroll() {
         // given
         setUpTest(config.orientation).apply {
-            setAdapterSync(adapterProvider(stringSequence(6)))
+            setAdapterSync(viewAdapterProvider(stringSequence(6)))
             val targetPage = 4
             val marker = 1
             val callback = viewPager.addNewRecordingCallback()
@@ -602,7 +580,7 @@
         // given
         assertThat(targetPage, greaterThanOrEqualTo(4))
         setUpTest(config.orientation).apply {
-            val adapterProvider = adapterProvider(stringSequence(5))
+            val adapterProvider = viewAdapterProvider(stringSequence(5))
             setAdapterSync(adapterProvider)
             val marker = 1
             val callback = viewPager.addNewRecordingCallback()
@@ -662,7 +640,7 @@
     fun test_selectItemProgrammatically_noSmoothScroll() {
         // given
         setUpTest(config.orientation).apply {
-            setAdapterSync(adapterProvider(stringSequence(3)))
+            setAdapterSync(viewAdapterProvider(stringSequence(3)))
 
             // when
             listOf(2, 2, 0, 0, 1, 2, 1, 0).forEach { targetPage ->
@@ -694,7 +672,7 @@
     fun test_swipeReleaseSwipeBack() {
         // given
         val test = setUpTest(config.orientation)
-        test.setAdapterSync(adapterProvider(stringSequence(3)))
+        test.setAdapterSync(viewAdapterProvider(stringSequence(3)))
         val currentPage = test.viewPager.currentItem
         val halfPage = test.viewPager.pageSize / 2f
         val pageSwiper = PageSwiperManual(test.viewPager)
@@ -768,7 +746,7 @@
     private fun test_selectItemProgrammatically_noCallback(smoothScroll: Boolean) {
         // given
         setUpTest(config.orientation).apply {
-            setAdapterSync(adapterProvider(stringSequence(3)))
+            setAdapterSync(viewAdapterProvider(stringSequence(3)))
 
             // when
             listOf(2, 2, 0, 0, 1, 2, 1, 0).forEach { targetPage ->
@@ -923,7 +901,7 @@
     private fun test_setCurrentItem_outOfBounds(smoothScroll: Boolean) {
         val test = setUpTest(config.orientation)
         val n = 3
-        test.setAdapterSync(adapterProvider(stringSequence(n)))
+        test.setAdapterSync(viewAdapterProvider(stringSequence(n)))
         val adapterCount = test.viewPager.adapter!!.itemCount
 
         listOf(-5, -1, n, n + 1, adapterCount, adapterCount + 1).forEach { targetPage ->
@@ -1199,10 +1177,8 @@
 
 private fun createTestSet(): List<TestConfig> {
     return listOf(ORIENTATION_HORIZONTAL, ORIENTATION_VERTICAL).flatMap { orientation ->
-        listOf(true, false).flatMap { rtl ->
-            listOf(0, 10, -10).map { margin ->
-                TestConfig(orientation, rtl, margin)
-            }
+        listOf(true, false).map { rtl ->
+            TestConfig(orientation, rtl)
         }
     }
 }
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageTransformerItemAnimatorTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageTransformerItemAnimatorTest.kt
new file mode 100644
index 0000000..8dc6458
--- /dev/null
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageTransformerItemAnimatorTest.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2019 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.viewpager2.widget
+
+import androidx.recyclerview.widget.DefaultItemAnimator
+import androidx.recyclerview.widget.RecyclerView
+import androidx.recyclerview.widget.RecyclerView.ItemAnimator
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
+import androidx.viewpager2.widget.ViewPager2.PageTransformer
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.CoreMatchers.not
+import org.hamcrest.CoreMatchers.notNullValue
+import org.hamcrest.CoreMatchers.nullValue
+import org.junit.Assert.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Tests that setting a transformer disables data-set change animations, and that those are restored
+ * when a transformer is removed.
+ */
+@RunWith(AndroidJUnit4::class)
+@LargeTest
+class PageTransformerItemAnimatorTest : BaseTest() {
+
+    @Test
+    fun test() {
+        setUpTest(ORIENTATION_HORIZONTAL).apply {
+            setAdapterSync(viewAdapterProviderValueId(stringSequence(5)))
+            assertBasicState(0)
+
+            val rv = viewPager.getChildAt(0) as RecyclerView
+            val animatorDefault = rv.itemAnimator as ItemAnimator
+            val animatorCustom = object : DefaultItemAnimator() {} as ItemAnimator
+            assertThat(animatorDefault, notNullValue())
+            assertThat(animatorDefault, not(equalTo(animatorCustom)))
+
+            val transformer1 = PageTransformer { _, _ -> }
+            val transformer2 = PageTransformer { _, _ -> }
+            val transformer3 = PageTransformer { _, _ -> }
+
+            runOnUiThreadSync {
+                assertThat(rv.itemAnimator, equalTo(animatorDefault))
+                viewPager.setPageTransformer(MarginPageTransformer(50))
+                assertThat(rv.itemAnimator, nullValue())
+
+                viewPager.setPageTransformer(transformer1)
+                assertThat(rv.itemAnimator, nullValue())
+
+                viewPager.setPageTransformer(null)
+                assertThat(rv.itemAnimator, equalTo(animatorDefault))
+
+                rv.itemAnimator = animatorCustom
+                viewPager.setPageTransformer(transformer2)
+                assertThat(rv.itemAnimator, nullValue())
+
+                viewPager.setPageTransformer(MarginPageTransformer(100))
+                assertThat(rv.itemAnimator, nullValue())
+
+                viewPager.setPageTransformer(CompositePageTransformer())
+                assertThat(rv.itemAnimator, nullValue())
+
+                viewPager.setPageTransformer(null)
+                assertThat(rv.itemAnimator, equalTo(animatorCustom))
+
+                viewPager.setPageTransformer(transformer3)
+                assertThat(rv.itemAnimator, nullValue())
+
+                viewPager.setPageTransformer(null)
+                assertThat(rv.itemAnimator, equalTo(animatorCustom))
+
+                viewPager.setPageTransformer(null)
+                assertThat(rv.itemAnimator, equalTo(animatorCustom))
+            }
+        }
+    }
+}
diff --git a/viewpager2/src/main/java/androidx/viewpager2/widget/ScrollEventAdapter.java b/viewpager2/src/main/java/androidx/viewpager2/widget/ScrollEventAdapter.java
index 456786f..f122b43 100644
--- a/viewpager2/src/main/java/androidx/viewpager2/widget/ScrollEventAdapter.java
+++ b/viewpager2/src/main/java/androidx/viewpager2/widget/ScrollEventAdapter.java
@@ -16,8 +16,6 @@
 
 package androidx.viewpager2.widget;
 
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-
 import static androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL;
 import static androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_DRAGGING;
 import static androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_IDLE;
@@ -27,6 +25,7 @@
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 import android.view.View;
+import android.view.ViewGroup.LayoutParams;
 import android.view.ViewGroup.MarginLayoutParams;
 
 import androidx.annotation.IntDef;
@@ -44,13 +43,6 @@
  * relative to the pages and exposes this position via ({@link #getRelativeScrollPosition()}.
  */
 final class ScrollEventAdapter extends RecyclerView.OnScrollListener {
-    private static final MarginLayoutParams ZERO_MARGIN_LAYOUT_PARAMS;
-
-    static {
-        ZERO_MARGIN_LAYOUT_PARAMS = new MarginLayoutParams(MATCH_PARENT, MATCH_PARENT);
-        ZERO_MARGIN_LAYOUT_PARAMS.setMargins(0, 0, 0, 0);
-    }
-
     /** @hide */
     @Retention(SOURCE)
     @IntDef({STATE_IDLE, STATE_IN_PROGRESS_MANUAL_DRAG, STATE_IN_PROGRESS_SMOOTH_SCROLL,
@@ -67,8 +59,9 @@
     private static final int NO_POSITION = -1;
 
     private OnPageChangeCallback mCallback;
-    private final @NonNull LinearLayoutManager mLayoutManager;
     private final @NonNull ViewPager2 mViewPager;
+    private final @NonNull RecyclerView mRecyclerView;
+    private final @NonNull LinearLayoutManager mLayoutManager;
 
     // state related fields
     private @AdapterState int mAdapterState;
@@ -82,8 +75,10 @@
     private boolean mFakeDragging;
 
     ScrollEventAdapter(@NonNull ViewPager2 viewPager) {
-        mLayoutManager = viewPager.mLayoutManager;
         mViewPager = viewPager;
+        mRecyclerView = mViewPager.mRecyclerView;
+        //noinspection ConstantConditions
+        mLayoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
         mScrollValues = new ScrollEventValues();
         resetState();
     }
@@ -239,24 +234,34 @@
             return;
         }
 
-        // TODO(123350297): automated test for this
-        MarginLayoutParams margin =
-                (firstVisibleView.getLayoutParams() instanceof MarginLayoutParams)
-                        ? (MarginLayoutParams) firstVisibleView.getLayoutParams()
-                        : ZERO_MARGIN_LAYOUT_PARAMS;
+        int leftDecorations = mLayoutManager.getLeftDecorationWidth(firstVisibleView);
+        int rightDecorations = mLayoutManager.getRightDecorationWidth(firstVisibleView);
+        int topDecorations = mLayoutManager.getTopDecorationHeight(firstVisibleView);
+        int bottomDecorations = mLayoutManager.getBottomDecorationHeight(firstVisibleView);
+
+        LayoutParams params = firstVisibleView.getLayoutParams();
+        if (params instanceof MarginLayoutParams) {
+            MarginLayoutParams margin = (MarginLayoutParams) params;
+            leftDecorations += margin.leftMargin;
+            rightDecorations += margin.rightMargin;
+            topDecorations += margin.topMargin;
+            bottomDecorations += margin.bottomMargin;
+        }
+
+        int decoratedHeight = firstVisibleView.getHeight() + topDecorations + bottomDecorations;
+        int decoratedWidth = firstVisibleView.getWidth() + leftDecorations + rightDecorations;
 
         boolean isHorizontal = mLayoutManager.getOrientation() == ORIENTATION_HORIZONTAL;
         int start, sizePx;
         if (isHorizontal) {
-            sizePx = firstVisibleView.getWidth() + margin.leftMargin + margin.rightMargin;
-            if (!mViewPager.isRtl()) {
-                start = firstVisibleView.getLeft() - margin.leftMargin;
-            } else {
-                start = sizePx - firstVisibleView.getRight() - margin.rightMargin;
+            sizePx = decoratedWidth;
+            start = firstVisibleView.getLeft() - leftDecorations - mRecyclerView.getPaddingLeft();
+            if (mViewPager.isRtl()) {
+                start = -start;
             }
         } else {
-            sizePx = firstVisibleView.getHeight() + margin.topMargin + margin.bottomMargin;
-            start = firstVisibleView.getTop() - margin.topMargin;
+            sizePx = decoratedHeight;
+            start = firstVisibleView.getTop() - topDecorations - mRecyclerView.getPaddingTop();
         }
 
         values.mOffsetPx = -start;
diff --git a/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java b/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java
index bd4247e..3bfaf3d 100644
--- a/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java
+++ b/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java
@@ -138,15 +138,17 @@
                 }
             };
 
-    LinearLayoutManager mLayoutManager;
+    private LinearLayoutManager mLayoutManager;
     private int mPendingCurrentItem = NO_POSITION;
     private Parcelable mPendingAdapterState;
-    private RecyclerView mRecyclerView;
+    RecyclerView mRecyclerView;
     private PagerSnapHelper mPagerSnapHelper;
     ScrollEventAdapter mScrollEventAdapter;
     private CompositeOnPageChangeCallback mPageChangeEventDispatcher;
     private FakeDrag mFakeDragger;
     private PageTransformerAdapter mPageTransformerAdapter;
+    private RecyclerView.ItemAnimator mSavedItemAnimator = null;
+    private boolean mSavedItemAnimatorPresent = false;
     private boolean mUserInputEnabled = true;
     private @OffscreenPageLimit int mOffscreenPageLimit = OFFSCREEN_PAGE_LIMIT_DEFAULT;
     AccessibilityProvider mAccessibilityProvider; // to avoid creation of a synthetic accessor
@@ -538,9 +540,10 @@
     }
 
     int getPageSize() {
+        final RecyclerView rv = mRecyclerView;
         return getOrientation() == ORIENTATION_HORIZONTAL
-                ? getWidth() - getPaddingLeft() - getPaddingRight()
-                : getHeight() - getPaddingTop() - getPaddingBottom();
+                ? rv.getWidth() - rv.getPaddingLeft() - rv.getPaddingRight()
+                : rv.getHeight() - rv.getPaddingTop() - rv.getPaddingBottom();
     }
 
     /**
@@ -860,6 +863,10 @@
      * Sets a {@link PageTransformer} that will be called for each attached page whenever the
      * scroll position is changed. This allows the application to apply custom property
      * transformations to each page, overriding the default sliding behavior.
+     * <p>
+     * Note: setting a {@link PageTransformer} disables data-set change animations to prevent
+     * conflicts between the two animation systems. Setting a {@code null} transformer will restore
+     * data-set change animations.
      *
      * @param transformer PageTransformer that will modify each page's animation properties
      *
@@ -867,6 +874,20 @@
      * @see CompositePageTransformer
      */
     public void setPageTransformer(@Nullable PageTransformer transformer) {
+        if (transformer != null) {
+            if (!mSavedItemAnimatorPresent) {
+                mSavedItemAnimator = mRecyclerView.getItemAnimator();
+                mSavedItemAnimatorPresent = true;
+            }
+            mRecyclerView.setItemAnimator(null);
+        } else {
+            if (mSavedItemAnimatorPresent) {
+                mRecyclerView.setItemAnimator(mSavedItemAnimator);
+                mSavedItemAnimator = null;
+                mSavedItemAnimatorPresent = false;
+            }
+        }
+
         // TODO: add support for reverseDrawingOrder: b/112892792
         // TODO: add support for pageLayerType: b/112893074
         if (transformer == mPageTransformerAdapter.getPageTransformer()) {
diff --git a/wear/api/api_lint.ignore b/wear/api/api_lint.ignore
index 6af38c4..de18302 100644
--- a/wear/api/api_lint.ignore
+++ b/wear/api/api_lint.ignore
@@ -21,6 +21,276 @@
     ConfirmationActivity should not extend `Activity`. Activity subclasses are impossible to compose. Expose a composable API instead.
 
 
+MissingNullability: androidx.wear.activity.ConfirmationActivity#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.wear.ambient.AmbientMode#attachAmbientSupport(T):
+    Missing nullability on method `attachAmbientSupport` return
+MissingNullability: androidx.wear.ambient.AmbientMode#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
+    Missing nullability on parameter `prefix` in method `dump`
+MissingNullability: androidx.wear.ambient.AmbientMode#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
+    Missing nullability on parameter `fd` in method `dump`
+MissingNullability: androidx.wear.ambient.AmbientMode#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2:
+    Missing nullability on parameter `writer` in method `dump`
+MissingNullability: androidx.wear.ambient.AmbientMode#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #3:
+    Missing nullability on parameter `args` in method `dump`
+MissingNullability: androidx.wear.ambient.AmbientMode#onAttach(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `onAttach`
+MissingNullability: androidx.wear.ambient.AmbientMode#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.wear.ambient.AmbientMode.AmbientCallback#onEnterAmbient(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `ambientDetails` in method `onEnterAmbient`
+MissingNullability: androidx.wear.ambient.AmbientMode.AmbientCallbackProvider#getAmbientCallback():
+    Missing nullability on method `getAmbientCallback` return
+MissingNullability: androidx.wear.ambient.AmbientModeSupport#attach(T):
+    Missing nullability on method `attach` return
+MissingNullability: androidx.wear.ambient.AmbientModeSupport#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
+    Missing nullability on parameter `prefix` in method `dump`
+MissingNullability: androidx.wear.ambient.AmbientModeSupport#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
+    Missing nullability on parameter `fd` in method `dump`
+MissingNullability: androidx.wear.ambient.AmbientModeSupport#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2:
+    Missing nullability on parameter `writer` in method `dump`
+MissingNullability: androidx.wear.ambient.AmbientModeSupport#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #3:
+    Missing nullability on parameter `args` in method `dump`
+MissingNullability: androidx.wear.ambient.AmbientModeSupport#onAttach(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `onAttach`
+MissingNullability: androidx.wear.ambient.AmbientModeSupport#onCreate(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
+MissingNullability: androidx.wear.ambient.AmbientModeSupport.AmbientCallback#onEnterAmbient(android.os.Bundle) parameter #0:
+    Missing nullability on parameter `ambientDetails` in method `onEnterAmbient`
+MissingNullability: androidx.wear.ambient.AmbientModeSupport.AmbientCallbackProvider#getAmbientCallback():
+    Missing nullability on method `getAmbientCallback` return
+MissingNullability: androidx.wear.utils.MetadataConstants#getPreviewDrawableResourceId(android.content.Context, boolean) parameter #0:
+    Missing nullability on parameter `context` in method `getPreviewDrawableResourceId`
+MissingNullability: androidx.wear.utils.MetadataConstants#isNotificationBridgingEnabled(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `isNotificationBridgingEnabled`
+MissingNullability: androidx.wear.utils.MetadataConstants#isStandalone(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `isStandalone`
+MissingNullability: androidx.wear.widget.BoxInsetLayout#checkLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `checkLayoutParams`
+MissingNullability: androidx.wear.widget.BoxInsetLayout#generateLayoutParams(android.util.AttributeSet):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.wear.widget.BoxInsetLayout#generateLayoutParams(android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `attrs` in method `generateLayoutParams`
+MissingNullability: androidx.wear.widget.BoxInsetLayout#generateLayoutParams(android.view.ViewGroup.LayoutParams):
+    Missing nullability on method `generateLayoutParams` return
+MissingNullability: androidx.wear.widget.BoxInsetLayout#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `p` in method `generateLayoutParams`
+MissingNullability: androidx.wear.widget.BoxInsetLayout#setForeground(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `drawable` in method `setForeground`
+MissingNullability: androidx.wear.widget.CircularProgressLayout#CircularProgressLayout(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `CircularProgressLayout`
+MissingNullability: androidx.wear.widget.CircularProgressLayout#CircularProgressLayout(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `CircularProgressLayout`
+MissingNullability: androidx.wear.widget.CircularProgressLayout#CircularProgressLayout(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `CircularProgressLayout`
+MissingNullability: androidx.wear.widget.CircularProgressLayout#CircularProgressLayout(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `CircularProgressLayout`
+MissingNullability: androidx.wear.widget.CircularProgressLayout#CircularProgressLayout(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `CircularProgressLayout`
+MissingNullability: androidx.wear.widget.CircularProgressLayout#CircularProgressLayout(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `CircularProgressLayout`
+MissingNullability: androidx.wear.widget.CircularProgressLayout#CircularProgressLayout(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `CircularProgressLayout`
+MissingNullability: androidx.wear.widget.CircularProgressLayout#getColorSchemeColors():
+    Missing nullability on method `getColorSchemeColors` return
+MissingNullability: androidx.wear.widget.CircularProgressLayout#setColorSchemeColors(int...) parameter #0:
+    Missing nullability on parameter `colors` in method `setColorSchemeColors`
+MissingNullability: androidx.wear.widget.CircularProgressLayout.OnTimerFinishedListener#onTimerFinished(androidx.wear.widget.CircularProgressLayout) parameter #0:
+    Missing nullability on parameter `layout` in method `onTimerFinished`
+MissingNullability: androidx.wear.widget.ConfirmationOverlay#setDuration(int):
+    Missing nullability on method `setDuration` return
+MissingNullability: androidx.wear.widget.ConfirmationOverlay#setFinishedAnimationListener(androidx.wear.widget.ConfirmationOverlay.OnAnimationFinishedListener):
+    Missing nullability on method `setFinishedAnimationListener` return
+MissingNullability: androidx.wear.widget.ConfirmationOverlay#setMessage(String):
+    Missing nullability on method `setMessage` return
+MissingNullability: androidx.wear.widget.ConfirmationOverlay#setMessage(String) parameter #0:
+    Missing nullability on parameter `message` in method `setMessage`
+MissingNullability: androidx.wear.widget.ConfirmationOverlay#setType(int):
+    Missing nullability on method `setType` return
+MissingNullability: androidx.wear.widget.ConfirmationOverlay#showAbove(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `showAbove`
+MissingNullability: androidx.wear.widget.ConfirmationOverlay#showOn(android.app.Activity) parameter #0:
+    Missing nullability on parameter `activity` in method `showOn`
+MissingNullability: androidx.wear.widget.CurvingLayoutCallback#CurvingLayoutCallback(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `CurvingLayoutCallback`
+MissingNullability: androidx.wear.widget.CurvingLayoutCallback#adjustAnchorOffsetXY(android.view.View, float[]) parameter #0:
+    Missing nullability on parameter `child` in method `adjustAnchorOffsetXY`
+MissingNullability: androidx.wear.widget.CurvingLayoutCallback#adjustAnchorOffsetXY(android.view.View, float[]) parameter #1:
+    Missing nullability on parameter `anchorOffsetXY` in method `adjustAnchorOffsetXY`
+MissingNullability: androidx.wear.widget.CurvingLayoutCallback#onLayoutFinished(android.view.View, androidx.recyclerview.widget.RecyclerView) parameter #0:
+    Missing nullability on parameter `child` in method `onLayoutFinished`
+MissingNullability: androidx.wear.widget.CurvingLayoutCallback#onLayoutFinished(android.view.View, androidx.recyclerview.widget.RecyclerView) parameter #1:
+    Missing nullability on parameter `parent` in method `onLayoutFinished`
+MissingNullability: androidx.wear.widget.RoundedDrawable#onBoundsChange(android.graphics.Rect) parameter #0:
+    Missing nullability on parameter `bounds` in method `onBoundsChange`
+MissingNullability: androidx.wear.widget.RoundedDrawable#setColorFilter(android.graphics.ColorFilter) parameter #0:
+    Missing nullability on parameter `cf` in method `setColorFilter`
+MissingNullability: androidx.wear.widget.SwipeDismissFrameLayout#SwipeDismissFrameLayout(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `SwipeDismissFrameLayout`
+MissingNullability: androidx.wear.widget.SwipeDismissFrameLayout#SwipeDismissFrameLayout(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `SwipeDismissFrameLayout`
+MissingNullability: androidx.wear.widget.SwipeDismissFrameLayout#SwipeDismissFrameLayout(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `SwipeDismissFrameLayout`
+MissingNullability: androidx.wear.widget.SwipeDismissFrameLayout#SwipeDismissFrameLayout(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `SwipeDismissFrameLayout`
+MissingNullability: androidx.wear.widget.SwipeDismissFrameLayout#SwipeDismissFrameLayout(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `SwipeDismissFrameLayout`
+MissingNullability: androidx.wear.widget.SwipeDismissFrameLayout#SwipeDismissFrameLayout(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `SwipeDismissFrameLayout`
+MissingNullability: androidx.wear.widget.SwipeDismissFrameLayout#SwipeDismissFrameLayout(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `SwipeDismissFrameLayout`
+MissingNullability: androidx.wear.widget.SwipeDismissFrameLayout#addCallback(androidx.wear.widget.SwipeDismissFrameLayout.Callback) parameter #0:
+    Missing nullability on parameter `callback` in method `addCallback`
+MissingNullability: androidx.wear.widget.SwipeDismissFrameLayout#removeCallback(androidx.wear.widget.SwipeDismissFrameLayout.Callback) parameter #0:
+    Missing nullability on parameter `callback` in method `removeCallback`
+MissingNullability: androidx.wear.widget.SwipeDismissFrameLayout.Callback#onDismissed(androidx.wear.widget.SwipeDismissFrameLayout) parameter #0:
+    Missing nullability on parameter `layout` in method `onDismissed`
+MissingNullability: androidx.wear.widget.SwipeDismissFrameLayout.Callback#onSwipeCanceled(androidx.wear.widget.SwipeDismissFrameLayout) parameter #0:
+    Missing nullability on parameter `layout` in method `onSwipeCanceled`
+MissingNullability: androidx.wear.widget.SwipeDismissFrameLayout.Callback#onSwipeStarted(androidx.wear.widget.SwipeDismissFrameLayout) parameter #0:
+    Missing nullability on parameter `layout` in method `onSwipeStarted`
+MissingNullability: androidx.wear.widget.WearableLinearLayoutManager#WearableLinearLayoutManager(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `WearableLinearLayoutManager`
+MissingNullability: androidx.wear.widget.WearableLinearLayoutManager#WearableLinearLayoutManager(android.content.Context, androidx.wear.widget.WearableLinearLayoutManager.LayoutCallback) parameter #0:
+    Missing nullability on parameter `context` in method `WearableLinearLayoutManager`
+MissingNullability: androidx.wear.widget.WearableLinearLayoutManager#WearableLinearLayoutManager(android.content.Context, androidx.wear.widget.WearableLinearLayoutManager.LayoutCallback) parameter #1:
+    Missing nullability on parameter `layoutCallback` in method `WearableLinearLayoutManager`
+MissingNullability: androidx.wear.widget.WearableLinearLayoutManager#onLayoutChildren(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #0:
+    Missing nullability on parameter `recycler` in method `onLayoutChildren`
+MissingNullability: androidx.wear.widget.WearableLinearLayoutManager#onLayoutChildren(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `state` in method `onLayoutChildren`
+MissingNullability: androidx.wear.widget.WearableLinearLayoutManager#scrollVerticallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #1:
+    Missing nullability on parameter `recycler` in method `scrollVerticallyBy`
+MissingNullability: androidx.wear.widget.WearableLinearLayoutManager#scrollVerticallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State) parameter #2:
+    Missing nullability on parameter `state` in method `scrollVerticallyBy`
+MissingNullability: androidx.wear.widget.WearableLinearLayoutManager.LayoutCallback#onLayoutFinished(android.view.View, androidx.recyclerview.widget.RecyclerView) parameter #0:
+    Missing nullability on parameter `child` in method `onLayoutFinished`
+MissingNullability: androidx.wear.widget.WearableLinearLayoutManager.LayoutCallback#onLayoutFinished(android.view.View, androidx.recyclerview.widget.RecyclerView) parameter #1:
+    Missing nullability on parameter `parent` in method `onLayoutFinished`
+MissingNullability: androidx.wear.widget.WearableRecyclerView#WearableRecyclerView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `WearableRecyclerView`
+MissingNullability: androidx.wear.widget.WearableRecyclerView#WearableRecyclerView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `WearableRecyclerView`
+MissingNullability: androidx.wear.widget.WearableRecyclerView#WearableRecyclerView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `WearableRecyclerView`
+MissingNullability: androidx.wear.widget.WearableRecyclerView#WearableRecyclerView(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `WearableRecyclerView`
+MissingNullability: androidx.wear.widget.WearableRecyclerView#onTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `event` in method `onTouchEvent`
+MissingNullability: androidx.wear.widget.drawer.WearableActionDrawerView#WearableActionDrawerView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `WearableActionDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableActionDrawerView#WearableActionDrawerView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `WearableActionDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableActionDrawerView#WearableActionDrawerView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `WearableActionDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableActionDrawerView#WearableActionDrawerView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `WearableActionDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableActionDrawerView#WearableActionDrawerView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `WearableActionDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableActionDrawerView#WearableActionDrawerView(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `WearableActionDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableActionDrawerView#WearableActionDrawerView(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `WearableActionDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableActionDrawerView#getMenu():
+    Missing nullability on method `getMenu` return
+MissingNullability: androidx.wear.widget.drawer.WearableActionDrawerView#onPeekContainerClicked(android.view.View) parameter #0:
+    Missing nullability on parameter `v` in method `onPeekContainerClicked`
+MissingNullability: androidx.wear.widget.drawer.WearableActionDrawerView#setOnMenuItemClickListener(android.view.MenuItem.OnMenuItemClickListener) parameter #0:
+    Missing nullability on parameter `listener` in method `setOnMenuItemClickListener`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout#WearableDrawerLayout(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `WearableDrawerLayout`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout#WearableDrawerLayout(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `WearableDrawerLayout`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout#WearableDrawerLayout(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `WearableDrawerLayout`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout#WearableDrawerLayout(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `WearableDrawerLayout`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout#WearableDrawerLayout(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `WearableDrawerLayout`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout#WearableDrawerLayout(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `WearableDrawerLayout`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout#WearableDrawerLayout(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `WearableDrawerLayout`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout#addView(android.view.View, int, android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `child` in method `addView`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout#addView(android.view.View, int, android.view.ViewGroup.LayoutParams) parameter #2:
+    Missing nullability on parameter `params` in method `addView`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout#onApplyWindowInsets(android.view.WindowInsets):
+    Missing nullability on method `onApplyWindowInsets` return
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout#onApplyWindowInsets(android.view.WindowInsets) parameter #0:
+    Missing nullability on parameter `insets` in method `onApplyWindowInsets`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout#onFlingComplete(android.view.View) parameter #0:
+    Missing nullability on parameter `view` in method `onFlingComplete`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onInterceptTouchEvent`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout#onLayoutChange(android.view.View, int, int, int, int, int, int, int, int) parameter #0:
+    Missing nullability on parameter `v` in method `onLayoutChange`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout#onTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onTouchEvent`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout#setDrawerStateCallback(androidx.wear.widget.drawer.WearableDrawerLayout.DrawerStateCallback) parameter #0:
+    Missing nullability on parameter `callback` in method `setDrawerStateCallback`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout.DrawerStateCallback#onDrawerClosed(androidx.wear.widget.drawer.WearableDrawerLayout, androidx.wear.widget.drawer.WearableDrawerView) parameter #0:
+    Missing nullability on parameter `layout` in method `onDrawerClosed`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout.DrawerStateCallback#onDrawerClosed(androidx.wear.widget.drawer.WearableDrawerLayout, androidx.wear.widget.drawer.WearableDrawerView) parameter #1:
+    Missing nullability on parameter `drawerView` in method `onDrawerClosed`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout.DrawerStateCallback#onDrawerOpened(androidx.wear.widget.drawer.WearableDrawerLayout, androidx.wear.widget.drawer.WearableDrawerView) parameter #0:
+    Missing nullability on parameter `layout` in method `onDrawerOpened`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout.DrawerStateCallback#onDrawerOpened(androidx.wear.widget.drawer.WearableDrawerLayout, androidx.wear.widget.drawer.WearableDrawerView) parameter #1:
+    Missing nullability on parameter `drawerView` in method `onDrawerOpened`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerLayout.DrawerStateCallback#onDrawerStateChanged(androidx.wear.widget.drawer.WearableDrawerLayout, int) parameter #0:
+    Missing nullability on parameter `layout` in method `onDrawerStateChanged`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerView#WearableDrawerView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `WearableDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerView#WearableDrawerView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `WearableDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerView#WearableDrawerView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `WearableDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerView#WearableDrawerView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `WearableDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerView#WearableDrawerView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `WearableDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerView#WearableDrawerView(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `WearableDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerView#WearableDrawerView(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `WearableDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerView#addView(android.view.View, int, android.view.ViewGroup.LayoutParams) parameter #0:
+    Missing nullability on parameter `child` in method `addView`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerView#addView(android.view.View, int, android.view.ViewGroup.LayoutParams) parameter #2:
+    Missing nullability on parameter `params` in method `addView`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerView#getController():
+    Missing nullability on method `getController` return
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerView#onPeekContainerClicked(android.view.View) parameter #0:
+    Missing nullability on parameter `v` in method `onPeekContainerClicked`
+MissingNullability: androidx.wear.widget.drawer.WearableDrawerView#setPeekContent(android.view.View) parameter #0:
+    Missing nullability on parameter `content` in method `setPeekContent`
+MissingNullability: androidx.wear.widget.drawer.WearableNavigationDrawerView#WearableNavigationDrawerView(android.content.Context) parameter #0:
+    Missing nullability on parameter `context` in method `WearableNavigationDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableNavigationDrawerView#WearableNavigationDrawerView(android.content.Context, android.util.AttributeSet) parameter #0:
+    Missing nullability on parameter `context` in method `WearableNavigationDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableNavigationDrawerView#WearableNavigationDrawerView(android.content.Context, android.util.AttributeSet) parameter #1:
+    Missing nullability on parameter `attrs` in method `WearableNavigationDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableNavigationDrawerView#WearableNavigationDrawerView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+    Missing nullability on parameter `context` in method `WearableNavigationDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableNavigationDrawerView#WearableNavigationDrawerView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `WearableNavigationDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableNavigationDrawerView#WearableNavigationDrawerView(android.content.Context, android.util.AttributeSet, int, int) parameter #0:
+    Missing nullability on parameter `context` in method `WearableNavigationDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableNavigationDrawerView#WearableNavigationDrawerView(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
+    Missing nullability on parameter `attrs` in method `WearableNavigationDrawerView`
+MissingNullability: androidx.wear.widget.drawer.WearableNavigationDrawerView#addOnItemSelectedListener(androidx.wear.widget.drawer.WearableNavigationDrawerView.OnItemSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `addOnItemSelectedListener`
+MissingNullability: androidx.wear.widget.drawer.WearableNavigationDrawerView#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
+    Missing nullability on parameter `ev` in method `onInterceptTouchEvent`
+MissingNullability: androidx.wear.widget.drawer.WearableNavigationDrawerView#removeOnItemSelectedListener(androidx.wear.widget.drawer.WearableNavigationDrawerView.OnItemSelectedListener) parameter #0:
+    Missing nullability on parameter `listener` in method `removeOnItemSelectedListener`
+MissingNullability: androidx.wear.widget.drawer.WearableNavigationDrawerView#setAdapter(androidx.wear.widget.drawer.WearableNavigationDrawerView.WearableNavigationDrawerAdapter) parameter #0:
+    Missing nullability on parameter `adapter` in method `setAdapter`
+MissingNullability: androidx.wear.widget.drawer.WearableNavigationDrawerView.WearableNavigationDrawerAdapter#getItemDrawable(int):
+    Missing nullability on method `getItemDrawable` return
+MissingNullability: androidx.wear.widget.drawer.WearableNavigationDrawerView.WearableNavigationDrawerAdapter#getItemText(int):
+    Missing nullability on method `getItemText` return
+
+
 NoClone: androidx.wear.ambient.AmbientMode#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
     Must use ParcelFileDescriptor instead of FileDescriptor in parameter fd in androidx.wear.ambient.AmbientMode.dump(String prefix, java.io.FileDescriptor fd, java.io.PrintWriter writer, String[] args)
 NoClone: androidx.wear.ambient.AmbientModeSupport#dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
diff --git a/webkit/api/1.1.0-alpha02.txt b/webkit/api/1.1.0-alpha02.txt
index 7242db2..44938cf 100644
--- a/webkit/api/1.1.0-alpha02.txt
+++ b/webkit/api/1.1.0-alpha02.txt
@@ -143,6 +143,11 @@
     method public androidx.webkit.WebViewAssetLoader.Builder setHttpAllowed(boolean);
   }
 
+  public static final class WebViewAssetLoader.InternalStoragePathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+    ctor public WebViewAssetLoader.InternalStoragePathHandler(android.content.Context, java.io.File);
+    method @WorkerThread public android.webkit.WebResourceResponse handle(String);
+  }
+
   public static interface WebViewAssetLoader.PathHandler {
     method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
   }
diff --git a/webkit/api/1.1.0-alpha03.txt b/webkit/api/1.1.0-alpha03.txt
new file mode 100644
index 0000000..2936afa
--- /dev/null
+++ b/webkit/api/1.1.0-alpha03.txt
@@ -0,0 +1,245 @@
+// Signature format: 3.0
+package androidx.webkit {
+
+  public final class ProxyConfig {
+    method public java.util.List<java.lang.String!> getBypassRules();
+    method public java.util.List<androidx.webkit.ProxyConfig.ProxyRule!> getProxyRules();
+    field public static final String MATCH_ALL_SCHEMES = "*";
+    field public static final String MATCH_HTTP = "http";
+    field public static final String MATCH_HTTPS = "https";
+  }
+
+  public static final class ProxyConfig.Builder {
+    ctor public ProxyConfig.Builder();
+    ctor public ProxyConfig.Builder(androidx.webkit.ProxyConfig);
+    method public androidx.webkit.ProxyConfig.Builder addBypassRule(String);
+    method public androidx.webkit.ProxyConfig.Builder addDirect(String);
+    method public androidx.webkit.ProxyConfig.Builder addDirect();
+    method public androidx.webkit.ProxyConfig.Builder addProxyRule(String);
+    method public androidx.webkit.ProxyConfig.Builder addProxyRule(String, String);
+    method public androidx.webkit.ProxyConfig build();
+    method public androidx.webkit.ProxyConfig.Builder bypassSimpleHostnames();
+    method public androidx.webkit.ProxyConfig.Builder removeImplicitRules();
+  }
+
+  public static final class ProxyConfig.ProxyRule {
+    method public String getSchemeFilter();
+    method public String getUrl();
+  }
+
+  public abstract class ProxyController {
+    method public abstract void clearProxyOverride(java.util.concurrent.Executor, Runnable);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.PROXY_OVERRIDE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ProxyController getInstance();
+    method public abstract void setProxyOverride(androidx.webkit.ProxyConfig, java.util.concurrent.Executor, Runnable);
+  }
+
+  public abstract class SafeBrowsingResponseCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void backToSafety(boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void proceed(boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void showInterstitial(boolean);
+  }
+
+  public abstract class ServiceWorkerClientCompat {
+    ctor public ServiceWorkerClientCompat();
+    method @WorkerThread public abstract android.webkit.WebResourceResponse? shouldInterceptRequest(android.webkit.WebResourceRequest);
+  }
+
+  public abstract class ServiceWorkerControllerCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ServiceWorkerControllerCompat getInstance();
+    method public abstract androidx.webkit.ServiceWorkerWebSettingsCompat getServiceWorkerWebSettings();
+    method public abstract void setServiceWorkerClient(androidx.webkit.ServiceWorkerClientCompat?);
+  }
+
+  public abstract class ServiceWorkerWebSettingsCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowContentAccess();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowFileAccess();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getBlockNetworkLoads();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getCacheMode();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowContentAccess(boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowFileAccess(boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setBlockNetworkLoads(boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setCacheMode(int);
+  }
+
+  public class TracingConfig {
+    method public java.util.List<java.lang.String!> getCustomIncludedCategories();
+    method public int getPredefinedCategories();
+    method public int getTracingMode();
+    field public static final int CATEGORIES_ALL = 1; // 0x1
+    field public static final int CATEGORIES_ANDROID_WEBVIEW = 2; // 0x2
+    field public static final int CATEGORIES_FRAME_VIEWER = 64; // 0x40
+    field public static final int CATEGORIES_INPUT_LATENCY = 8; // 0x8
+    field public static final int CATEGORIES_JAVASCRIPT_AND_RENDERING = 32; // 0x20
+    field public static final int CATEGORIES_NONE = 0; // 0x0
+    field public static final int CATEGORIES_RENDERING = 16; // 0x10
+    field public static final int CATEGORIES_WEB_DEVELOPER = 4; // 0x4
+    field public static final int RECORD_CONTINUOUSLY = 1; // 0x1
+    field public static final int RECORD_UNTIL_FULL = 0; // 0x0
+  }
+
+  public static class TracingConfig.Builder {
+    ctor public TracingConfig.Builder();
+    method public androidx.webkit.TracingConfig.Builder addCategories(int...);
+    method public androidx.webkit.TracingConfig.Builder addCategories(java.lang.String!...);
+    method public androidx.webkit.TracingConfig.Builder addCategories(java.util.Collection<java.lang.String!>);
+    method public androidx.webkit.TracingConfig build();
+    method public androidx.webkit.TracingConfig.Builder setTracingMode(int);
+  }
+
+  public abstract class TracingController {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.TRACING_CONTROLLER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.TracingController getInstance();
+    method public abstract boolean isTracing();
+    method public abstract void start(androidx.webkit.TracingConfig);
+    method public abstract boolean stop(java.io.OutputStream?, java.util.concurrent.Executor);
+  }
+
+  public class WebMessageCompat {
+    ctor public WebMessageCompat(String?);
+    ctor public WebMessageCompat(String?, androidx.webkit.WebMessagePortCompat![]?);
+    method public String? getData();
+    method public androidx.webkit.WebMessagePortCompat![]? getPorts();
+  }
+
+  public abstract class WebMessagePortCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_CLOSE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void close();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_POST_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(androidx.webkit.WebMessageCompat);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(android.os.Handler?, androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
+  }
+
+  public abstract static class WebMessagePortCompat.WebMessageCallbackCompat {
+    ctor public WebMessagePortCompat.WebMessageCallbackCompat();
+    method public void onMessage(androidx.webkit.WebMessagePortCompat, androidx.webkit.WebMessageCompat?);
+  }
+
+  public abstract class WebResourceErrorCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract CharSequence getDescription();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getErrorCode();
+  }
+
+  public class WebResourceRequestCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isRedirect(android.webkit.WebResourceRequest);
+  }
+
+  public class WebSettingsCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getDisabledActionModeMenuItems(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getOffscreenPreRaster(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getSafeBrowsingEnabled(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setDisabledActionModeMenuItems(android.webkit.WebSettings, int);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setOffscreenPreRaster(android.webkit.WebSettings, boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingEnabled(android.webkit.WebSettings, boolean);
+  }
+
+  public final class WebViewAssetLoader {
+    method @WorkerThread public android.webkit.WebResourceResponse? shouldInterceptRequest(android.net.Uri);
+    field public static final String DEFAULT_DOMAIN = "appassets.androidplatform.net";
+  }
+
+  public static final class WebViewAssetLoader.AssetsPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+    ctor public WebViewAssetLoader.AssetsPathHandler(android.content.Context);
+    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+  }
+
+  public static final class WebViewAssetLoader.Builder {
+    ctor public WebViewAssetLoader.Builder();
+    method public androidx.webkit.WebViewAssetLoader.Builder addPathHandler(String, androidx.webkit.WebViewAssetLoader.PathHandler);
+    method public androidx.webkit.WebViewAssetLoader build();
+    method public androidx.webkit.WebViewAssetLoader.Builder setDomain(String);
+    method public androidx.webkit.WebViewAssetLoader.Builder setHttpAllowed(boolean);
+  }
+
+  public static final class WebViewAssetLoader.InternalStoragePathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+    ctor public WebViewAssetLoader.InternalStoragePathHandler(android.content.Context, java.io.File);
+    method @WorkerThread public android.webkit.WebResourceResponse handle(String);
+  }
+
+  public static interface WebViewAssetLoader.PathHandler {
+    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+  }
+
+  public static final class WebViewAssetLoader.ResourcesPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+    ctor public WebViewAssetLoader.ResourcesPathHandler(android.content.Context);
+    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+  }
+
+  public class WebViewClientCompat extends android.webkit.WebViewClient {
+    ctor public WebViewClientCompat();
+    method @RequiresApi(23) public final void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceError);
+    method @RequiresApi(21) @UiThread public void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, androidx.webkit.WebResourceErrorCompat);
+    method @RequiresApi(27) public final void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, android.webkit.SafeBrowsingResponse);
+    method @UiThread public void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, androidx.webkit.SafeBrowsingResponseCompat);
+  }
+
+  public class WebViewCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebMessagePortCompat![] createWebMessageChannel(android.webkit.WebView);
+    method public static android.content.pm.PackageInfo? getCurrentWebViewPackage(android.content.Context);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.net.Uri getSafeBrowsingPrivacyPolicyUrl();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_CHROME_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebChromeClient? getWebChromeClient(android.webkit.WebView);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebViewClient getWebViewClient(android.webkit.WebView);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_RENDERER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcess? getWebViewRenderProcess(android.webkit.WebView);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcessClient? getWebViewRenderProcessClient(android.webkit.WebView);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.VISUAL_STATE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postVisualStateCallback(android.webkit.WebView, long, androidx.webkit.WebViewCompat.VisualStateCallback);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.POST_WEB_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postWebMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_WHITELIST, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingWhitelist(java.util.List<java.lang.String!>, android.webkit.ValueCallback<java.lang.Boolean!>?);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, java.util.concurrent.Executor, androidx.webkit.WebViewRenderProcessClient);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, androidx.webkit.WebViewRenderProcessClient?);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.START_SAFE_BROWSING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void startSafeBrowsing(android.content.Context, android.webkit.ValueCallback<java.lang.Boolean!>?);
+  }
+
+  public static interface WebViewCompat.VisualStateCallback {
+    method @UiThread public void onComplete(long);
+  }
+
+  public class WebViewFeature {
+    method public static boolean isFeatureSupported(String);
+    field public static final String CREATE_WEB_MESSAGE_CHANNEL = "CREATE_WEB_MESSAGE_CHANNEL";
+    field public static final String DISABLED_ACTION_MODE_MENU_ITEMS = "DISABLED_ACTION_MODE_MENU_ITEMS";
+    field public static final String GET_WEB_CHROME_CLIENT = "GET_WEB_CHROME_CLIENT";
+    field public static final String GET_WEB_VIEW_CLIENT = "GET_WEB_VIEW_CLIENT";
+    field public static final String GET_WEB_VIEW_RENDERER = "GET_WEB_VIEW_RENDERER";
+    field public static final String OFF_SCREEN_PRERASTER = "OFF_SCREEN_PRERASTER";
+    field public static final String POST_WEB_MESSAGE = "POST_WEB_MESSAGE";
+    field public static final String PROXY_OVERRIDE = "PROXY_OVERRIDE";
+    field public static final String RECEIVE_HTTP_ERROR = "RECEIVE_HTTP_ERROR";
+    field public static final String RECEIVE_WEB_RESOURCE_ERROR = "RECEIVE_WEB_RESOURCE_ERROR";
+    field public static final String SAFE_BROWSING_ENABLE = "SAFE_BROWSING_ENABLE";
+    field public static final String SAFE_BROWSING_HIT = "SAFE_BROWSING_HIT";
+    field public static final String SAFE_BROWSING_PRIVACY_POLICY_URL = "SAFE_BROWSING_PRIVACY_POLICY_URL";
+    field public static final String SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY = "SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY";
+    field public static final String SAFE_BROWSING_RESPONSE_PROCEED = "SAFE_BROWSING_RESPONSE_PROCEED";
+    field public static final String SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL = "SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL";
+    field public static final String SAFE_BROWSING_WHITELIST = "SAFE_BROWSING_WHITELIST";
+    field public static final String SERVICE_WORKER_BASIC_USAGE = "SERVICE_WORKER_BASIC_USAGE";
+    field public static final String SERVICE_WORKER_BLOCK_NETWORK_LOADS = "SERVICE_WORKER_BLOCK_NETWORK_LOADS";
+    field public static final String SERVICE_WORKER_CACHE_MODE = "SERVICE_WORKER_CACHE_MODE";
+    field public static final String SERVICE_WORKER_CONTENT_ACCESS = "SERVICE_WORKER_CONTENT_ACCESS";
+    field public static final String SERVICE_WORKER_FILE_ACCESS = "SERVICE_WORKER_FILE_ACCESS";
+    field public static final String SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST = "SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST";
+    field public static final String SHOULD_OVERRIDE_WITH_REDIRECTS = "SHOULD_OVERRIDE_WITH_REDIRECTS";
+    field public static final String START_SAFE_BROWSING = "START_SAFE_BROWSING";
+    field public static final String TRACING_CONTROLLER_BASIC_USAGE = "TRACING_CONTROLLER_BASIC_USAGE";
+    field public static final String VISUAL_STATE_CALLBACK = "VISUAL_STATE_CALLBACK";
+    field public static final String WEB_MESSAGE_CALLBACK_ON_MESSAGE = "WEB_MESSAGE_CALLBACK_ON_MESSAGE";
+    field public static final String WEB_MESSAGE_PORT_CLOSE = "WEB_MESSAGE_PORT_CLOSE";
+    field public static final String WEB_MESSAGE_PORT_POST_MESSAGE = "WEB_MESSAGE_PORT_POST_MESSAGE";
+    field public static final String WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK = "WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK";
+    field public static final String WEB_RESOURCE_ERROR_GET_CODE = "WEB_RESOURCE_ERROR_GET_CODE";
+    field public static final String WEB_RESOURCE_ERROR_GET_DESCRIPTION = "WEB_RESOURCE_ERROR_GET_DESCRIPTION";
+    field public static final String WEB_RESOURCE_REQUEST_IS_REDIRECT = "WEB_RESOURCE_REQUEST_IS_REDIRECT";
+    field public static final String WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE = "WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE";
+    field public static final String WEB_VIEW_RENDERER_TERMINATE = "WEB_VIEW_RENDERER_TERMINATE";
+  }
+
+  public abstract class WebViewRenderProcess {
+    ctor public WebViewRenderProcess();
+    method public abstract boolean terminate();
+  }
+
+  public abstract class WebViewRenderProcessClient {
+    ctor public WebViewRenderProcessClient();
+    method public abstract void onRenderProcessResponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
+    method public abstract void onRenderProcessUnresponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
+  }
+
+}
+
diff --git a/webkit/api/current.txt b/webkit/api/current.txt
index 7242db2..2936afa 100644
--- a/webkit/api/current.txt
+++ b/webkit/api/current.txt
@@ -3,7 +3,7 @@
 
   public final class ProxyConfig {
     method public java.util.List<java.lang.String!> getBypassRules();
-    method public java.util.List<androidx.core.util.Pair<java.lang.String!,java.lang.String!>!> getProxyRules();
+    method public java.util.List<androidx.webkit.ProxyConfig.ProxyRule!> getProxyRules();
     field public static final String MATCH_ALL_SCHEMES = "*";
     field public static final String MATCH_HTTP = "http";
     field public static final String MATCH_HTTPS = "https";
@@ -22,6 +22,11 @@
     method public androidx.webkit.ProxyConfig.Builder removeImplicitRules();
   }
 
+  public static final class ProxyConfig.ProxyRule {
+    method public String getSchemeFilter();
+    method public String getUrl();
+  }
+
   public abstract class ProxyController {
     method public abstract void clearProxyOverride(java.util.concurrent.Executor, Runnable);
     method @RequiresFeature(name=androidx.webkit.WebViewFeature.PROXY_OVERRIDE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ProxyController getInstance();
@@ -143,6 +148,11 @@
     method public androidx.webkit.WebViewAssetLoader.Builder setHttpAllowed(boolean);
   }
 
+  public static final class WebViewAssetLoader.InternalStoragePathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+    ctor public WebViewAssetLoader.InternalStoragePathHandler(android.content.Context, java.io.File);
+    method @WorkerThread public android.webkit.WebResourceResponse handle(String);
+  }
+
   public static interface WebViewAssetLoader.PathHandler {
     method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
   }
diff --git a/preference/ktx/api/res-1.1.0-alpha03.txt b/webkit/api/res-1.1.0-alpha03.txt
similarity index 100%
copy from preference/ktx/api/res-1.1.0-alpha03.txt
copy to webkit/api/res-1.1.0-alpha03.txt
diff --git a/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/ForceDarkActivity.java b/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/ForceDarkActivity.java
index aa8531b..37600b6 100644
--- a/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/ForceDarkActivity.java
+++ b/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/ForceDarkActivity.java
@@ -27,11 +27,6 @@
 import androidx.webkit.WebSettingsCompat;
 import androidx.webkit.WebViewFeature;
 
-// TODO(amalova): enable the following attributes once Q SDK is available.
-// <item name="android:forceDarkAllowed">true</item>
-// <item name="android:isLightTheme">true</item>
-// This attributes are necessary to make force dark auto mode works.
-
 /**
  * An {@link Activity} to exercise Force Dark functionality.
  * It shows WebViews side by side with different dark mode settings.
diff --git a/webkit/src/androidTest/java/androidx/webkit/WebViewClientCompatTest.java b/webkit/src/androidTest/java/androidx/webkit/WebViewClientCompatTest.java
index d48607b..b8288c0 100644
--- a/webkit/src/androidTest/java/androidx/webkit/WebViewClientCompatTest.java
+++ b/webkit/src/androidTest/java/androidx/webkit/WebViewClientCompatTest.java
@@ -18,7 +18,6 @@
 
 import android.graphics.Bitmap;
 import android.net.Uri;
-import android.webkit.ValueCallback;
 import android.webkit.WebResourceRequest;
 import android.webkit.WebResourceResponse;
 import android.webkit.WebView;
@@ -159,18 +158,9 @@
 
     private void clickOnLinkUsingJs(final String linkId, WebViewOnUiThread webViewOnUiThread)
             throws InterruptedException, ExecutionException, TimeoutException {
-        final ResolvableFuture<String> javascriptFuture = ResolvableFuture.create();
-        ValueCallback<String> callback = new ValueCallback<String>() {
-            @Override
-            public void onReceiveValue(String value) {
-                javascriptFuture.set(value);
-            }
-        };
-        webViewOnUiThread.evaluateJavascript(
+        webViewOnUiThread.evaluateJavascriptSync(
                 "document.getElementById('" + linkId + "').click();"
-                        + "console.log('element with id [" + linkId + "] clicked');", callback);
-        // TODO(ntfschr): consider asserting the value.
-        WebkitUtils.waitForFuture(javascriptFuture);
+                        + "console.log('element with id [" + linkId + "] clicked');");
     }
 
     /**
diff --git a/webkit/src/androidTest/java/androidx/webkit/WebViewOnUiThread.java b/webkit/src/androidTest/java/androidx/webkit/WebViewOnUiThread.java
index 37053db..8790899 100644
--- a/webkit/src/androidTest/java/androidx/webkit/WebViewOnUiThread.java
+++ b/webkit/src/androidTest/java/androidx/webkit/WebViewOnUiThread.java
@@ -287,8 +287,17 @@
         });
     }
 
-    void evaluateJavascript(final String script, final ValueCallback<String> result) {
-        WebkitUtils.onMainThreadSync(() -> mWebView.evaluateJavascript(script, result));
+    /**
+     * Execute javascript synchronously, returning the result.
+     */
+    public String evaluateJavascriptSync(final String script) {
+        final ResolvableFuture<String> future = ResolvableFuture.create();
+        evaluateJavascript(script, result -> future.set(result));
+        return WebkitUtils.waitForFuture(future);
+    }
+
+    public void evaluateJavascript(final String script, final ValueCallback<String> result) {
+        WebkitUtils.onMainThread(() -> mWebView.evaluateJavascript(script, result));
     }
 
     public WebViewClient getWebViewClient() {
diff --git a/webkit/src/main/java/androidx/webkit/ProxyConfig.java b/webkit/src/main/java/androidx/webkit/ProxyConfig.java
index 74adb9c..39c658f 100644
--- a/webkit/src/main/java/androidx/webkit/ProxyConfig.java
+++ b/webkit/src/main/java/androidx/webkit/ProxyConfig.java
@@ -19,11 +19,11 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.StringDef;
-import androidx.core.util.Pair;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.Executor;
 
@@ -66,22 +66,22 @@
     private static final String BYPASS_RULE_SIMPLE_NAMES = "<local>";
     private static final String BYPASS_RULE_REMOVE_IMPLICIT = "<-loopback>";
 
-    private List<Pair<String, String>> mProxyRules;
+    private List<ProxyRule> mProxyRules;
     private List<String> mBypassRules;
 
     /**
      * @hide Internal use only
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
-    public ProxyConfig(List<Pair<String, String>> proxyRules, List<String> bypassRules) {
+    public ProxyConfig(List<ProxyRule> proxyRules, List<String> bypassRules) {
         mProxyRules = proxyRules;
         mBypassRules = bypassRules;
     }
 
     /**
-     * Returns the current list of proxy rules. Each pair of (String, String) consists of the proxy
-     * URL and the URL schemes for which this proxy is used (one of {@code MATCH_HTTP},
-     * {@code MATCH_HTTPS}, {@code MATCH_ALL_SCHEMES}).
+     * Returns the current list of proxy rules. Each {@link ProxyRule} object
+     * holds the proxy URL and the URL schemes for which this proxy is used (one of
+     * {@code MATCH_HTTP}, {@code MATCH_HTTPS}, {@code MATCH_ALL_SCHEMES}).
      *
      * <p>To add new rules use {@link Builder#addProxyRule(String)} or
      * {@link Builder#addProxyRule(String, String)}.
@@ -89,8 +89,8 @@
      * @return List of proxy rules
      */
     @NonNull
-    public List<Pair<String, String>> getProxyRules() {
-        return mProxyRules;
+    public List<ProxyRule> getProxyRules() {
+        return Collections.unmodifiableList(mProxyRules);
     }
 
     /**
@@ -102,7 +102,52 @@
      */
     @NonNull
     public List<String> getBypassRules() {
-        return mBypassRules;
+        return Collections.unmodifiableList(mBypassRules);
+    }
+
+    /**
+     * Class that holds a scheme filter and a proxy URL.
+     */
+    public static final class ProxyRule {
+        private String mSchemeFilter;
+        private String mUrl;
+
+        /**
+         * @hide Internal use only
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        public ProxyRule(@NonNull String schemeFilter, @NonNull String url) {
+            mSchemeFilter = schemeFilter;
+            mUrl = url;
+        }
+
+        /**
+         * @hide Internal use only
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        public ProxyRule(@NonNull String url) {
+            this(ProxyConfig.MATCH_ALL_SCHEMES, url);
+        }
+
+        /**
+         * Returns the {@link String} that represents the scheme filter for this object.
+         *
+         * @return Scheme filter
+         */
+        @NonNull
+        public String getSchemeFilter() {
+            return mSchemeFilter;
+        }
+
+        /**
+         * Returns the {@link String} that represents the proxy URL for this object.
+         *
+         * @return Proxy URL
+         */
+        @NonNull
+        public String getUrl() {
+            return mUrl;
+        }
     }
 
     /**
@@ -115,7 +160,7 @@
      * connections to be made directly.
      */
     public static final class Builder {
-        private List<Pair<String, String>> mProxyRules;
+        private List<ProxyRule> mProxyRules;
         private List<String> mBypassRules;
 
         /**
@@ -175,7 +220,8 @@
          */
         @NonNull
         public Builder addProxyRule(@NonNull String proxyUrl) {
-            return addProxyRule(proxyUrl, MATCH_ALL_SCHEMES);
+            mProxyRules.add(new ProxyRule(proxyUrl));
+            return this;
         }
 
         /**
@@ -191,7 +237,7 @@
         @NonNull
         public Builder addProxyRule(@NonNull String proxyUrl,
                 @NonNull @ProxyScheme String schemeFilter) {
-            mProxyRules.add(new Pair<>(schemeFilter, proxyUrl));
+            mProxyRules.add(new ProxyRule(schemeFilter, proxyUrl));
             return this;
         }
 
@@ -220,7 +266,7 @@
          */
         @NonNull
         public Builder addDirect(@NonNull @ProxyScheme String schemeFilter) {
-            mProxyRules.add(new Pair<>(DIRECT, schemeFilter));
+            mProxyRules.add(new ProxyRule(schemeFilter, DIRECT));
             return this;
         }
 
@@ -271,7 +317,7 @@
         }
 
         @NonNull
-        private List<Pair<String, String>> proxyRules() {
+        private List<ProxyRule> proxyRules() {
             return mProxyRules;
         }
 
diff --git a/webkit/src/main/java/androidx/webkit/WebResourceRequestCompat.java b/webkit/src/main/java/androidx/webkit/WebResourceRequestCompat.java
index cb98b23..fc99bcb 100644
--- a/webkit/src/main/java/androidx/webkit/WebResourceRequestCompat.java
+++ b/webkit/src/main/java/androidx/webkit/WebResourceRequestCompat.java
@@ -25,8 +25,6 @@
 import androidx.webkit.internal.WebViewFeatureInternal;
 import androidx.webkit.internal.WebViewGlueCommunicator;
 
-// TODO(gsennton) add a test for this class
-
 /**
  * Compatibility version of {@link WebResourceRequest}.
  */
diff --git a/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java b/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java
index 62f2a98..c5d69d1 100644
--- a/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java
+++ b/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java
@@ -294,7 +294,7 @@
      * @hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    public static final int FORCE_DARK_OFF = 0;
+    public static final int FORCE_DARK_OFF = WebSettings.FORCE_DARK_OFF;
 
     /**
      * Enable force dark dependent on the state of the WebView parent view. If the WebView parent
@@ -308,7 +308,7 @@
      * @hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    public static final int FORCE_DARK_AUTO = 1;
+    public static final int FORCE_DARK_AUTO = WebSettings.FORCE_DARK_AUTO;
 
     /**
      * Used with {@link #setForceDark}
@@ -321,12 +321,11 @@
      * @hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    public static final int FORCE_DARK_ON = 2;
+    public static final int FORCE_DARK_ON = WebSettings.FORCE_DARK_ON;
 
     /**
      * @hide
      */
-    // TODO(amalova): redefine with framework constants when AndroidX compiles against Q
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
     @IntDef(value = {
             FORCE_DARK_OFF,
diff --git a/webkit/src/main/java/androidx/webkit/WebViewAssetLoader.java b/webkit/src/main/java/androidx/webkit/WebViewAssetLoader.java
index f782bcb..1625d57 100644
--- a/webkit/src/main/java/androidx/webkit/WebViewAssetLoader.java
+++ b/webkit/src/main/java/androidx/webkit/WebViewAssetLoader.java
@@ -23,8 +23,6 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RestrictTo;
-import androidx.annotation.RestrictTo.Scope;
 import androidx.annotation.VisibleForTesting;
 import androidx.annotation.WorkerThread;
 import androidx.webkit.internal.AssetHelper;
@@ -227,20 +225,29 @@
      * For more information about android storage please refer to
      * <a href="https://developer.android.com/guide/topics/data/data-storage">Android Developers
      * Docs: Data and file storage overview</a>.
-     * <p>
+     * <p class="note">
      * To avoid leaking user or app data to the web, make sure to choose {@code directory}
      * carefully, and assume any file under this directory could be accessed by any web page subject
      * to same-origin rules.
-     * @hide
+     * <p>
+     * A typical usage would be like:
+     * <pre class="prettyprint">
+     *     File publicDir = new File(context.getFilesDir(), "public");
+     *     // Host "files/public/" in app's data directory under:
+     *     // http://appassets.androidplatform.net/public/...
+     *     WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder()
+     *              .addPathHandler("/public/", new InternalStoragePathHandler(context, publicDir))
+     *              .build();
+     * </pre>
      */
-    // TODO(b/132880733) unhide the API when it's ready.
-    @RestrictTo(Scope.LIBRARY_GROUP)
     public static final class InternalStoragePathHandler implements PathHandler {
         /**
          * Forbidden subdirectories of {@link Context#getDataDir} that cannot be exposed by this
          * handler. They are forbidden as they often contain sensitive information.
+         * <p class="note">
+         * Note: Any future addition to this list will be considered breaking changes to the API.
          */
-        public static final String[] FORBIDDEN_DATA_DIRS =
+        private static final String[] FORBIDDEN_DATA_DIRS =
                 new String[] {"app_webview/", "databases/", "lib/", "shared_prefs/", "code_cache/"};
 
         @NonNull private final File mDirectory;
@@ -248,14 +255,16 @@
         /**
          * Creates PathHandler for app's internal storage.
          * The directory to be exposed must be inside either the application's internal data
-         * directory {@link context#getDataDir} or cache directory {@link context#getCacheDir}.
+         * directory {@link Context#getDataDir} or cache directory {@link Context#getCacheDir}.
          * External storage is not supported for security reasons, as other apps with
          * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} may be able to modify the
          * files.
          * <p>
          * Exposing the entire data or cache directory is not permitted, to avoid accidentally
-         * exposing sensitive application files to the web. Certain existing directories are also
-         * not permitted, such as {@link FORBIDDEN_DATA_DIRS}, as they are often sensitive.
+         * exposing sensitive application files to the web. Certain existing subdirectories of
+         * {@link Context#getDataDir} are also not permitted as they are often sensitive.
+         * These files are ({@code "app_webview/"}, {@code "databases/"}, {@code "lib/"},
+         * {@code "shared_prefs/"} and {@code "code_cache/"}).
          * <p>
          * The application should typically use a dedicated subdirectory for the files it intends to
          * expose and keep them separate from other files.
diff --git a/webkit/src/main/java/androidx/webkit/internal/ProxyControllerImpl.java b/webkit/src/main/java/androidx/webkit/internal/ProxyControllerImpl.java
index c2b4675..fe8dbc8 100644
--- a/webkit/src/main/java/androidx/webkit/internal/ProxyControllerImpl.java
+++ b/webkit/src/main/java/androidx/webkit/internal/ProxyControllerImpl.java
@@ -17,7 +17,6 @@
 package androidx.webkit.internal;
 
 import androidx.annotation.NonNull;
-import androidx.core.util.Pair;
 import androidx.webkit.ProxyConfig;
 import androidx.webkit.ProxyController;
 import androidx.webkit.WebViewFeature;
@@ -39,14 +38,15 @@
         WebViewFeatureInternal webViewFeature =
                 WebViewFeatureInternal.getFeature(WebViewFeature.PROXY_OVERRIDE);
         if (webViewFeature.isSupportedByWebView()) {
-            List<Pair<String, String>> proxyRulesList = proxyConfig.getProxyRules();
+            List<ProxyConfig.ProxyRule> proxyRulesList = proxyConfig.getProxyRules();
 
             // A 2D String array representation is required by reflection
             String[][] proxyRulesArray = new String[proxyRulesList.size()][2];
             for (int i = 0; i < proxyRulesList.size(); i++) {
-                proxyRulesArray[i][0] = proxyRulesList.get(0).first;
-                proxyRulesArray[i][1] = proxyRulesList.get(0).second;
+                proxyRulesArray[i][0] = proxyRulesList.get(0).getSchemeFilter();
+                proxyRulesArray[i][1] = proxyRulesList.get(0).getUrl();
             }
+
             getBoundaryInterface().setProxyOverride(proxyRulesArray,
                     proxyConfig.getBypassRules().toArray(new String[0]), listener, executor);
         } else {
diff --git a/work/workmanager-benchmark/build.gradle b/work/workmanager-benchmark/build.gradle
new file mode 100644
index 0000000..e64d2a7
--- /dev/null
+++ b/work/workmanager-benchmark/build.gradle
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 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.AndroidXExtension
+import androidx.build.LibraryGroups
+import androidx.build.LibraryVersions
+import androidx.build.Publish
+
+import static androidx.build.dependencies.DependenciesKt.*
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+    id("kotlin-android")
+    id("androidx.benchmark")
+}
+
+dependencies {
+    androidTestImplementation(project(':work:work-runtime-ktx'))
+    androidTestImplementation(project(":benchmark:benchmark-junit4"))
+    androidTestImplementation(WORK_ARCH_ROOM_RUNTIME)
+    androidTestImplementation(JUNIT)
+    androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
+    androidTestImplementation(ANDROIDX_TEST_CORE)
+    androidTestImplementation(ANDROIDX_TEST_RUNNER)
+    androidTestImplementation(ESPRESSO_CORE)
+    androidTestImplementation(KOTLIN_STDLIB)
+    androidTestImplementation(KOTLIN_COROUTINES)
+}
+
+androidx {
+    name = "Android WorkManager Benchmarks"
+     publish = Publish.NONE
+    mavenVersion = LibraryVersions.WORK
+    mavenGroup = LibraryGroups.WORK
+    inceptionYear = "2019"
+    description = "Android WorkManager Benchmark Library"
+    url = AndroidXExtension.ARCHITECTURE_URL
+}
diff --git a/work/workmanager-benchmark/src/androidTest/AndroidManifest.xml b/work/workmanager-benchmark/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..9ad6fef
--- /dev/null
+++ b/work/workmanager-benchmark/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 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"
+    xmlns:tools="http://schemas.android.com/tools"
+    package="androidx.work.benchmark.test">
+
+    <!-- Important: disable debuggable for accurate performance results -->
+    <application
+        android:debuggable="false"
+        tools:replace="android:debuggable">
+    </application>
+</manifest>
diff --git a/work/workmanager-benchmark/src/androidTest/java/androidx/work/benchmark/DispatchingExecutor.kt b/work/workmanager-benchmark/src/androidTest/java/androidx/work/benchmark/DispatchingExecutor.kt
new file mode 100644
index 0000000..84bf03b
--- /dev/null
+++ b/work/workmanager-benchmark/src/androidTest/java/androidx/work/benchmark/DispatchingExecutor.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019 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.work.benchmark
+
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import java.util.concurrent.Executor
+
+/**
+ * An [Executor] where we can await termination of all commands.
+ */
+class DispatchingExecutor : Executor {
+    private val job = CompletableDeferred<Unit>()
+    private val scope = CoroutineScope(Dispatchers.Default + job)
+    override fun execute(command: Runnable) {
+        scope.launch {
+            command.run()
+        }
+    }
+
+    fun runAllCommands() {
+        runBlocking {
+            job.complete(Unit)
+            job.join()
+        }
+    }
+}
diff --git a/work/workmanager-benchmark/src/androidTest/java/androidx/work/benchmark/InitializeBenchmark.kt b/work/workmanager-benchmark/src/androidTest/java/androidx/work/benchmark/InitializeBenchmark.kt
new file mode 100644
index 0000000..32858bf
--- /dev/null
+++ b/work/workmanager-benchmark/src/androidTest/java/androidx/work/benchmark/InitializeBenchmark.kt
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2019 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.work.benchmark
+
+import android.content.Context
+import android.util.Log
+import androidx.benchmark.junit4.BenchmarkRule
+import androidx.benchmark.junit4.measureRepeated
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.work.Configuration
+import androidx.work.OneTimeWorkRequestBuilder
+import androidx.work.WorkInfo
+import androidx.work.impl.WorkDatabase
+import androidx.work.impl.WorkManagerImpl
+import androidx.work.impl.utils.SerialExecutor
+import androidx.work.impl.utils.taskexecutor.TaskExecutor
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import java.util.concurrent.Executor
+
+@RunWith(AndroidJUnit4::class)
+@LargeTest
+class InitializeBenchmark {
+
+    @get:Rule
+    val benchmarkRule = BenchmarkRule()
+    private lateinit var context: Context
+    private lateinit var executor: DispatchingExecutor
+    private lateinit var taskExecutor: TaskExecutor
+    private lateinit var configuration: Configuration
+
+    @Before
+    fun setUp() {
+        context = ApplicationProvider.getApplicationContext()
+
+        // Use a DispatchingExecutor to avoid having to wait for all the tasks to be done
+        // in the actual benchmark.
+        executor = DispatchingExecutor()
+        val serialExecutor = SerialExecutor(executor)
+
+        taskExecutor = object : TaskExecutor {
+            override fun postToMainThread(runnable: Runnable) {
+                serialExecutor.execute(runnable)
+            }
+
+            override fun getMainThreadExecutor(): Executor {
+                return serialExecutor
+            }
+
+            override fun executeOnBackgroundThread(runnable: Runnable) {
+                serialExecutor.execute(runnable)
+            }
+
+            override fun getBackgroundExecutor(): SerialExecutor {
+                return serialExecutor
+            }
+        }
+
+        configuration = Configuration.Builder()
+            .setTaskExecutor(executor)
+            .setExecutor(executor)
+            .setMinimumLoggingLevel(Log.DEBUG)
+            .build()
+    }
+
+    @Test
+    fun initializeSimple() {
+        benchmarkRule.measureRepeated {
+            // Runs ForceStopRunnable
+            val database = WorkDatabase.create(context, configuration.taskExecutor, false)
+            WorkManagerImpl(context, configuration, taskExecutor, database)
+            runWithTimingDisabled {
+                executor.runAllCommands()
+                database.close()
+                context.deleteDatabase(WorkDatabase.DB_NAME)
+            }
+        }
+    }
+
+    @Test
+    fun initializeWithWorkLeft() {
+        val count = 20
+        benchmarkRule.measureRepeated {
+            val database = WorkDatabase.create(context, configuration.taskExecutor, false)
+            runWithTimingDisabled {
+                for (i in 0 until count) {
+                    val request = OneTimeWorkRequestBuilder<NoOpWorker>()
+                    val state =
+                        if (i <= count - 2) WorkInfo.State.SUCCEEDED else WorkInfo.State.RUNNING
+                    request.setInitialState(state)
+                    database.workSpecDao().insertWorkSpec(request.build().workSpec)
+                }
+            }
+            // Runs ForceStopRunnable
+            WorkManagerImpl(context, configuration, taskExecutor, database)
+            // Prune records for the next run.
+            runWithTimingDisabled {
+                executor.runAllCommands()
+                with(database) {
+                    workSpecDao().pruneFinishedWorkWithZeroDependentsIgnoringKeepForAtLeast()
+                    close()
+                }
+                context.deleteDatabase(WorkDatabase.DB_NAME)
+            }
+        }
+    }
+}
diff --git a/work/workmanager-benchmark/src/androidTest/java/androidx/work/benchmark/NoOpWorker.kt b/work/workmanager-benchmark/src/androidTest/java/androidx/work/benchmark/NoOpWorker.kt
new file mode 100644
index 0000000..760ffd9
--- /dev/null
+++ b/work/workmanager-benchmark/src/androidTest/java/androidx/work/benchmark/NoOpWorker.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2019 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.work.benchmark
+
+import android.content.Context
+import androidx.work.CoroutineWorker
+import androidx.work.WorkerParameters
+
+/**
+ * Does not do anything useful except returning a [androidx.work.ListenableWorker.Result.success].
+ */
+class NoOpWorker(context: Context, parameters: WorkerParameters) :
+    CoroutineWorker(context, parameters) {
+    override suspend fun doWork(): Result {
+        return Result.success()
+    }
+}
\ No newline at end of file
diff --git a/work/workmanager-benchmark/src/main/AndroidManifest.xml b/work/workmanager-benchmark/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..4eb2ff3
--- /dev/null
+++ b/work/workmanager-benchmark/src/main/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<!--
+  ~ Copyright (C) 2019 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 package="androidx.work.benchmark" />
diff --git a/work/workmanager-ktx/api/2.3.0-alpha01.txt b/work/workmanager-ktx/api/2.3.0-alpha01.txt
index ddfb009..32b05f64 100644
--- a/work/workmanager-ktx/api/2.3.0-alpha01.txt
+++ b/work/workmanager-ktx/api/2.3.0-alpha01.txt
@@ -13,6 +13,7 @@
 
   public final class DataKt {
     ctor public DataKt();
+    method public static inline <reified T> boolean containsKey(androidx.work.Data, String key);
     method public static inline androidx.work.Data workDataOf(kotlin.Pair<java.lang.String,?>... pairs);
   }
 
diff --git a/work/workmanager-ktx/api/api_lint.ignore b/work/workmanager-ktx/api/api_lint.ignore
new file mode 100644
index 0000000..89a6dae
--- /dev/null
+++ b/work/workmanager-ktx/api/api_lint.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+MissingNullability: androidx.work.CoroutineWorker#setProgress(androidx.work.Data, kotlin.coroutines.Continuation<? super kotlin.Unit>):
+    Missing nullability on method `setProgress` return
+MissingNullability: androidx.work.OperationKt#await(androidx.work.Operation, kotlin.coroutines.Continuation<? super androidx.work.Operation.State.SUCCESS>):
+    Missing nullability on method `await` return
diff --git a/work/workmanager-ktx/api/current.txt b/work/workmanager-ktx/api/current.txt
index ddfb009..32b05f64 100644
--- a/work/workmanager-ktx/api/current.txt
+++ b/work/workmanager-ktx/api/current.txt
@@ -13,6 +13,7 @@
 
   public final class DataKt {
     ctor public DataKt();
+    method public static inline <reified T> boolean containsKey(androidx.work.Data, String key);
     method public static inline androidx.work.Data workDataOf(kotlin.Pair<java.lang.String,?>... pairs);
   }
 
diff --git a/work/workmanager-ktx/api/restricted_2.3.0-alpha01.txt b/work/workmanager-ktx/api/restricted_2.3.0-alpha01.txt
index 5b6423e..303990d 100644
--- a/work/workmanager-ktx/api/restricted_2.3.0-alpha01.txt
+++ b/work/workmanager-ktx/api/restricted_2.3.0-alpha01.txt
@@ -13,6 +13,7 @@
 
   public final class DataKt {
     ctor public DataKt();
+    method public static inline <reified T> boolean containsKey(androidx.work.Data, String key);
     method public static inline androidx.work.Data workDataOf(kotlin.Pair<java.lang.String,?>... pairs);
   }
 
diff --git a/work/workmanager-ktx/api/restricted_current.txt b/work/workmanager-ktx/api/restricted_current.txt
index 5b6423e..303990d 100644
--- a/work/workmanager-ktx/api/restricted_current.txt
+++ b/work/workmanager-ktx/api/restricted_current.txt
@@ -13,6 +13,7 @@
 
   public final class DataKt {
     ctor public DataKt();
+    method public static inline <reified T> boolean containsKey(androidx.work.Data, String key);
     method public static inline androidx.work.Data workDataOf(kotlin.Pair<java.lang.String,?>... pairs);
   }
 
diff --git a/work/workmanager-ktx/src/androidTest/java/androidx/work/DataTest.kt b/work/workmanager-ktx/src/androidTest/java/androidx/work/DataTest.kt
index 2583ece..16f4b23 100644
--- a/work/workmanager-ktx/src/androidTest/java/androidx/work/DataTest.kt
+++ b/work/workmanager-ktx/src/androidTest/java/androidx/work/DataTest.kt
@@ -19,16 +19,17 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
 import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertTrue
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class DataTest {
-
     @Test
-    fun testToWorkDataOf() {
+    fun testDataExtensions() {
         val data = workDataOf("one" to 1,
                 "two" to 2L,
                 "three" to "Three",
@@ -41,5 +42,11 @@
         assertEquals(longArray!!.size, 2)
         assertEquals(longArray[0], 1L)
         assertEquals(longArray[1], 2L)
+        assertTrue(data.containsKey<Int>("one"))
+        assertTrue(data.containsKey<Long>("two"))
+        assertTrue(data.containsKey<String>("three"))
+        assertTrue(data.containsKey<Array<Long>>("four"))
+        assertFalse(data.containsKey<Any>("nothing"))
+        assertFalse(data.containsKey<Float>("two"))
     }
 }
diff --git a/work/workmanager-ktx/src/main/java/androidx/work/Data.kt b/work/workmanager-ktx/src/main/java/androidx/work/Data.kt
index 4e502df..8d97e75 100644
--- a/work/workmanager-ktx/src/main/java/androidx/work/Data.kt
+++ b/work/workmanager-ktx/src/main/java/androidx/work/Data.kt
@@ -34,3 +34,9 @@
     }
     return dataBuilder.build()
 }
+
+/**
+ * Returns true if the instance of [Data] has a value corresponding to the given [key] with an
+ * expected type [T].
+ */
+inline fun <reified T : Any> Data.containsKey(key: String) = containsKey(key, T::class.java)
diff --git a/work/workmanager-testing/src/androidTest/java/androidx/work/testing/TestSchedulerTest.java b/work/workmanager-testing/src/androidTest/java/androidx/work/testing/TestSchedulerTest.java
index 3bbb0bb..83f2d59 100644
--- a/work/workmanager-testing/src/androidTest/java/androidx/work/testing/TestSchedulerTest.java
+++ b/work/workmanager-testing/src/androidTest/java/androidx/work/testing/TestSchedulerTest.java
@@ -20,10 +20,15 @@
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
 
+import androidx.lifecycle.Observer;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
+import androidx.work.Configuration;
 import androidx.work.Constraints;
 import androidx.work.NetworkType;
 import androidx.work.OneTimeWorkRequest;
@@ -41,7 +46,11 @@
 import org.junit.runner.RunWith;
 
 import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 
 @RunWith(AndroidJUnit4.class)
@@ -50,11 +59,18 @@
 
     private Context mContext;
     private TestDriver mTestDriver;
+    private Handler mHandler;
 
     @Before
     public void setUp() {
         mContext = ApplicationProvider.getApplicationContext();
-        WorkManagerTestInitHelper.initializeTestWorkManager(mContext);
+        mHandler = new Handler(Looper.getMainLooper());
+        // Don't set the task executor
+        Configuration configuration = new Configuration.Builder()
+                .setExecutor(new SynchronousExecutor())
+                .setMinimumLoggingLevel(Log.DEBUG)
+                .build();
+        WorkManagerTestInitHelper.initializeTestWorkManager(mContext, configuration);
         mTestDriver = WorkManagerTestInitHelper.getTestDriver(mContext);
         CountingTestWorker.COUNT.set(0);
     }
@@ -161,6 +177,131 @@
         }
     }
 
+    @Test
+    public void testWorker_afterSuccessfulRun_postConditions()
+            throws InterruptedException, ExecutionException {
+
+        OneTimeWorkRequest request = createWorkRequest();
+        WorkManager workManager = WorkManager.getInstance(mContext);
+        workManager.enqueue(request).getResult().get();
+        WorkInfo status = workManager.getWorkInfoById(request.getId()).get();
+        assertThat(status.getState().isFinished(), is(true));
+        mTestDriver.setAllConstraintsMet(request.getId());
+        mTestDriver.setInitialDelayMet(request.getId());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testWorker_afterSuccessfulRun_throwsExceptionWhenSetPeriodDelayMet()
+            throws InterruptedException, ExecutionException {
+
+        OneTimeWorkRequest request = createWorkRequest();
+        WorkManager workManager = WorkManager.getInstance(mContext);
+        workManager.enqueue(request).getResult().get();
+        WorkInfo status = workManager.getWorkInfoById(request.getId()).get();
+        assertThat(status.getState().isFinished(), is(true));
+        mTestDriver.setPeriodDelayMet(request.getId());
+    }
+
+    @Test
+    @LargeTest
+    public void testWorker_multipleSetInitialDelayMet_noDeadLock()
+            throws InterruptedException, ExecutionException {
+
+        Configuration configuration = new Configuration.Builder()
+                .setMinimumLoggingLevel(Log.DEBUG)
+                .build();
+        WorkManagerTestInitHelper.initializeTestWorkManager(mContext, configuration);
+        mTestDriver = WorkManagerTestInitHelper.getTestDriver(mContext);
+
+        // This should not deadlock
+        final OneTimeWorkRequest request = createWorkRequest();
+        final WorkManager workManager = WorkManager.getInstance(mContext);
+        workManager.enqueue(request).getResult().get();
+        mTestDriver.setInitialDelayMet(request.getId());
+        mTestDriver.setInitialDelayMet(request.getId());
+
+        final CountDownLatch latch = new CountDownLatch(1);
+        // Use the main looper to observe LiveData because we are using a SerialExecutor which is
+        // wrapping a SynchronousExecutor.
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                workManager.getWorkInfoByIdLiveData(request.getId()).observeForever(
+                        new Observer<WorkInfo>() {
+                            @Override
+                            public void onChanged(WorkInfo workInfo) {
+                                if (workInfo != null && workInfo.getState().isFinished()) {
+                                    latch.countDown();
+                                }
+                            }
+                        });
+            }
+        });
+
+        latch.await(5, TimeUnit.SECONDS);
+        assertThat(latch.getCount(), is(0L));
+    }
+
+    @Test
+    @LargeTest
+    public void testWorker_multipleSetInitialDelayMetMultiThreaded_noDeadLock()
+            throws InterruptedException {
+
+        Configuration configuration = new Configuration.Builder()
+                .setMinimumLoggingLevel(Log.DEBUG)
+                .build();
+        WorkManagerTestInitHelper.initializeTestWorkManager(mContext, configuration);
+        mTestDriver = WorkManagerTestInitHelper.getTestDriver(mContext);
+
+        // This should not deadlock
+        final WorkManager workManager = WorkManager.getInstance(mContext);
+        int numberOfWorkers = 10;
+        final ExecutorService service = Executors.newFixedThreadPool(numberOfWorkers);
+        for (int i = 0; i < numberOfWorkers; i++) {
+            service.submit(new Runnable() {
+                @Override
+                public void run() {
+                    final OneTimeWorkRequest request = createWorkRequest();
+                    workManager.enqueue(request);
+                    mTestDriver.setInitialDelayMet(request.getId());
+                    mTestDriver.setInitialDelayMet(request.getId());
+                }
+            });
+        }
+
+        final CountDownLatch latch = new CountDownLatch(1);
+        // Use the main looper to observe LiveData because we are using a SerialExecutor which is
+        // wrapping a SynchronousExecutor.
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                // Using the implicit tag name.
+                workManager.getWorkInfosByTagLiveData(TestWorker.class.getName()).observeForever(
+                        new Observer<List<WorkInfo>>() {
+                            @Override
+                            public void onChanged(List<WorkInfo> workInfos) {
+                                boolean completed = true;
+                                if (workInfos != null && !workInfos.isEmpty()) {
+                                    for (WorkInfo workInfo : workInfos) {
+                                        if (!workInfo.getState().isFinished()) {
+                                            completed = false;
+                                            break;
+                                        }
+                                    }
+                                }
+                                if (completed) {
+                                    latch.countDown();
+                                }
+                            }
+                        });
+            }
+        });
+
+        latch.await(10, TimeUnit.SECONDS);
+        service.shutdownNow();
+        assertThat(latch.getCount(), is(0L));
+    }
+
     private static OneTimeWorkRequest createWorkRequest() {
         return new OneTimeWorkRequest.Builder(TestWorker.class).build();
     }
diff --git a/work/workmanager-testing/src/androidTest/java/androidx/work/testing/WorkManagerInitHelperTest.java b/work/workmanager-testing/src/androidTest/java/androidx/work/testing/WorkManagerInitHelperTest.java
index 32f1a86..93e5fcd 100644
--- a/work/workmanager-testing/src/androidTest/java/androidx/work/testing/WorkManagerInitHelperTest.java
+++ b/work/workmanager-testing/src/androidTest/java/androidx/work/testing/WorkManagerInitHelperTest.java
@@ -16,17 +16,21 @@
 
 package androidx.work.testing;
 
+import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.notNullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import android.content.Context;
+import android.util.Log;
 
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
 import androidx.work.Configuration;
+import androidx.work.InputMergerFactory;
 import androidx.work.WorkManager;
+import androidx.work.WorkerFactory;
 import androidx.work.impl.WorkManagerImpl;
 import androidx.work.impl.utils.SerialExecutor;
 
@@ -70,4 +74,43 @@
         SerialExecutor serialExecutor = workManager.getWorkTaskExecutor().getBackgroundExecutor();
         assertThat(serialExecutor.getDelegatedExecutor(), is(mExecutor));
     }
+
+    @Test
+    public void testWorkManagerInitialized_withSynchronousTaskExecutor() {
+        Configuration configuration = new Configuration.Builder()
+                .setExecutor(mExecutor)
+                .build();
+
+        WorkManagerTestInitHelper.initializeTestWorkManager(mContext, configuration);
+        WorkManagerImpl workManager = (WorkManagerImpl) WorkManager.getInstance(mContext);
+        assertThat(workManager, is(notNullValue()));
+        SerialExecutor serialExecutor = workManager.getWorkTaskExecutor().getBackgroundExecutor();
+        assertThat(serialExecutor.getDelegatedExecutor(), instanceOf(SynchronousExecutor.class));
+    }
+
+    @Test
+    public void testWorkManagerInitialized_withFullConfiguration() {
+        Configuration configuration = new Configuration.Builder()
+                .setExecutor(mExecutor)
+                .setInputMergerFactory(InputMergerFactory.getDefaultInputMergerFactory())
+                .setWorkerFactory(WorkerFactory.getDefaultWorkerFactory())
+                .setJobSchedulerJobIdRange(1000, 2000)
+                .setMaxSchedulerLimit(50)
+                .setMinimumLoggingLevel(Log.DEBUG)
+                .build();
+
+        WorkManagerTestInitHelper.initializeTestWorkManager(mContext, configuration);
+        WorkManagerImpl workManager = (WorkManagerImpl) WorkManager.getInstance(mContext);
+        assertThat(workManager, is(notNullValue()));
+        SerialExecutor serialExecutor = workManager.getWorkTaskExecutor().getBackgroundExecutor();
+        assertThat(serialExecutor.getDelegatedExecutor(), instanceOf(SynchronousExecutor.class));
+        Configuration used = workManager.getConfiguration();
+
+        assertThat(configuration.getInputMergerFactory(), is(used.getInputMergerFactory()));
+        assertThat(configuration.getWorkerFactory(), is(used.getWorkerFactory()));
+        assertThat(configuration.getMinJobSchedulerId(), is(used.getMinJobSchedulerId()));
+        assertThat(configuration.getMaxJobSchedulerId(), is(used.getMaxJobSchedulerId()));
+        assertThat(configuration.getMaxSchedulerLimit(), is(used.getMaxSchedulerLimit()));
+        assertThat(configuration.getMinimumLoggingLevel(), is(used.getMinimumLoggingLevel()));
+    }
 }
diff --git a/work/workmanager-testing/src/main/java/androidx/work/testing/TestScheduler.java b/work/workmanager-testing/src/main/java/androidx/work/testing/TestScheduler.java
index 4a526ce..1595350 100644
--- a/work/workmanager-testing/src/main/java/androidx/work/testing/TestScheduler.java
+++ b/work/workmanager-testing/src/main/java/androidx/work/testing/TestScheduler.java
@@ -47,13 +47,13 @@
 class TestScheduler implements Scheduler, ExecutionListener {
 
     private final Context mContext;
-    private final Map<String, InternalWorkState> mInternalWorkStates;
-
-    private static final Object sLock = new Object();
+    private final Map<String, InternalWorkState> mPendingWorkStates;
+    private final Map<String, InternalWorkState> mTerminatedWorkStates;
 
     TestScheduler(@NonNull Context context) {
         mContext = context;
-        mInternalWorkStates = new HashMap<>();
+        mPendingWorkStates = new HashMap<>();
+        mTerminatedWorkStates = new HashMap<>();
     }
 
     @Override
@@ -62,24 +62,24 @@
             return;
         }
 
-        synchronized (sLock) {
-            List<String> workSpecIdsToSchedule = new ArrayList<>(workSpecs.length);
-            for (WorkSpec workSpec : workSpecs) {
-                if (!mInternalWorkStates.containsKey(workSpec.id)) {
-                    mInternalWorkStates.put(workSpec.id, new InternalWorkState(mContext, workSpec));
-                }
-                workSpecIdsToSchedule.add(workSpec.id);
+        List<String> workSpecIdsToSchedule = new ArrayList<>(workSpecs.length);
+        for (WorkSpec workSpec : workSpecs) {
+            if (!mPendingWorkStates.containsKey(workSpec.id)) {
+                mPendingWorkStates.put(workSpec.id, new InternalWorkState(mContext, workSpec));
             }
-            scheduleInternal(workSpecIdsToSchedule);
+            workSpecIdsToSchedule.add(workSpec.id);
         }
+        scheduleInternal(workSpecIdsToSchedule);
     }
 
     @Override
     public void cancel(@NonNull String workSpecId) {
-        synchronized (sLock) {
-            WorkManagerImpl.getInstance(mContext).stopWork(workSpecId);
-            mInternalWorkStates.remove(workSpecId);
-        }
+        // We don't need to keep track of cancelled workSpecs. This is because subsequent calls
+        // to enqueue() will no-op because insertWorkSpec in WorkDatabase has a conflict
+        // policy of @Ignore. So TestScheduler will _never_ be asked to schedule those
+        // WorkSpecs.
+        WorkManagerImpl.getInstance(mContext).stopWork(workSpecId);
+        mPendingWorkStates.remove(workSpecId);
     }
 
     /**
@@ -90,8 +90,9 @@
      * @throws IllegalArgumentException if {@code workSpecId} is not enqueued
      */
     void setAllConstraintsMet(@NonNull UUID workSpecId) {
-        synchronized (sLock) {
-            InternalWorkState internalWorkState = mInternalWorkStates.get(workSpecId.toString());
+        String id = workSpecId.toString();
+        if (!mTerminatedWorkStates.containsKey(id)) {
+            InternalWorkState internalWorkState = mPendingWorkStates.get(id);
             if (internalWorkState == null) {
                 throw new IllegalArgumentException(
                         "Work with id " + workSpecId + " is not enqueued!");
@@ -109,8 +110,9 @@
      * @throws IllegalArgumentException if {@code workSpecId} is not enqueued
      */
     void setInitialDelayMet(@NonNull UUID workSpecId) {
-        synchronized (sLock) {
-            InternalWorkState internalWorkState = mInternalWorkStates.get(workSpecId.toString());
+        String id = workSpecId.toString();
+        if (!mTerminatedWorkStates.containsKey(id)) {
+            InternalWorkState internalWorkState = mPendingWorkStates.get(id);
             if (internalWorkState == null) {
                 throw new IllegalArgumentException(
                         "Work with id " + workSpecId + " is not enqueued!");
@@ -128,33 +130,32 @@
      * @throws IllegalArgumentException if {@code workSpecId} is not enqueued
      */
     void setPeriodDelayMet(@NonNull UUID workSpecId) {
-        synchronized (sLock) {
-            InternalWorkState internalWorkState = mInternalWorkStates.get(workSpecId.toString());
-            if (internalWorkState == null) {
-                throw new IllegalArgumentException(
-                        "Work with id " + workSpecId + " is not enqueued!");
-            }
-            internalWorkState.mPeriodDelayMet = true;
-            scheduleInternal(Collections.singletonList(workSpecId.toString()));
+        String id = workSpecId.toString();
+        InternalWorkState internalWorkState = mPendingWorkStates.get(id);
+        if (internalWorkState == null) {
+            throw new IllegalArgumentException(
+                    "Work with id " + workSpecId + " is not enqueued!");
         }
+        internalWorkState.mPeriodDelayMet = true;
+        scheduleInternal(Collections.singletonList(workSpecId.toString()));
     }
 
     @Override
     public void onExecuted(@NonNull String workSpecId, boolean needsReschedule) {
-
-        synchronized (sLock) {
-            InternalWorkState internalWorkState = mInternalWorkStates.get(workSpecId);
+        InternalWorkState internalWorkState = mPendingWorkStates.get(workSpecId);
+        if (internalWorkState != null) {
             if (internalWorkState.mWorkSpec.isPeriodic()) {
                 internalWorkState.reset();
             } else {
-                mInternalWorkStates.remove(workSpecId);
+                mTerminatedWorkStates.put(workSpecId, internalWorkState);
+                mPendingWorkStates.remove(workSpecId);
             }
         }
     }
 
     private void scheduleInternal(Collection<String> workSpecIds) {
         for (String workSpecId : workSpecIds) {
-            InternalWorkState internalWorkState = mInternalWorkStates.get(workSpecId);
+            InternalWorkState internalWorkState = mPendingWorkStates.get(workSpecId);
             if (internalWorkState.isRunnable()) {
                 WorkManagerImpl.getInstance(mContext).startWork(workSpecId);
             }
diff --git a/work/workmanager-testing/src/main/java/androidx/work/testing/TestWorkManagerImpl.java b/work/workmanager-testing/src/main/java/androidx/work/testing/TestWorkManagerImpl.java
index 4e7c916..bb84e45 100644
--- a/work/workmanager-testing/src/main/java/androidx/work/testing/TestWorkManagerImpl.java
+++ b/work/workmanager-testing/src/main/java/androidx/work/testing/TestWorkManagerImpl.java
@@ -49,6 +49,14 @@
 
         // Note: This implies that the call to ForceStopRunnable() actually does nothing.
         // This is okay when testing.
+
+        // IMPORTANT: Leave the main thread executor as a Direct executor. This is very important.
+        // Otherwise we subtly change the order of callbacks. onExecuted() will execute after
+        // a call to StopWorkRunnable(). StopWorkRunnable() removes the pending WorkSpec and
+        // therefore the call to onExecuted() does not add the workSpecId to the list of
+        // terminated WorkSpecs. This is because internalWorkState == null.
+        // Also for PeriodicWorkRequests, Schedulers.schedule() will run before the call to
+        // onExecuted() and therefore PeriodicWorkRequests will always run twice.
         super(
                 context,
                 configuration,
diff --git a/work/workmanager-testing/src/main/java/androidx/work/testing/WorkManagerTestInitHelper.java b/work/workmanager-testing/src/main/java/androidx/work/testing/WorkManagerTestInitHelper.java
index 1864168..c13b28c 100644
--- a/work/workmanager-testing/src/main/java/androidx/work/testing/WorkManagerTestInitHelper.java
+++ b/work/workmanager-testing/src/main/java/androidx/work/testing/WorkManagerTestInitHelper.java
@@ -52,6 +52,15 @@
     public static void initializeTestWorkManager(
             @NonNull Context context,
             @NonNull Configuration configuration) {
+
+        // Check if the configuration being used has overridden the task executor. If not,
+        // swap to SynchronousExecutor. This is to preserve existing behavior.
+        if (configuration.isUsingDefaultTaskExecutor()) {
+            Configuration.Builder builder = new Configuration.Builder(configuration)
+                    .setTaskExecutor(new SynchronousExecutor());
+            configuration = builder.build();
+        }
+
         WorkManagerImpl.setDelegate(new TestWorkManagerImpl(context, configuration));
     }
 
diff --git a/work/workmanager/api/2.3.0-alpha01.txt b/work/workmanager/api/2.3.0-alpha01.txt
index a6cb786..51cdfd0 100644
--- a/work/workmanager/api/2.3.0-alpha01.txt
+++ b/work/workmanager/api/2.3.0-alpha01.txt
@@ -64,6 +64,8 @@
 
   public final class Data {
     ctor public Data(androidx.work.Data);
+    method public <T> boolean containsKey(String, Class<T!>);
+    method public static androidx.work.Data fromByteArray(byte[]);
     method public boolean getBoolean(String, boolean);
     method public boolean[]? getBooleanArray(String);
     method public byte getByte(String, byte);
@@ -79,6 +81,7 @@
     method public long[]? getLongArray(String);
     method public String? getString(String);
     method public String![]? getStringArray(String);
+    method public byte[] toByteArray();
     field public static final androidx.work.Data! EMPTY;
     field public static final int MAX_DATA_BYTES = 10240; // 0x2800
   }
diff --git a/work/workmanager/api/api_lint.ignore b/work/workmanager/api/api_lint.ignore
index cc73c5c..8bca693 100644
--- a/work/workmanager/api/api_lint.ignore
+++ b/work/workmanager/api/api_lint.ignore
@@ -5,3 +5,21 @@
     Acronyms should not be capitalized in class names: was `IN_PROGRESS`, should this be `InProgress`?
 AcronymName: androidx.work.Operation.State.SUCCESS:
     Acronyms should not be capitalized in class names: was `SUCCESS`, should this be `Success`?
+
+
+MissingNullability: androidx.work.Constraints#NONE:
+    Missing nullability on field `NONE` in class `class androidx.work.Constraints`
+MissingNullability: androidx.work.Constraints#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.work.Constraints.Builder#setTriggerContentMaxDelay(java.time.Duration) parameter #0:
+    Missing nullability on parameter `duration` in method `setTriggerContentMaxDelay`
+MissingNullability: androidx.work.Constraints.Builder#setTriggerContentUpdateDelay(java.time.Duration) parameter #0:
+    Missing nullability on parameter `duration` in method `setTriggerContentUpdateDelay`
+MissingNullability: androidx.work.Data#EMPTY:
+    Missing nullability on field `EMPTY` in class `class androidx.work.Data`
+MissingNullability: androidx.work.Data#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.work.WorkInfo#equals(Object) parameter #0:
+    Missing nullability on parameter `o` in method `equals`
+MissingNullability: androidx.work.WorkInfo#toString():
+    Missing nullability on method `toString` return
diff --git a/work/workmanager/api/current.txt b/work/workmanager/api/current.txt
index a6cb786..51cdfd0 100644
--- a/work/workmanager/api/current.txt
+++ b/work/workmanager/api/current.txt
@@ -64,6 +64,8 @@
 
   public final class Data {
     ctor public Data(androidx.work.Data);
+    method public <T> boolean containsKey(String, Class<T!>);
+    method public static androidx.work.Data fromByteArray(byte[]);
     method public boolean getBoolean(String, boolean);
     method public boolean[]? getBooleanArray(String);
     method public byte getByte(String, byte);
@@ -79,6 +81,7 @@
     method public long[]? getLongArray(String);
     method public String? getString(String);
     method public String![]? getStringArray(String);
+    method public byte[] toByteArray();
     field public static final androidx.work.Data! EMPTY;
     field public static final int MAX_DATA_BYTES = 10240; // 0x2800
   }
diff --git a/work/workmanager/src/androidTest/java/androidx/work/WorkDatabaseMigrationTest.java b/work/workmanager/src/androidTest/java/androidx/work/WorkDatabaseMigrationTest.java
index d44bdf5..780ee56 100644
--- a/work/workmanager/src/androidTest/java/androidx/work/WorkDatabaseMigrationTest.java
+++ b/work/workmanager/src/androidTest/java/androidx/work/WorkDatabaseMigrationTest.java
@@ -307,8 +307,8 @@
         contentValues.put("state", WorkTypeConverters.StateIds.ENQUEUED);
         contentValues.put("worker_class_name", TestWorker.class.getName());
         contentValues.put("input_merger_class_name", OverwritingInputMerger.class.getName());
-        contentValues.put("input", Data.toByteArray(Data.EMPTY));
-        contentValues.put("output", Data.toByteArray(Data.EMPTY));
+        contentValues.put("input", Data.EMPTY.toByteArray());
+        contentValues.put("output", Data.EMPTY.toByteArray());
         contentValues.put("initial_delay", 0L);
         contentValues.put("interval_duration", 0L);
         contentValues.put("flex_duration", 0L);
diff --git a/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java b/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
index c142b99..726ce26 100644
--- a/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
+++ b/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
@@ -77,7 +77,6 @@
 import androidx.work.ContentUriTriggers;
 import androidx.work.Data;
 import androidx.work.ExistingPeriodicWorkPolicy;
-import androidx.work.Logger;
 import androidx.work.OneTimeWorkRequest;
 import androidx.work.PeriodicWorkRequest;
 import androidx.work.TestLifecycleOwner;
@@ -120,8 +119,6 @@
 @RunWith(AndroidJUnit4.class)
 public class WorkManagerImplTest {
 
-    private static final String TAG = Logger.tagWithPrefix("WorkManagerImplTest");
-
     private static final long SLEEP_DURATION_SMALL_MILLIS = 500L;
 
     private Context mContext;
@@ -935,10 +932,8 @@
         assertThat(workInfo, is(nullValue()));
     }
 
-    // Temporarily disabled due to b/121002352.
-    // bug b/121090948 filed to keep track.
-    // @Test
-    // @MediumTest
+    @Test
+    @MediumTest
     @SuppressWarnings("unchecked")
     public void testGetWorkInfoById() {
         OneTimeWorkRequest work0 = new OneTimeWorkRequest.Builder(TestWorker.class).build();
@@ -1400,8 +1395,7 @@
     @LargeTest
     @SuppressWarnings("unchecked")
     public void testCancelAllWork_updatesLastCancelAllTimeLiveData() throws InterruptedException {
-        Preferences preferences = new Preferences(
-                (Context) ApplicationProvider.getApplicationContext());
+        Preferences preferences = new Preferences(ApplicationProvider.getApplicationContext());
         preferences.setLastCancelAllTimeMillis(0L);
 
         TestLifecycleOwner testLifecycleOwner = new TestLifecycleOwner();
diff --git a/work/workmanager/src/androidTest/java/androidx/work/impl/background/greedy/GreedySchedulerTest.java b/work/workmanager/src/androidTest/java/androidx/work/impl/background/greedy/GreedySchedulerTest.java
index 99d2a83..d79fc01 100644
--- a/work/workmanager/src/androidTest/java/androidx/work/impl/background/greedy/GreedySchedulerTest.java
+++ b/work/workmanager/src/androidTest/java/androidx/work/impl/background/greedy/GreedySchedulerTest.java
@@ -23,6 +23,8 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.content.Context;
+
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
@@ -51,6 +53,7 @@
 
     private static final String TEST_ID = "test";
 
+    private Context mContext;
     private WorkManagerImpl mWorkManagerImpl;
     private Processor mMockProcessor;
     private WorkConstraintsTracker mMockWorkConstraintsTracker;
@@ -58,13 +61,17 @@
 
     @Before
     public void setUp() {
+        mContext = mock(Context.class);
         TaskExecutor taskExecutor = mock(TaskExecutor.class);
         mWorkManagerImpl = mock(WorkManagerImpl.class);
         mMockProcessor = mock(Processor.class);
         mMockWorkConstraintsTracker = mock(WorkConstraintsTracker.class);
         when(mWorkManagerImpl.getProcessor()).thenReturn(mMockProcessor);
         when(mWorkManagerImpl.getWorkTaskExecutor()).thenReturn(taskExecutor);
-        mGreedyScheduler = new GreedyScheduler(mWorkManagerImpl, mMockWorkConstraintsTracker);
+        mGreedyScheduler = new GreedyScheduler(
+                mContext,
+                mWorkManagerImpl,
+                mMockWorkConstraintsTracker);
     }
 
     @Test
@@ -168,4 +175,16 @@
         }
         verify(mMockProcessor, times(1)).addExecutionListener(mGreedyScheduler);
     }
+
+    @Test
+    @SmallTest
+    public void testGreedyScheduler_ignoresRequestsInADifferentProcess() {
+        // Context.getSystemService() returns null so no work should be executed.
+        when(mContext.getPackageName()).thenReturn("packageName");
+        OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(TestWorker.class).build();
+        WorkSpec workSpec = getWorkSpec(work);
+        mGreedyScheduler.schedule(workSpec);
+        verify(mMockProcessor, times(0)).addExecutionListener(mGreedyScheduler);
+        verify(mMockWorkConstraintsTracker, never()).replace(ArgumentMatchers.<WorkSpec>anyList());
+    }
 }
diff --git a/work/workmanager/src/androidTest/java/androidx/work/impl/background/systemjob/SystemJobInfoConverterTest.java b/work/workmanager/src/androidTest/java/androidx/work/impl/background/systemjob/SystemJobInfoConverterTest.java
index 037ec16..a36e628 100644
--- a/work/workmanager/src/androidTest/java/androidx/work/impl/background/systemjob/SystemJobInfoConverterTest.java
+++ b/work/workmanager/src/androidTest/java/androidx/work/impl/background/systemjob/SystemJobInfoConverterTest.java
@@ -218,6 +218,25 @@
         convertWithRequiredNetworkType(METERED, JobInfo.NETWORK_TYPE_METERED, 26);
     }
 
+    @Test
+    @SmallTest
+    @SdkSuppress(minSdkVersion = 29)
+    public void testConvert_setImportantWhileForeground() {
+        WorkSpec workSpec = getTestWorkSpecWithConstraints(new Constraints.Builder().build());
+        JobInfo jobInfo = mConverter.convert(workSpec, JOB_ID);
+        assertThat(jobInfo.isImportantWhileForeground(), is(true));
+    }
+
+    @Test
+    @SmallTest
+    @SdkSuppress(minSdkVersion = 29)
+    public void testConvert_setImportantWhileForeground_withTimingConstraints() {
+        WorkSpec workSpec = new WorkSpec("id", TestWorker.class.getName());
+        workSpec.setPeriodic(TEST_INTERVAL_DURATION, TEST_FLEX_DURATION);
+        JobInfo jobInfo = mConverter.convert(workSpec, JOB_ID);
+        assertThat(jobInfo.isImportantWhileForeground(), is(false));
+    }
+
     private void convertWithRequiredNetworkType(NetworkType networkType,
                                                 int jobInfoNetworkType,
                                                 int minSdkVersion) {
diff --git a/work/workmanager/src/main/java/androidx/work/Configuration.java b/work/workmanager/src/main/java/androidx/work/Configuration.java
index c24f643..4be8448 100644
--- a/work/workmanager/src/main/java/androidx/work/Configuration.java
+++ b/work/workmanager/src/main/java/androidx/work/Configuration.java
@@ -48,14 +48,24 @@
      */
     public static final int MIN_SCHEDULER_LIMIT = 20;
 
-    private final @NonNull Executor mExecutor;
-    private final @NonNull Executor mTaskExecutor;
-    private final @NonNull WorkerFactory mWorkerFactory;
-    private final @NonNull InputMergerFactory mInputMergerFactory;
-    private final int mLoggingLevel;
-    private final int mMinJobSchedulerId;
-    private final int mMaxJobSchedulerId;
-    private final int mMaxSchedulerLimit;
+    // Synthetic access
+    @SuppressWarnings("WeakerAccess")
+    final @NonNull Executor mExecutor;
+    @SuppressWarnings("WeakerAccess")
+    final @NonNull Executor mTaskExecutor;
+    @SuppressWarnings("WeakerAccess")
+    final @NonNull WorkerFactory mWorkerFactory;
+    @SuppressWarnings("WeakerAccess")
+    final @NonNull InputMergerFactory mInputMergerFactory;
+    @SuppressWarnings("WeakerAccess")
+    final int mLoggingLevel;
+    @SuppressWarnings("WeakerAccess")
+    final int mMinJobSchedulerId;
+    @SuppressWarnings("WeakerAccess")
+    final int mMaxJobSchedulerId;
+    @SuppressWarnings("WeakerAccess")
+    final int mMaxSchedulerLimit;
+    private final boolean mIsUsingDefaultTaskExecutor;
 
     Configuration(@NonNull Configuration.Builder builder) {
         if (builder.mExecutor == null) {
@@ -65,11 +75,13 @@
         }
 
         if (builder.mTaskExecutor == null) {
+            mIsUsingDefaultTaskExecutor = true;
             // This executor is used for *both* WorkManager's tasks and Room's query executor.
             // So this should not be a single threaded executor. Writes will still be serialized
             // as this will be wrapped with an SerialExecutor.
             mTaskExecutor = createDefaultExecutor();
         } else {
+            mIsUsingDefaultTaskExecutor = false;
             mTaskExecutor = builder.mTaskExecutor;
         }
 
@@ -136,7 +148,7 @@
      * {@link android.util.Log}
      * @hide
      */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     public int getMinimumLoggingLevel() {
         return mLoggingLevel;
     }
@@ -188,6 +200,15 @@
         }
     }
 
+    /**
+     * @return {@code true} If the default task {@link Executor} is being used
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public boolean isUsingDefaultTaskExecutor() {
+        return mIsUsingDefaultTaskExecutor;
+    }
+
     private @NonNull Executor createDefaultExecutor() {
         return Executors.newFixedThreadPool(
                 // This value is the same as the core pool size for AsyncTask#THREAD_POOL_EXECUTOR.
@@ -204,10 +225,41 @@
         InputMergerFactory mInputMergerFactory;
         Executor mTaskExecutor;
 
-        int mLoggingLevel = Log.INFO;
-        int mMinJobSchedulerId = IdGenerator.INITIAL_ID;
-        int mMaxJobSchedulerId = Integer.MAX_VALUE;
-        int mMaxSchedulerLimit = MIN_SCHEDULER_LIMIT;
+        int mLoggingLevel;
+        int mMinJobSchedulerId;
+        int mMaxJobSchedulerId;
+        int mMaxSchedulerLimit;
+
+        /**
+         * Creates a new {@link Configuration.Builder}.
+         */
+        public Builder() {
+            mLoggingLevel = Log.INFO;
+            mMinJobSchedulerId = IdGenerator.INITIAL_ID;
+            mMaxJobSchedulerId = Integer.MAX_VALUE;
+            mMaxSchedulerLimit = MIN_SCHEDULER_LIMIT;
+        }
+
+        /**
+         * Creates a new {@link Configuration.Builder} with an existing {@link Configuration} as its
+         * template.
+         *
+         * @param configuration An existing {@link Configuration} to use as a template
+         * @hide
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        public Builder(@NonNull Configuration configuration) {
+            // Note that these must be accessed through fields and not the getters, which can
+            // otherwise manipulate the returned value (see getMaxSchedulerLimit(), for example).
+            mExecutor = configuration.mExecutor;
+            mWorkerFactory = configuration.mWorkerFactory;
+            mInputMergerFactory = configuration.mInputMergerFactory;
+            mTaskExecutor = configuration.mTaskExecutor;
+            mLoggingLevel = configuration.mLoggingLevel;
+            mMinJobSchedulerId = configuration.mMinJobSchedulerId;
+            mMaxJobSchedulerId = configuration.mMaxJobSchedulerId;
+            mMaxSchedulerLimit = configuration.mMaxSchedulerLimit;
+        }
 
         /**
          * Specifies a custom {@link WorkerFactory} for WorkManager.
diff --git a/work/workmanager/src/main/java/androidx/work/Data.java b/work/workmanager/src/main/java/androidx/work/Data.java
index 6d0beba..8e5fbac 100644
--- a/work/workmanager/src/main/java/androidx/work/Data.java
+++ b/work/workmanager/src/main/java/androidx/work/Data.java
@@ -330,6 +330,35 @@
     }
 
     /**
+     * Converts this Data to a byte array suitable for sending to other processes in your
+     * application.  There are no versioning guarantees with this byte array, so you should not
+     * use this for IPCs between applications or persistence.
+     *
+     * @return The byte array representation of the input
+     * @throws IllegalStateException if the serialized payload is bigger than
+     *                               {@link #MAX_DATA_BYTES}
+     */
+    @NonNull
+    public byte[] toByteArray() {
+        return Data.toByteArray(this);
+    }
+
+     /**
+     * Returns {@code true} if the instance of {@link Data} has a non-null value corresponding to
+     * the given {@link String} key with the expected type of {@code T}.
+     *
+     * @param key   The {@link String} key
+     * @param klass The {@link Class} container for the expected type
+     * @param <T>   The expected type
+     * @return {@code true} If the instance of {@link Data} has a value for the given
+     * {@link String} key with the expected type.
+     */
+    public <T> boolean containsKey(@NonNull String key, @NonNull Class<T> klass) {
+        Object value = mValues.get(key);
+        return value != null && klass.isAssignableFrom(value.getClass());
+    }
+
+    /**
      * @return The number of elements in this Data object.
      * @hide
      */
@@ -345,12 +374,12 @@
      * @param data The {@link Data} object to convert
      * @return The byte array representation of the input
      * @throws IllegalStateException if the serialized payload is bigger than
-     *         {@link #MAX_DATA_BYTES}
+     *                               {@link #MAX_DATA_BYTES}
      * @hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @TypeConverter
-    public static @NonNull byte[] toByteArray(@NonNull Data data) throws IllegalStateException {
+    public static @NonNull byte[] toByteArray(@NonNull Data data) {
         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         ObjectOutputStream objectOutputStream = null;
         try {
@@ -394,11 +423,9 @@
      * @param bytes The byte array representation to convert
      * @return An {@link Data} object built from the input
      * @throws IllegalStateException if bytes is bigger than {@link #MAX_DATA_BYTES}
-     * @hide
      */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @TypeConverter
-    public static @NonNull Data fromByteArray(@NonNull byte[] bytes) throws IllegalStateException {
+    public static @NonNull Data fromByteArray(@NonNull byte[] bytes) {
         if (bytes.length > MAX_DATA_BYTES) {
             throw new IllegalStateException(
                     "Data cannot occupy more than " + MAX_DATA_BYTES + " bytes when serialized");
diff --git a/work/workmanager/src/main/java/androidx/work/impl/WorkDatabase.java b/work/workmanager/src/main/java/androidx/work/impl/WorkDatabase.java
index f0f35f8..f2e50eb 100644
--- a/work/workmanager/src/main/java/androidx/work/impl/WorkDatabase.java
+++ b/work/workmanager/src/main/java/androidx/work/impl/WorkDatabase.java
@@ -29,6 +29,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
+import androidx.annotation.VisibleForTesting;
 import androidx.room.Database;
 import androidx.room.Room;
 import androidx.room.RoomDatabase;
@@ -69,7 +70,8 @@
 @TypeConverters(value = {Data.class, WorkTypeConverters.class})
 public abstract class WorkDatabase extends RoomDatabase {
 
-    private static final String DB_NAME = "androidx.work.workdb";
+    @VisibleForTesting
+    public static final String DB_NAME = "androidx.work.workdb";
     // Delete rows in the workspec table that...
     private static final String PRUNE_SQL_FORMAT_PREFIX = "DELETE FROM workspec WHERE "
             // are completed...
@@ -104,11 +106,11 @@
             builder = Room.inMemoryDatabaseBuilder(context, WorkDatabase.class)
                     .allowMainThreadQueries();
         } else {
-            builder = Room.databaseBuilder(context, WorkDatabase.class, DB_NAME)
-                    .setQueryExecutor(queryExecutor);
+            builder = Room.databaseBuilder(context, WorkDatabase.class, DB_NAME);
         }
 
-        return builder.addCallback(generateCleanupCallback())
+        return builder.setQueryExecutor(queryExecutor)
+                .addCallback(generateCleanupCallback())
                 .addMigrations(WorkDatabaseMigrations.MIGRATION_1_2)
                 .addMigrations(
                         new WorkDatabaseMigrations.WorkMigration(context, VERSION_2, VERSION_3))
diff --git a/work/workmanager/src/main/java/androidx/work/impl/WorkManagerImpl.java b/work/workmanager/src/main/java/androidx/work/impl/WorkManagerImpl.java
index e5120d2..7d902bd 100644
--- a/work/workmanager/src/main/java/androidx/work/impl/WorkManagerImpl.java
+++ b/work/workmanager/src/main/java/androidx/work/impl/WorkManagerImpl.java
@@ -93,7 +93,7 @@
      * @hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    public static void setDelegate(WorkManagerImpl delegate) {
+    public static void setDelegate(@Nullable WorkManagerImpl delegate) {
         synchronized (sLock) {
             sDelegatedInstance = delegate;
         }
@@ -220,10 +220,33 @@
             @NonNull Configuration configuration,
             @NonNull TaskExecutor workTaskExecutor,
             boolean useTestDatabase) {
+        this(context,
+                configuration,
+                workTaskExecutor,
+                WorkDatabase.create(
+                        context.getApplicationContext(),
+                        workTaskExecutor.getBackgroundExecutor(),
+                        useTestDatabase)
+        );
+    }
 
+    /**
+     * Create an instance of {@link WorkManagerImpl}.
+     *
+     * @param context          The application {@link Context}
+     * @param configuration    The {@link Configuration} configuration
+     * @param workTaskExecutor The {@link TaskExecutor} for running "processing" jobs, such as
+     *                         enqueueing, scheduling, cancellation, etc.
+     * @param database         The {@link WorkDatabase}
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public WorkManagerImpl(
+            @NonNull Context context,
+            @NonNull Configuration configuration,
+            @NonNull TaskExecutor workTaskExecutor,
+            @NonNull WorkDatabase database) {
         Context applicationContext = context.getApplicationContext();
-        WorkDatabase database = WorkDatabase.create(
-                applicationContext, configuration.getTaskExecutor(), useTestDatabase);
         Logger.setLogger(new Logger.LogcatLogger(configuration.getMinimumLoggingLevel()));
         List<Scheduler> schedulers = createSchedulers(applicationContext, workTaskExecutor);
         Processor processor = new Processor(
diff --git a/work/workmanager/src/main/java/androidx/work/impl/background/greedy/GreedyScheduler.java b/work/workmanager/src/main/java/androidx/work/impl/background/greedy/GreedyScheduler.java
index c54c6f9..3d5aa01 100644
--- a/work/workmanager/src/main/java/androidx/work/impl/background/greedy/GreedyScheduler.java
+++ b/work/workmanager/src/main/java/androidx/work/impl/background/greedy/GreedyScheduler.java
@@ -16,12 +16,16 @@
 
 package androidx.work.impl.background.greedy;
 
+import static android.content.Context.ACTIVITY_SERVICE;
 import static android.os.Build.VERSION.SDK_INT;
 
+import android.app.ActivityManager;
 import android.content.Context;
+import android.os.Process;
 import android.text.TextUtils;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.VisibleForTesting;
 import androidx.work.Logger;
@@ -49,24 +53,32 @@
 
     private static final String TAG = Logger.tagWithPrefix("GreedyScheduler");
 
-    private WorkManagerImpl mWorkManagerImpl;
-    private WorkConstraintsTracker mWorkConstraintsTracker;
+    private final Context mContext;
+    private final WorkManagerImpl mWorkManagerImpl;
+    private final WorkConstraintsTracker mWorkConstraintsTracker;
     private List<WorkSpec> mConstrainedWorkSpecs = new ArrayList<>();
     private boolean mRegisteredExecutionListener;
     private final Object mLock;
 
-    public GreedyScheduler(Context context,
-            TaskExecutor taskExecutor,
-            WorkManagerImpl workManagerImpl) {
+    // Internal State
+    private Boolean mIsMainProcess;
 
+    public GreedyScheduler(
+            @NonNull Context context,
+            @NonNull TaskExecutor taskExecutor,
+            @NonNull WorkManagerImpl workManagerImpl) {
+        mContext = context;
         mWorkManagerImpl = workManagerImpl;
         mWorkConstraintsTracker = new WorkConstraintsTracker(context, taskExecutor, this);
         mLock = new Object();
     }
 
     @VisibleForTesting
-    public GreedyScheduler(WorkManagerImpl workManagerImpl,
-            WorkConstraintsTracker workConstraintsTracker) {
+    public GreedyScheduler(
+            @NonNull Context context,
+            @NonNull WorkManagerImpl workManagerImpl,
+            @NonNull WorkConstraintsTracker workConstraintsTracker) {
+        mContext = context;
         mWorkManagerImpl = workManagerImpl;
         mWorkConstraintsTracker = workConstraintsTracker;
         mLock = new Object();
@@ -74,6 +86,16 @@
 
     @Override
     public void schedule(@NonNull WorkSpec... workSpecs) {
+        if (mIsMainProcess == null) {
+            // The default process name is the package name.
+            mIsMainProcess = TextUtils.equals(mContext.getPackageName(), getProcessName());
+        }
+
+        if (!mIsMainProcess) {
+            Logger.get().info(TAG, "Ignoring schedule request in non-main process");
+            return;
+        }
+
         registerExecutionListenerIfNeeded();
 
         // Keep track of the list of new WorkSpecs whose constraints need to be tracked.
@@ -82,7 +104,7 @@
         // are updating mConstrainedWorkSpecs.
         List<WorkSpec> constrainedWorkSpecs = new ArrayList<>();
         List<String> constrainedWorkSpecIds = new ArrayList<>();
-        for (WorkSpec workSpec: workSpecs) {
+        for (WorkSpec workSpec : workSpecs) {
             if (workSpec.state == WorkInfo.State.ENQUEUED
                     && !workSpec.isPeriodic()
                     && workSpec.initialDelay == 0L
@@ -123,6 +145,16 @@
 
     @Override
     public void cancel(@NonNull String workSpecId) {
+        if (mIsMainProcess == null) {
+            // The default process name is the package name.
+            mIsMainProcess = TextUtils.equals(mContext.getPackageName(), getProcessName());
+        }
+
+        if (!mIsMainProcess) {
+            Logger.get().info(TAG, "Ignoring schedule request in non-main process");
+            return;
+        }
+
         registerExecutionListenerIfNeeded();
         Logger.get().debug(TAG, String.format("Cancelling work ID %s", workSpecId));
         // onExecutionCompleted does the cleanup.
@@ -177,4 +209,24 @@
             mRegisteredExecutionListener = true;
         }
     }
+
+    @Nullable
+    private String getProcessName() {
+        int pid = Process.myPid();
+        ActivityManager am =
+                (ActivityManager) mContext.getSystemService(ACTIVITY_SERVICE);
+
+        if (am != null) {
+            List<ActivityManager.RunningAppProcessInfo> processes = am.getRunningAppProcesses();
+            if (processes != null && !processes.isEmpty()) {
+                for (ActivityManager.RunningAppProcessInfo process : processes) {
+                    if (process.pid == pid) {
+                        return process.processName;
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
 }
diff --git a/work/workmanager/src/main/java/androidx/work/impl/background/systemjob/SystemJobInfoConverter.java b/work/workmanager/src/main/java/androidx/work/impl/background/systemjob/SystemJobInfoConverter.java
index d78a9d9..224d23c 100644
--- a/work/workmanager/src/main/java/androidx/work/impl/background/systemjob/SystemJobInfoConverter.java
+++ b/work/workmanager/src/main/java/androidx/work/impl/background/systemjob/SystemJobInfoConverter.java
@@ -89,10 +89,19 @@
         long now = System.currentTimeMillis();
         long offset = Math.max(nextRunTime - now, 0);
 
-        // Even if a WorkRequest has no constraints, setMinimumLatency(0) still needs to be
-        // called due to an issue in JobInfo.Builder#build and JobInfo with no constraints. See
-        // b/67716867.
-        builder.setMinimumLatency(offset);
+        if (Build.VERSION.SDK_INT <= 28) {
+            // Before API 29, Jobs needed at least one constraint. Therefore before API 29 we
+            // always setMinimumLatency to make sure we have at least one constraint.
+            // See aosp/5434530 & b/6771687
+            builder.setMinimumLatency(offset);
+        } else  {
+            if (offset > 0) {
+                // Only set a minimum latency when applicable.
+                builder.setMinimumLatency(offset);
+            } else {
+                builder.setImportantWhileForeground(true);
+            }
+        }
 
         if (Build.VERSION.SDK_INT >= 24 && constraints.hasContentUriTriggers()) {
             ContentUriTriggers contentUriTriggers = constraints.getContentUriTriggers();
diff --git a/work/workmanager/src/test/java/androidx/work/DataTest.java b/work/workmanager/src/test/java/androidx/work/DataTest.java
index 9bb2466..80740e8 100644
--- a/work/workmanager/src/test/java/androidx/work/DataTest.java
+++ b/work/workmanager/src/test/java/androidx/work/DataTest.java
@@ -47,7 +47,7 @@
     public void testSerializeEmpty() {
         Data data = Data.EMPTY;
 
-        byte[] byteArray = Data.toByteArray(data);
+        byte[] byteArray = data.toByteArray();
         Data restoredData = Data.fromByteArray(byteArray);
 
         assertThat(restoredData, is(data));
@@ -62,7 +62,7 @@
                 .putString(KEY2, expectedValue2)
                 .build();
 
-        byte[] byteArray = Data.toByteArray(data);
+        byte[] byteArray = data.toByteArray();
         Data restoredData = Data.fromByteArray(byteArray);
 
         assertThat(restoredData, is(data));